Implement call nn
This commit is contained in:
parent
7e558104de
commit
f6e68231fd
@ -77,12 +77,14 @@ module control (
|
|||||||
logic decoder_alu_op_valid;
|
logic decoder_alu_op_valid;
|
||||||
logic decoder_memory_we;
|
logic decoder_memory_we;
|
||||||
adr_src_t decoder_adr_src;
|
adr_src_t decoder_adr_src;
|
||||||
|
logic decoder_sp_we;
|
||||||
|
|
||||||
logic is_undef;
|
logic is_undef;
|
||||||
logic pc_incr;
|
logic pc_incr;
|
||||||
logic instr_valid;
|
logic instr_valid;
|
||||||
logic branch_taken;
|
logic branch_taken;
|
||||||
logic branch_cc_true;
|
logic branch_cc_true;
|
||||||
|
logic branch_always;
|
||||||
|
|
||||||
sp_src_t sp_src;
|
sp_src_t sp_src;
|
||||||
pc_src_t pc_src;
|
pc_src_t pc_src;
|
||||||
@ -109,9 +111,14 @@ module control (
|
|||||||
|
|
||||||
assign pc_we = (nreset_r & ~is_undef & ~halted_r) & (pc_incr | branch_taken);
|
assign pc_we = (nreset_r & ~is_undef & ~halted_r) & (pc_incr | branch_taken);
|
||||||
assign pc_next = (branch_taken & pc_src == PC_SRC_OPERAND8) ? (pc_r + {{8{operand0_r[7]}}, operand0_r}) :
|
assign pc_next = (branch_taken & pc_src == PC_SRC_OPERAND8) ? (pc_r + {{8{operand0_r[7]}}, operand0_r}) :
|
||||||
|
(branch_taken & pc_src == PC_SRC_OPERAND16) ? {operand1_r, operand0_r} :
|
||||||
(pc_r + 16'b1);
|
(pc_r + 16'b1);
|
||||||
|
|
||||||
assign sp_next = (sp_src == SP_SRC_OPERAND16) ? {operand1_r, operand0_r} : '0;
|
assign sp_we = instr_valid & decoder_sp_we;
|
||||||
|
assign sp_next = (sp_src == SP_SRC_OPERAND16) ? {operand1_r, operand0_r} :
|
||||||
|
(sp_src == SP_SRC_INC) ? (sp_r + 16'h01) :
|
||||||
|
(sp_src == SP_SRC_DEC) ? (sp_r + 16'hFFFF) :
|
||||||
|
'0;
|
||||||
|
|
||||||
assign instr_we = (state_r == ST1_DEC);
|
assign instr_we = (state_r == ST1_DEC);
|
||||||
assign instr_next = rdata_i;
|
assign instr_next = rdata_i;
|
||||||
@ -135,7 +142,8 @@ module control (
|
|||||||
ST2_DEC: state_next = decoder_need_instr2 ? ST3_DEC : ST3_EXEC;
|
ST2_DEC: state_next = decoder_need_instr2 ? ST3_DEC : ST3_EXEC;
|
||||||
ST3_DEC: state_next = ST4_EXEC;
|
ST3_DEC: state_next = ST4_EXEC;
|
||||||
ST3_EXEC: state_next = ST0_ADDR;
|
ST3_EXEC: state_next = ST0_ADDR;
|
||||||
ST4_EXEC: state_next = ST0_ADDR;
|
ST4_EXEC: state_next = decoder_is_multicycle ? ST5_EXEC : ST0_ADDR;
|
||||||
|
ST5_EXEC: state_next = ST0_ADDR;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -150,7 +158,7 @@ module control (
|
|||||||
.is_multicycle_o(decoder_is_multicycle),
|
.is_multicycle_o(decoder_is_multicycle),
|
||||||
.undef_o (decoder_is_undef),
|
.undef_o (decoder_is_undef),
|
||||||
|
|
||||||
.sp_we_o (sp_we),
|
.sp_we_o (decoder_sp_we),
|
||||||
.sp_src_o (sp_src),
|
.sp_src_o (sp_src),
|
||||||
|
|
||||||
.alu_op_valid_o(decoder_alu_op_valid),
|
.alu_op_valid_o(decoder_alu_op_valid),
|
||||||
@ -168,6 +176,7 @@ module control (
|
|||||||
|
|
||||||
.memory_we_o (decoder_memory_we),
|
.memory_we_o (decoder_memory_we),
|
||||||
.adr_src_o (decoder_adr_src),
|
.adr_src_o (decoder_adr_src),
|
||||||
|
.branch_always_o(branch_always),
|
||||||
.cc_o (cc),
|
.cc_o (cc),
|
||||||
.pc_src_o (pc_src)
|
.pc_src_o (pc_src)
|
||||||
);
|
);
|
||||||
@ -177,12 +186,12 @@ module control (
|
|||||||
assign decoder_instr2_selected = (state_r == ST3_DEC) ? rdata_i : operand1_r;
|
assign decoder_instr2_selected = (state_r == ST3_DEC) ? rdata_i : operand1_r;
|
||||||
|
|
||||||
assign is_undef = instr_valid & decoder_is_undef;
|
assign is_undef = instr_valid & decoder_is_undef;
|
||||||
assign instr_valid = (state_r == ST2_EXEC | state_r == ST3_EXEC | state_r == ST4_EXEC);
|
assign instr_valid = (state_r == ST2_EXEC | state_r == ST3_EXEC | state_r == ST4_EXEC | state_r == ST5_EXEC);
|
||||||
assign alu_op_valid_o = decoder_alu_op_valid & instr_valid;
|
assign alu_op_valid_o = decoder_alu_op_valid & instr_valid;
|
||||||
|
|
||||||
assign pc_incr = (state_r == ST0_ADDR) | (state_r == ST1_DEC & decoder_need_instr1) | (state_r == ST2_DEC & decoder_need_instr2);
|
assign pc_incr = (state_r == ST0_ADDR) | (state_r == ST1_DEC & decoder_need_instr1) | (state_r == ST2_DEC & decoder_need_instr2);
|
||||||
|
|
||||||
assign branch_taken = instr_valid & (pc_src != PC_SRC_SEQ) & branch_cc_true;
|
assign branch_taken = instr_valid & (pc_src != PC_SRC_SEQ) & (branch_cc_true | branch_always);
|
||||||
assign branch_cc_true = ((cc == CC_NZ) & ~f_i[7]) |
|
assign branch_cc_true = ((cc == CC_NZ) & ~f_i[7]) |
|
||||||
((cc == CC_Z) & f_i[7]) |
|
((cc == CC_Z) & f_i[7]) |
|
||||||
((cc == CC_NC) & ~f_i[4]) |
|
((cc == CC_NC) & ~f_i[4]) |
|
||||||
|
@ -117,6 +117,8 @@ module cpu (
|
|||||||
(op_src == OP_SRC_OPERAND8) ? operand8 :
|
(op_src == OP_SRC_OPERAND8) ? operand8 :
|
||||||
(op_src == OP_SRC_REG8) ? reg8_rdata :
|
(op_src == OP_SRC_REG8) ? reg8_rdata :
|
||||||
(op_src == OP_SRC_MEMORY) ? rdata_i :
|
(op_src == OP_SRC_MEMORY) ? rdata_i :
|
||||||
|
(op_src == OP_SRC_PC_L) ? pc[7:0] :
|
||||||
|
(op_src == OP_SRC_PC_H) ? pc[15:8] :
|
||||||
'X;
|
'X;
|
||||||
|
|
||||||
assign reg8_we = instr_valid & (op_dest == OP_DEST_REG8);
|
assign reg8_we = instr_valid & (op_dest == OP_DEST_REG8);
|
||||||
@ -126,6 +128,7 @@ module cpu (
|
|||||||
assign reg16_rselect2 = reg16_wselect;
|
assign reg16_rselect2 = reg16_wselect;
|
||||||
|
|
||||||
assign address_o = (adr_src == ADR_SRC_HL) ? hl :
|
assign address_o = (adr_src == ADR_SRC_HL) ? hl :
|
||||||
|
(adr_src == ADR_SRC_SP) ? sp :
|
||||||
(adr_src == ADR_SRC_REG8) ? {8'hFF, reg8_rdata} :
|
(adr_src == ADR_SRC_REG8) ? {8'hFF, reg8_rdata} :
|
||||||
(adr_src == ADR_SRC_REG16) ? reg16_rdata :
|
(adr_src == ADR_SRC_REG16) ? reg16_rdata :
|
||||||
(adr_src == ADR_SRC_OPERAND8) ? {8'hFF, operand8} :
|
(adr_src == ADR_SRC_OPERAND8) ? {8'hFF, operand8} :
|
||||||
|
@ -11,7 +11,8 @@ package cpu_pkg;
|
|||||||
ST2_DEC,
|
ST2_DEC,
|
||||||
ST3_DEC,
|
ST3_DEC,
|
||||||
ST3_EXEC,
|
ST3_EXEC,
|
||||||
ST4_EXEC
|
ST4_EXEC,
|
||||||
|
ST5_EXEC
|
||||||
} state_t;
|
} state_t;
|
||||||
|
|
||||||
typedef enum logic [2:0] {
|
typedef enum logic [2:0] {
|
||||||
@ -66,7 +67,9 @@ package cpu_pkg;
|
|||||||
OP_SRC_OPERAND8,
|
OP_SRC_OPERAND8,
|
||||||
OP_SRC_MEMORY,
|
OP_SRC_MEMORY,
|
||||||
OP_SRC_OPERAND16,
|
OP_SRC_OPERAND16,
|
||||||
OP_SRC_REG16
|
OP_SRC_REG16,
|
||||||
|
OP_SRC_PC_L,
|
||||||
|
OP_SRC_PC_H
|
||||||
} op_src_t;
|
} op_src_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -77,12 +80,15 @@ package cpu_pkg;
|
|||||||
} op_dest_t;
|
} op_dest_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SP_SRC_OPERAND16
|
SP_SRC_OPERAND16,
|
||||||
|
SP_SRC_INC,
|
||||||
|
SP_SRC_DEC
|
||||||
} sp_src_t;
|
} sp_src_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ADR_SRC_PC,
|
ADR_SRC_PC,
|
||||||
ADR_SRC_HL,
|
ADR_SRC_HL,
|
||||||
|
ADR_SRC_SP,
|
||||||
ADR_SRC_REG8, // extended with FF
|
ADR_SRC_REG8, // extended with FF
|
||||||
ADR_SRC_REG16,
|
ADR_SRC_REG16,
|
||||||
ADR_SRC_OPERAND8, // extended with FF
|
ADR_SRC_OPERAND8, // extended with FF
|
||||||
@ -91,7 +97,8 @@ package cpu_pkg;
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PC_SRC_SEQ,
|
PC_SRC_SEQ,
|
||||||
PC_SRC_OPERAND8
|
PC_SRC_OPERAND8,
|
||||||
|
PC_SRC_OPERAND16
|
||||||
} pc_src_t;
|
} pc_src_t;
|
||||||
|
|
||||||
endpackage
|
endpackage
|
||||||
|
@ -29,6 +29,7 @@ module decode (
|
|||||||
output reg16_t reg16_dest_o,
|
output reg16_t reg16_dest_o,
|
||||||
output reg16_t reg16_src_o,
|
output reg16_t reg16_src_o,
|
||||||
|
|
||||||
|
output logic branch_always_o,
|
||||||
output cc_t cc_o,
|
output cc_t cc_o,
|
||||||
|
|
||||||
output pc_src_t pc_src_o,
|
output pc_src_t pc_src_o,
|
||||||
@ -60,6 +61,7 @@ module decode (
|
|||||||
logic is_inc_a;
|
logic is_inc_a;
|
||||||
logic is_inc_r;
|
logic is_inc_r;
|
||||||
logic is_jr_cc_n;
|
logic is_jr_cc_n;
|
||||||
|
logic is_call_nn;
|
||||||
|
|
||||||
reg8_t reg8_dest;
|
reg8_t reg8_dest;
|
||||||
reg8_t reg8_src;
|
reg8_t reg8_src;
|
||||||
@ -92,6 +94,7 @@ module decode (
|
|||||||
assign is_inc_r = (dec_x == 2'h0) & (dec_z == 3'h4);
|
assign is_inc_r = (dec_x == 2'h0) & (dec_z == 3'h4);
|
||||||
|
|
||||||
assign is_jr_cc_n = (dec_x == 2'h0) & (dec_z == 2'h0) & dec_y[2];
|
assign is_jr_cc_n = (dec_x == 2'h0) & (dec_z == 2'h0) & dec_y[2];
|
||||||
|
assign is_call_nn = (instr0_i == 8'hCD);
|
||||||
|
|
||||||
assign reg8_src = is_cb ? reg8_t'(instr1_i[2:0]) :
|
assign reg8_src = is_cb ? reg8_t'(instr1_i[2:0]) :
|
||||||
is_ldh_c_a ? REG8_C :
|
is_ldh_c_a ? REG8_C :
|
||||||
@ -99,14 +102,17 @@ module decode (
|
|||||||
reg8_t'(dec_z);
|
reg8_t'(dec_z);
|
||||||
assign reg8_dest = reg8_t'(dec_y);
|
assign reg8_dest = reg8_t'(dec_y);
|
||||||
|
|
||||||
assign need_instr1_o = is_ld_sp_nn | is_ld_rr_nn | is_ld_a_nn | is_cb | is_jr_cc_n | is_ld_r_n | is_ldh_n_a;
|
assign need_instr1_o = is_ld_sp_nn | is_ld_rr_nn | is_ld_a_nn | is_call_nn | is_cb | is_jr_cc_n | is_ld_r_n | is_ldh_n_a;
|
||||||
assign need_instr2_o = is_ld_sp_nn | is_ld_rr_nn | is_ld_a_nn;
|
assign need_instr2_o = is_ld_sp_nn | is_ld_rr_nn | is_ld_a_nn | is_call_nn;
|
||||||
assign is_multicycle_o = is_ld_a_rr;
|
assign is_multicycle_o = is_ld_a_rr | is_call_nn;
|
||||||
|
|
||||||
assign undef_o = ~(is_ldh_n_a | is_ld_r_r | is_ld_sp_nn | is_ld_rr_nn | is_alu_a_r | is_ldd_hl_a | is_bit_n_r |
|
assign undef_o = ~(is_ldh_n_a | is_ld_r_r | is_ld_sp_nn | is_ld_rr_nn | is_alu_a_r | is_ldd_hl_a | is_bit_n_r |
|
||||||
is_jr_cc_n | is_ld_r_n | is_ldh_c_a | is_inc_r | is_ld_rr_a | is_ld_a_rr);
|
is_jr_cc_n | is_ld_r_n | is_ldh_c_a | is_inc_r | is_ld_rr_a | is_ld_a_rr | is_call_nn);
|
||||||
|
|
||||||
assign sp_we_o = is_ld_sp_nn & (state_i == ST4_EXEC);
|
assign sp_we_o = is_ld_sp_nn | is_call_nn;
|
||||||
|
assign sp_src_o = is_ld_sp_nn ? SP_SRC_OPERAND16 :
|
||||||
|
is_call_nn ? SP_SRC_DEC :
|
||||||
|
sp_src_t'('X);
|
||||||
|
|
||||||
assign alu_op_valid_o = is_alu_a_r | is_bit_n_r | is_ld_a_n | is_ld_a_rr | is_ld_a_nn | is_inc_r;
|
assign alu_op_valid_o = is_alu_a_r | is_bit_n_r | is_ld_a_n | is_ld_a_rr | is_ld_a_nn | is_inc_r;
|
||||||
assign alu_op_o = is_bit_n_r ? ALU_OP_BIT :
|
assign alu_op_o = is_bit_n_r ? ALU_OP_BIT :
|
||||||
@ -132,6 +138,7 @@ module decode (
|
|||||||
is_ldd_hl_a ? OP_DEST_REG16 :
|
is_ldd_hl_a ? OP_DEST_REG16 :
|
||||||
is_inc_a ? OP_DEST_A :
|
is_inc_a ? OP_DEST_A :
|
||||||
is_inc_r ? OP_DEST_REG8 :
|
is_inc_r ? OP_DEST_REG8 :
|
||||||
|
is_call_nn ? OP_DEST_MEMORY :
|
||||||
op_dest_t'('X);
|
op_dest_t'('X);
|
||||||
|
|
||||||
assign op_src_o = (is_ld_r_r & reg8_src == REG8_A) ? OP_SRC_A :
|
assign op_src_o = (is_ld_r_r & reg8_src == REG8_A) ? OP_SRC_A :
|
||||||
@ -147,6 +154,8 @@ module decode (
|
|||||||
is_ld_rr_nn ? OP_SRC_OPERAND16 :
|
is_ld_rr_nn ? OP_SRC_OPERAND16 :
|
||||||
is_ldd_hl_a ? OP_SRC_REG16 :
|
is_ldd_hl_a ? OP_SRC_REG16 :
|
||||||
is_bit_n_r ? OP_SRC_REG8 :
|
is_bit_n_r ? OP_SRC_REG8 :
|
||||||
|
is_call_nn & (state_i == ST4_EXEC) ? OP_SRC_PC_L :
|
||||||
|
is_call_nn & (state_i == ST5_EXEC) ? OP_SRC_PC_H :
|
||||||
op_src_t'('X);
|
op_src_t'('X);
|
||||||
|
|
||||||
assign reg8_dest_o = reg8_dest;
|
assign reg8_dest_o = reg8_dest;
|
||||||
@ -155,6 +164,7 @@ module decode (
|
|||||||
assign reg16_dest_o = is_ldd_hl_a ? REG16_HL : reg16_t'(dec_p);
|
assign reg16_dest_o = is_ldd_hl_a ? REG16_HL : reg16_t'(dec_p);
|
||||||
|
|
||||||
assign pc_src_o = is_jr_cc_n ? PC_SRC_OPERAND8 :
|
assign pc_src_o = is_jr_cc_n ? PC_SRC_OPERAND8 :
|
||||||
|
is_call_nn ? PC_SRC_OPERAND16 :
|
||||||
PC_SRC_SEQ;
|
PC_SRC_SEQ;
|
||||||
|
|
||||||
assign adr_src_o = (is_ld_r_r & reg8_dest == REG8_PHL) ? ADR_SRC_HL :
|
assign adr_src_o = (is_ld_r_r & reg8_dest == REG8_PHL) ? ADR_SRC_HL :
|
||||||
@ -167,10 +177,12 @@ module decode (
|
|||||||
is_ld_a_nn ? ADR_SRC_OPERAND16 :
|
is_ld_a_nn ? ADR_SRC_OPERAND16 :
|
||||||
is_ld_a_rr ? ADR_SRC_REG16 :
|
is_ld_a_rr ? ADR_SRC_REG16 :
|
||||||
is_ld_rr_a ? ADR_SRC_REG16 :
|
is_ld_rr_a ? ADR_SRC_REG16 :
|
||||||
|
is_call_nn ? ADR_SRC_SP :
|
||||||
ADR_SRC_PC;
|
ADR_SRC_PC;
|
||||||
|
|
||||||
|
assign branch_always_o = is_call_nn;
|
||||||
assign cc_o = cc_t'(dec_y[1:0]);
|
assign cc_o = cc_t'(dec_y[1:0]);
|
||||||
|
|
||||||
assign memory_we_o = is_ldd_hl_a | is_ldh_c_a | is_ldh_n_a | is_ld_rr_a | (is_ld_r_n & reg8_dest == REG8_PHL) | (is_ld_r_r & reg8_dest == REG8_PHL);
|
assign memory_we_o = is_ldd_hl_a | is_ldh_c_a | is_ldh_n_a | is_ld_rr_a | (is_ld_r_n & reg8_dest == REG8_PHL) | (is_ld_r_r & reg8_dest == REG8_PHL) | is_call_nn;
|
||||||
|
|
||||||
endmodule : decode
|
endmodule : decode
|
||||||
|
Loading…
Reference in New Issue
Block a user