diff --git a/rtl/cpu/control.sv b/rtl/cpu/control.sv index e7ce783..b74bf09 100644 --- a/rtl/cpu/control.sv +++ b/rtl/cpu/control.sv @@ -72,6 +72,7 @@ module control ( logic [ 7:0] decoder_instr2_selected; logic decoder_need_instr1; logic decoder_need_instr2; + logic decoder_is_multicycle; logic decoder_is_undef; logic decoder_alu_op_valid; logic decoder_memory_we; @@ -128,8 +129,8 @@ module control ( always_comb begin case (state_r) ST0_ADDR: state_next = ST1_DEC; - ST1_DEC: state_next = decoder_need_instr1 ? ST2_DEC : ST2_EXEC; - ST2_EXEC: state_next = ST0_ADDR; + ST1_DEC: state_next = decoder_need_instr1 ? ST2_DEC : ST2_EXEC; + ST2_EXEC: state_next = decoder_is_multicycle ? ST3_EXEC : ST0_ADDR; ST2_DEC: state_next = decoder_need_instr2 ? ST3_DEC : ST3_EXEC; ST3_DEC: state_next = ST4_EXEC; @@ -144,9 +145,10 @@ module control ( .instr2_i (decoder_instr2_selected), .state_i (state_r), - .need_instr1_o(decoder_need_instr1), - .need_instr2_o(decoder_need_instr2), - .undef_o (decoder_is_undef), + .need_instr1_o (decoder_need_instr1), + .need_instr2_o (decoder_need_instr2), + .is_multicycle_o(decoder_is_multicycle), + .undef_o (decoder_is_undef), .sp_we_o (sp_we), .sp_src_o (sp_src), diff --git a/rtl/cpu/decode.sv b/rtl/cpu/decode.sv index 5d0f7ce..54f614a 100644 --- a/rtl/cpu/decode.sv +++ b/rtl/cpu/decode.sv @@ -11,6 +11,7 @@ module decode ( output logic need_instr1_o, output logic need_instr2_o, + output logic is_multicycle_o, output logic undef_o, output logic sp_we_o, @@ -49,6 +50,8 @@ module decode ( logic is_ldh_n_a; logic is_ld_rr_a; logic is_ld_nn_a; + logic is_ld_a_rr; + logic is_ld_a_nn; logic is_ld_rr_nn; logic is_ld_sp_nn; logic is_ldd_hl_a; @@ -77,6 +80,8 @@ module decode ( assign is_ldd_hl_a = (dec_x == 2'h0) & (dec_z == 3'h2) & ~dec_q & (dec_p == 2'h3); assign is_ld_rr_a = (dec_x == 2'h0) & (dec_z == 3'h2) & ~dec_q & (dec_p != 2'h3); assign is_ld_nn_a = (dec_x == 2'h0) & (dec_z == 3'h2) & ~dec_q & (dec_p == 2'h2); + assign is_ld_a_rr = (dec_x == 2'h0) & (dec_z == 3'h2) & dec_q & (dec_p != 2'h3); + assign is_ld_a_nn = (dec_x == 2'h0) & (dec_z == 3'h2) & dec_q & (dec_p == 2'h3); assign is_ldh_c_a = instr0_i == 8'hE2; assign is_ldh_n_a = instr0_i == 8'hE0; @@ -94,34 +99,40 @@ module decode ( reg8_t'(dec_z); assign reg8_dest = reg8_t'(dec_y); - assign need_instr1_o = is_ld_sp_nn | is_ld_rr_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; + 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_instr2_o = is_ld_sp_nn | is_ld_rr_nn | is_ld_a_nn; + assign is_multicycle_o = is_ld_a_rr; - 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); + 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); assign sp_we_o = is_ld_sp_nn & (state_i == ST4_EXEC); - assign alu_op_valid_o = is_alu_a_r | is_bit_n_r | is_ld_a_n | 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 : is_ld_a_n ? ALU_OP_NOP : + is_ld_a_nn ? ALU_OP_NOP : + is_ld_a_rr ? ALU_OP_NOP : is_inc_a ? ALU_OP_INC : is_inc_r ? ALU_OP_INCR : alu_op_t'({1'b0, dec_y}); assign reg_write_alu_o = is_inc_r; - assign op_dest_o = (is_ld_r_r & reg8_dest == REG8_PHL) ? OP_DEST_MEMORY : - (is_ld_r_n & reg8_dest == REG8_PHL) ? OP_DEST_MEMORY : - (is_ld_r_r & reg8_dest == REG8_A) ? OP_DEST_A : - is_ld_r_r ? OP_DEST_REG8 : - is_ld_a_n ? OP_DEST_A : - is_ld_r_n ? OP_DEST_REG8 : - is_ldh_c_a ? OP_DEST_MEMORY : - is_ldh_n_a ? OP_DEST_MEMORY : - is_ld_rr_nn ? OP_DEST_REG16 : - is_ldd_hl_a ? OP_DEST_REG16 : - is_inc_a ? OP_DEST_A : - is_inc_r ? OP_DEST_REG8 : - op_dest_t'('X); + assign op_dest_o = (is_ld_r_r & reg8_dest == REG8_PHL) ? OP_DEST_MEMORY : + (is_ld_r_n & reg8_dest == REG8_PHL) ? OP_DEST_MEMORY : + (is_ld_r_r & reg8_dest == REG8_A) ? OP_DEST_A : + is_ld_r_r ? OP_DEST_REG8 : + is_ld_a_n ? OP_DEST_A : + is_ld_a_rr ? OP_DEST_A : + is_ld_a_nn ? OP_DEST_A : + is_ld_r_n ? OP_DEST_REG8 : + is_ldh_c_a ? OP_DEST_MEMORY : + is_ldh_n_a ? OP_DEST_MEMORY : + is_ld_rr_nn ? OP_DEST_REG16 : + is_ldd_hl_a ? OP_DEST_REG16 : + is_inc_a ? OP_DEST_A : + is_inc_r ? OP_DEST_REG8 : + op_dest_t'('X); assign op_src_o = (is_ld_r_r & reg8_src == REG8_A) ? OP_SRC_A : (is_alu_a_r & reg8_src == REG8_A) ? OP_SRC_A : @@ -131,6 +142,8 @@ module decode ( is_ld_r_n ? OP_SRC_OPERAND8 : is_ldh_c_a ? OP_SRC_A : is_ldh_n_a ? OP_SRC_A : + is_ld_a_rr ? OP_SRC_MEMORY : + is_ld_a_nn ? OP_SRC_MEMORY : is_ld_rr_nn ? OP_SRC_OPERAND16 : is_ldd_hl_a ? OP_SRC_REG16 : is_bit_n_r ? OP_SRC_REG8 : @@ -144,14 +157,16 @@ module decode ( assign pc_src_o = is_jr_cc_n ? PC_SRC_OPERAND8 : PC_SRC_SEQ; - assign adr_src_o = (is_ld_r_r & reg8_dest == REG8_PHL) ? ADR_SRC_HL : - (is_ld_r_r & reg8_src == REG8_PHL) ? ADR_SRC_HL : - is_ldd_hl_a ? ADR_SRC_HL : - (is_ld_r_n & reg8_dest == REG8_PHL) ? ADR_SRC_HL : - is_ldh_c_a ? ADR_SRC_REG8 : + assign adr_src_o = (is_ld_r_r & reg8_dest == REG8_PHL) ? ADR_SRC_HL : + (is_ld_r_r & reg8_src == REG8_PHL) ? ADR_SRC_HL : + is_ldd_hl_a ? ADR_SRC_HL : + (is_ld_r_n & reg8_dest == REG8_PHL) ? ADR_SRC_HL : + is_ldh_c_a ? ADR_SRC_REG8 : is_ldh_n_a ? ADR_SRC_OPERAND8 : is_ld_nn_a ? ADR_SRC_OPERAND16 : - is_ld_rr_a ? ADR_SRC_REG16: + is_ld_a_nn ? ADR_SRC_OPERAND16 : + is_ld_a_rr ? ADR_SRC_REG16 : + is_ld_rr_a ? ADR_SRC_REG16 : ADR_SRC_PC; assign cc_o = cc_t'(dec_y[1:0]);