From 67361093ecbca3311188bbd9b2e169acce3912b7 Mon Sep 17 00:00:00 2001 From: Koray Yanik Date: Sat, 20 Feb 2021 15:56:22 +0000 Subject: [PATCH] Implement LD r, $nn --- rtl/cpu/alu.sv | 3 ++- rtl/cpu/control.sv | 6 +++++- rtl/cpu/cpu.sv | 11 ++++++----- rtl/cpu/cpu_pkg.svh | 7 +++++-- rtl/cpu/decode.sv | 33 +++++++++++++++++++++++---------- 5 files changed, 41 insertions(+), 19 deletions(-) diff --git a/rtl/cpu/alu.sv b/rtl/cpu/alu.sv index 78c8742..5582a2f 100644 --- a/rtl/cpu/alu.sv +++ b/rtl/cpu/alu.sv @@ -44,7 +44,8 @@ module alu ( `DEF_FF(f_r, f_next, f_we, '0); assign a_we = alu_op_valid_i; - assign a_next = (alu_op_i == ALU_OP_XOR) ? a_xor : + assign a_next = (alu_op_i == ALU_OP_XOR) ? a_xor : + (alu_op_i == ALU_OP_NOP) ? operand_i : a_r; assign f_we = alu_op_valid_i; diff --git a/rtl/cpu/control.sv b/rtl/cpu/control.sv index 96671f8..3d7a370 100644 --- a/rtl/cpu/control.sv +++ b/rtl/cpu/control.sv @@ -24,6 +24,7 @@ module control ( output alu_op_t alu_op_o, output op_src_t op_src_o, output op_dest_t op_dest_o, + output reg8_t reg8_dest_o, output reg8_t reg8_src_o, output alu16_op_t alu16_op_o, output reg16_t reg16_src_o, @@ -70,6 +71,7 @@ module control ( logic decoder_need_instr1; logic decoder_need_instr2; logic decoder_is_undef; + logic decoder_alu_op_valid; logic decoder_memory_we; adr_src_t decoder_adr_src; @@ -140,11 +142,12 @@ module control ( .sp_we_o (sp_we), .sp_src_o (sp_src), - .alu_op_valid_o(alu_op_valid_o), + .alu_op_valid_o(decoder_alu_op_valid), .alu_op_o (alu_op_o), .op_src_o (op_src_o), .op_dest_o (op_dest_o), + .reg8_dest_o (reg8_dest_o), .reg8_src_o (reg8_src_o), .alu16_op_o (alu16_op_o), @@ -163,6 +166,7 @@ module control ( assign is_undef = instr_valid & decoder_is_undef; assign instr_valid = (state_r == ST2_EXEC | state_r == ST3_EXEC | state_r == ST4_EXEC); + 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); diff --git a/rtl/cpu/cpu.sv b/rtl/cpu/cpu.sv index b6797f4..bb4d783 100644 --- a/rtl/cpu/cpu.sv +++ b/rtl/cpu/cpu.sv @@ -66,6 +66,7 @@ module cpu ( .instr_undef_o (instr_undef), .operand8_o (operand8), .operand16_o (operand16), + .reg8_dest_o (reg8_wselect), .reg8_src_o (reg8_rselect), .alu16_op_o (alu16_op), .reg16_src_o (reg16_rselect), @@ -111,17 +112,17 @@ module cpu ( assign alu_operand = (op_src == OP_SRC_A) ? rega : (op_src == OP_SRC_OPERAND8) ? operand8 : (op_src == OP_SRC_REG8) ? reg8_rdata : - '0; + 'X; - assign reg8_wselect = reg8_t'('X); - assign reg8_we = '0; - assign reg8_wdata = operand8; + assign reg8_we = instr_valid & (op_dest == OP_DEST_REG8); + assign reg8_wdata = 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; assign address_o = (adr_src == ADR_SRC_HL) ? hl : pc; - assign wdata_o = rega; + assign wdata_o = (op_dest == OP_DEST_MEMORY) ? alu_operand : + rega; // ldi/ldd hl, a use the normal control paths for HL endmodule : cpu diff --git a/rtl/cpu/cpu_pkg.svh b/rtl/cpu/cpu_pkg.svh index 667fae2..78943fb 100644 --- a/rtl/cpu/cpu_pkg.svh +++ b/rtl/cpu/cpu_pkg.svh @@ -48,7 +48,8 @@ package cpu_pkg; ALU_OP_XOR = 4'h05, ALU_OP_OR = 4'h06, ALU_OP_CP = 4'h07, - ALU_OP_BIT = 4'h08 + ALU_OP_BIT = 4'h08, + ALU_OP_NOP = 4'h09 } alu_op_t; typedef enum logic [1:0] { @@ -66,8 +67,10 @@ package cpu_pkg; } op_src_t; typedef enum { + OP_DEST_A, OP_DEST_REG8, - OP_DEST_REG16 + OP_DEST_REG16, + OP_DEST_MEMORY } op_dest_t; typedef enum { diff --git a/rtl/cpu/decode.sv b/rtl/cpu/decode.sv index 5c5c2bc..442ee5b 100644 --- a/rtl/cpu/decode.sv +++ b/rtl/cpu/decode.sv @@ -21,6 +21,7 @@ module decode ( output op_src_t op_src_o, output op_dest_t op_dest_o, + output reg8_t reg8_dest_o, output reg8_t reg8_src_o, output alu16_op_t alu16_op_o, output reg16_t reg16_dest_o, @@ -40,6 +41,8 @@ module decode ( logic dec_q; logic is_cb; + logic is_ld_a_nn; + logic is_ld_r_nn; logic is_ld_rr_nnnn; logic is_ld_sp_nnnn; logic is_ldd_hl_a; @@ -47,6 +50,7 @@ module decode ( logic is_bit_n_r; logic is_jr_cc_n; + reg8_t reg8_dest; reg8_t reg8_src; assign dec_x = instr0_i[7:6]; @@ -57,6 +61,8 @@ module decode ( assign is_cb = (instr0_i == 8'hCB); + assign is_ld_a_nn = is_ld_r_nn & (reg8_dest == REG8_A); + assign is_ld_r_nn = (dec_x == 2'h0) & (dec_z == 3'h6); assign is_ld_rr_nnnn = (dec_x == 2'h0) & (dec_z == 3'h1) & ~dec_q & (dec_p != 2'h3); assign is_ld_sp_nnnn = (dec_x == 2'h0) & (dec_z == 3'h1) & ~dec_q & (dec_p == 2'h3); assign is_ldd_hl_a = (dec_x == 2'h0) & (dec_z == 3'h2) & ~dec_q & (dec_p == 2'h3); @@ -68,30 +74,36 @@ module decode ( assign reg8_src = is_cb ? reg8_t'(instr1_i[2:0]) : 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; + 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); + 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); 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; + 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 : alu_op_t'({1'b0, dec_y}); - assign op_dest_o = is_ld_rr_nnnn ? OP_DEST_REG16 : - is_ldd_hl_a ? OP_DEST_REG16 : - op_dest_t'('X); + assign op_dest_o = (is_ld_r_nn & reg8_dest == REG8_PHL) ? OP_DEST_MEMORY : + is_ld_a_nn ? OP_DEST_A : + is_ld_r_nn ? OP_DEST_REG8 : + is_ld_rr_nnnn ? OP_DEST_REG16 : + is_ldd_hl_a ? OP_DEST_REG16 : + 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_ld_r_nn ? OP_SRC_OPERAND8 : is_ld_rr_nnnn ? OP_SRC_OPERAND16 : is_ldd_hl_a ? OP_SRC_REG16 : is_bit_n_r ? OP_SRC_REG8 : op_src_t'('X); + assign reg8_dest_o = reg8_dest; assign reg8_src_o = reg8_src; 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); @@ -99,11 +111,12 @@ module decode ( 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 adr_src_o = is_ldd_hl_a ? ADR_SRC_HL : + (is_ld_r_nn & reg8_dest == REG8_PHL) ? ADR_SRC_HL : + ADR_SRC_PC; assign cc_o = cc_t'(dec_y[1:0]); - assign memory_we_o = is_ldd_hl_a; + assign memory_we_o = is_ldd_hl_a | (is_ld_r_nn & reg8_dest == REG8_PHL); endmodule : decode