From 7327ecffb9419860413b91aa8c18e011887f2104 Mon Sep 17 00:00:00 2001 From: Koray Yanik Date: Sat, 20 Feb 2021 15:00:01 +0000 Subject: [PATCH] Implement JR CC, $nn --- rtl/cpu/control.sv | 21 ++++++++++++++++++--- rtl/cpu/cpu.sv | 1 + rtl/cpu/cpu_pkg.svh | 12 ++++++++++++ rtl/cpu/decode.sv | 14 ++++++++++++-- 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/rtl/cpu/control.sv b/rtl/cpu/control.sv index 39e7abf..96671f8 100644 --- a/rtl/cpu/control.sv +++ b/rtl/cpu/control.sv @@ -8,6 +8,8 @@ module control ( input logic [ 7:0] rdata_i, + input logic [ 7:0] f_i, + output state_t state_o, output logic [15:0] pc_o, @@ -74,8 +76,12 @@ module control ( logic is_undef; logic pc_incr; logic instr_valid; + logic branch_taken; + logic branch_cc_true; sp_src_t sp_src; + pc_src_t pc_src; + cc_t cc; always_ff @(posedge clk_i) begin nreset_r <= nreset_i; @@ -89,8 +95,9 @@ module control ( `DEF_FF(operand0_r, operand0_next, operand0_we, '0); `DEF_FF(operand1_r, operand1_next, operand1_we, '0); - assign pc_we = nreset_r & pc_incr & ~is_undef; - assign pc_next = (pc_r + 16'b1); + assign pc_we = (nreset_r & pc_incr & ~is_undef) | branch_taken; + assign pc_next = (branch_taken & pc_src == PC_SRC_OPERAND8) ? (pc_r + {{8{operand0_r[7]}}, operand0_r}) : + (pc_r + 16'b1); assign sp_next = (sp_src == SP_SRC_OPERAND16) ? {operand1_r, operand0_r} : '0; @@ -145,7 +152,9 @@ module control ( .reg16_dest_o (reg16_dest_o), .memory_we_o (decoder_memory_we), - .adr_src_o (decoder_adr_src) + .adr_src_o (decoder_adr_src), + .cc_o (cc), + .pc_src_o (pc_src) ); assign decoder_instr0_selected = (state_r == ST1_DEC) ? rdata_i : instr_r; @@ -157,6 +166,12 @@ module control ( 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_cc_true = ((cc == CC_NZ) & ~f_i[7]) | + ((cc == CC_Z) & f_i[7]) | + ((cc == CC_NC) & ~f_i[4]) | + ((cc == CC_C) & f_i[4]); + assign state_o = state_r; assign pc_o = pc_r; assign sp_o = sp_r; diff --git a/rtl/cpu/cpu.sv b/rtl/cpu/cpu.sv index fe1475a..b6797f4 100644 --- a/rtl/cpu/cpu.sv +++ b/rtl/cpu/cpu.sv @@ -55,6 +55,7 @@ module cpu ( .nreset_i (nreset_i), .rdata_i (rdata_i), .state_o (state), + .f_i (regf), .pc_o (pc), .sp_o (sp), .alu_op_valid_o(alu_op_valid), diff --git a/rtl/cpu/cpu_pkg.svh b/rtl/cpu/cpu_pkg.svh index 1c69c23..667fae2 100644 --- a/rtl/cpu/cpu_pkg.svh +++ b/rtl/cpu/cpu_pkg.svh @@ -32,6 +32,13 @@ package cpu_pkg; REG16_SP_AF = 2'h03 } reg16_t; + typedef enum logic [1:0] { + CC_NZ = 2'h00, + CC_Z = 2'h01, + CC_NC = 2'h02, + CC_C = 2'h03 + } cc_t; + typedef enum logic [3:0] { ALU_OP_ADD = 4'h00, ALU_OP_ADC = 4'h01, @@ -72,6 +79,11 @@ package cpu_pkg; ADR_SRC_HL } adr_src_t; + typedef enum { + PC_SRC_SEQ, + PC_SRC_OPERAND8 + } pc_src_t; + endpackage `define DEF_FF(register, next, we, rst_value) \ diff --git a/rtl/cpu/decode.sv b/rtl/cpu/decode.sv index 6fb9b75..5c5c2bc 100644 --- a/rtl/cpu/decode.sv +++ b/rtl/cpu/decode.sv @@ -26,6 +26,9 @@ module decode ( output reg16_t reg16_dest_o, output reg16_t reg16_src_o, + output cc_t cc_o, + + output pc_src_t pc_src_o, output adr_src_t adr_src_o, output logic memory_we_o ); @@ -42,6 +45,7 @@ module decode ( logic is_ldd_hl_a; logic is_alu_a_r; logic is_bit_n_r; + logic is_jr_cc_n; reg8_t reg8_src; @@ -60,15 +64,16 @@ module decode ( assign is_alu_a_r = (dec_x == 3'h2); assign is_bit_n_r = (is_cb & instr1_i[7:6] == 2'h1); + assign is_jr_cc_n = (dec_x == 2'h0) & (dec_z == 2'h0) & dec_y[2]; assign reg8_src = is_cb ? reg8_t'(instr1_i[2:0]) : reg8_t'(dec_z); - assign need_instr1_o = is_ld_sp_nnnn | is_ld_rr_nnnn | is_cb; + assign need_instr1_o = is_ld_sp_nnnn | is_ld_rr_nnnn | is_cb | is_jr_cc_n; assign need_instr2_o = is_ld_sp_nnnn | is_ld_rr_nnnn; - assign undef_o = ~(is_ld_sp_nnnn | is_ld_rr_nnnn | is_alu_a_r | is_ldd_hl_a | is_bit_n_r); + assign undef_o = ~(is_ld_sp_nnnn | is_ld_rr_nnnn | is_alu_a_r | is_ldd_hl_a | is_bit_n_r | is_jr_cc_n); assign sp_we_o = is_ld_sp_nnnn & (state_i == ST4_EXEC); @@ -91,9 +96,14 @@ module decode ( assign reg16_src_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 : + PC_SRC_SEQ; + assign adr_src_o = is_ldd_hl_a ? ADR_SRC_HL : ADR_SRC_PC; + assign cc_o = cc_t'(dec_y[1:0]); + assign memory_we_o = is_ldd_hl_a; endmodule : decode