From ded64a89543318afd93abc25f804bc4c220313ee Mon Sep 17 00:00:00 2001 From: Koray Yanik Date: Sat, 20 Feb 2021 22:57:15 +0000 Subject: [PATCH] Implement inc r --- rtl/cpu/alu.sv | 26 +++++++++++++++++++++----- rtl/cpu/control.sv | 2 ++ rtl/cpu/cpu.sv | 6 +++++- rtl/cpu/cpu_pkg.svh | 24 +++++++++++++----------- rtl/cpu/decode.sv | 21 +++++++++++++++++---- 5 files changed, 58 insertions(+), 21 deletions(-) diff --git a/rtl/cpu/alu.sv b/rtl/cpu/alu.sv index 5582a2f..d2604a3 100644 --- a/rtl/cpu/alu.sv +++ b/rtl/cpu/alu.sv @@ -18,6 +18,7 @@ module alu ( output logic [ 7:0] a_o, output logic [ 7:0] f_o, + output logic [ 7:0] out8_o, // Only used for inc/dec reg8 output logic [15:0] out16_o ); @@ -29,14 +30,18 @@ module alu ( logic [ 7:0] f_r; logic [ 7:0] f_next; + logic [ 7:0] a_inc; + logic [ 7:0] f_inc; + logic [ 7:0] a_xor; logic [ 7:0] f_xor; logic [ 7:0] a_bit; // Never written, only to test logic [ 7:0] f_bit; - logic [16:0] out16_add; - logic [ 7:0] f16_add; + logic [ 7:0] f_incr; + logic [ 7:0] out8_inc; + logic [15:0] out16_inc; logic [15:0] out16_dec; @@ -46,24 +51,35 @@ module alu ( assign a_we = alu_op_valid_i; assign a_next = (alu_op_i == ALU_OP_XOR) ? a_xor : (alu_op_i == ALU_OP_NOP) ? operand_i : + (alu_op_i == ALU_OP_INC) ? a_inc : a_r; assign f_we = alu_op_valid_i; - assign f_next = (alu_op_i == ALU_OP_XOR) ? f_xor : - (alu_op_i == ALU_OP_BIT) ? f_bit : - f_r; + assign f_next = (alu_op_i == ALU_OP_XOR) ? f_xor : + (alu_op_i == ALU_OP_BIT) ? f_bit : + (alu_op_i == ALU_OP_INC) ? f_inc : + (alu_op_i == ALU_OP_INCR) ? f_incr : + f_r; assign a_xor = (a_r ^ operand_i); assign f_xor = {~(|a_xor), 3'b0, f_r[3:0]}; + assign a_inc = (a_r + 8'h01); + assign f_inc = {~(|a_inc), 1'b0, a_inc[4], f_r[3:0]}; + assign a_bit = (operand_i - {4'b0, inx8_i}); assign f_bit = {~(|a_bit), 2'b10, f_r[4:0]}; + assign f_incr = {~(|out8_inc), 1'b0, out8_inc[4], f_r[3:0]}; + + assign out8_inc = (operand_i + 8'h01); + assign out16_dec = (inx16_i - 16'h01); assign a_o = a_r; assign f_o = f_r; + assign out8_o = out8_inc; assign out16_o = out16_dec; endmodule : alu \ No newline at end of file diff --git a/rtl/cpu/control.sv b/rtl/cpu/control.sv index 3215ea7..e7ce783 100644 --- a/rtl/cpu/control.sv +++ b/rtl/cpu/control.sv @@ -22,6 +22,7 @@ module control ( output logic alu_op_valid_o, output alu_op_t alu_op_o, + output logic reg_write_alu_o, output op_src_t op_src_o, output op_dest_t op_dest_o, output reg8_t reg8_dest_o, @@ -152,6 +153,7 @@ module control ( .alu_op_valid_o(decoder_alu_op_valid), .alu_op_o (alu_op_o), + .reg_write_alu_o(reg_write_alu_o), .op_src_o (op_src_o), .op_dest_o (op_dest_o), diff --git a/rtl/cpu/cpu.sv b/rtl/cpu/cpu.sv index c5c905a..2ecfd02 100644 --- a/rtl/cpu/cpu.sv +++ b/rtl/cpu/cpu.sv @@ -19,6 +19,7 @@ module cpu ( op_src_t op_src; op_dest_t op_dest; adr_src_t adr_src; + logic reg_write_alu; logic [ 7:0] alu_operand; @@ -48,6 +49,7 @@ module cpu ( logic [15:0] reg16_rdata; logic [15:0] reg16_rdata2; alu16_op_t alu16_op; + logic [ 7:0] alu_out8; logic [15:0] alu_out16; control control_inst ( @@ -60,6 +62,7 @@ module cpu ( .sp_o (sp), .alu_op_valid_o(alu_op_valid), .alu_op_o (alu_op), + .reg_write_alu_o(reg_write_alu), .op_src_o (op_src), .op_dest_o (op_dest), .instr_valid_o (instr_valid), @@ -87,6 +90,7 @@ module cpu ( .alu16_op_i (alu16_op), .inx16_i (reg16_rdata2), .iny16_i (reg16_rdata), + .out8_o (alu_out8), .out16_o (alu_out16) ); @@ -115,7 +119,7 @@ module cpu ( 'X; assign reg8_we = instr_valid & (op_dest == OP_DEST_REG8); - assign reg8_wdata = alu_operand; + assign reg8_wdata = reg_write_alu ? alu_out8 : alu_operand; assign reg16_we = instr_valid & (op_dest == OP_DEST_REG16); assign reg16_wdata = (op_src == OP_SRC_OPERAND16) ? operand16 : alu_out16; assign reg16_rselect2 = reg16_wselect; diff --git a/rtl/cpu/cpu_pkg.svh b/rtl/cpu/cpu_pkg.svh index 3c18257..43ea5d2 100644 --- a/rtl/cpu/cpu_pkg.svh +++ b/rtl/cpu/cpu_pkg.svh @@ -39,17 +39,19 @@ package cpu_pkg; CC_C = 2'h03 } cc_t; - typedef enum logic [3:0] { - ALU_OP_ADD = 4'h00, - ALU_OP_ADC = 4'h01, - ALU_OP_SUB = 4'h02, - ALU_OP_SBC = 4'h03, - ALU_OP_AND = 4'h04, - ALU_OP_XOR = 4'h05, - ALU_OP_OR = 4'h06, - ALU_OP_CP = 4'h07, - ALU_OP_BIT = 4'h08, - ALU_OP_NOP = 4'h09 + typedef enum logic [4:0] { + ALU_OP_ADD = 5'h00, + ALU_OP_ADC = 5'h01, + ALU_OP_SUB = 5'h02, + ALU_OP_SBC = 5'h03, + ALU_OP_AND = 5'h04, + ALU_OP_XOR = 5'h05, + ALU_OP_OR = 5'h06, + ALU_OP_CP = 5'h07, + ALU_OP_BIT = 5'h08, + ALU_OP_NOP = 5'h09, + ALU_OP_INC = 5'h10, + ALU_OP_INCR = 5'h11 // Increment register instead of a } alu_op_t; typedef enum logic [1:0] { diff --git a/rtl/cpu/decode.sv b/rtl/cpu/decode.sv index 8563de0..88ff0b1 100644 --- a/rtl/cpu/decode.sv +++ b/rtl/cpu/decode.sv @@ -18,6 +18,7 @@ module decode ( output logic alu_op_valid_o, output alu_op_t alu_op_o, + output logic reg_write_alu_o, output op_src_t op_src_o, output op_dest_t op_dest_o, @@ -49,6 +50,8 @@ module decode ( logic is_ldd_hl_a; logic is_alu_a_r; logic is_bit_n_r; + logic is_inc_a; + logic is_inc_r; logic is_jr_cc_n; reg8_t reg8_dest; @@ -72,24 +75,31 @@ 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_inc_a = is_inc_r & (reg8_dest == REG8_A); + 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 reg8_src = is_cb ? reg8_t'(instr1_i[2:0]) : is_ldh_c_a ? REG8_C : + is_inc_r ? reg8_t'(dec_y) : reg8_t'(dec_z); assign reg8_dest = reg8_t'(dec_y); assign need_instr1_o = is_ld_sp_nnnn | is_ld_rr_nnnn | is_cb | is_jr_cc_n | is_ld_r_nn; 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 | is_jr_cc_n | is_ld_r_nn | is_ldh_c_a); + 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 | is_ld_r_nn | is_ldh_c_a | is_inc_r); assign sp_we_o = is_ld_sp_nnnn & (state_i == ST4_EXEC); - assign alu_op_valid_o = is_alu_a_r | is_bit_n_r | is_ld_a_nn; - assign alu_op_o = is_bit_n_r ? ALU_OP_BIT : - is_ld_a_nn ? ALU_OP_NOP : + assign alu_op_valid_o = is_alu_a_r | is_bit_n_r | is_ld_a_nn | is_inc_r; + assign alu_op_o = is_bit_n_r ? ALU_OP_BIT : + is_ld_a_nn ? 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_nn & reg8_dest == REG8_PHL) ? OP_DEST_MEMORY : is_ld_a_nn ? OP_DEST_A : @@ -97,10 +107,13 @@ module decode ( is_ldh_c_a ? OP_DEST_MEMORY : is_ld_rr_nnnn ? 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_alu_a_r & reg8_src == REG8_A) ? OP_SRC_A : (is_alu_a_r & reg8_src != REG8_A) ? OP_SRC_REG8 : + is_inc_r ? OP_SRC_REG8 : is_ld_r_nn ? OP_SRC_OPERAND8 : is_ldh_c_a ? OP_SRC_A : is_ld_rr_nnnn ? OP_SRC_OPERAND16 :