diff --git a/.gitignore b/.gitignore index ec05609..548bd9e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ build/.Xil build/xsim.dir build/*.wcfg +build/vivado_* diff --git a/rtl/cpu/cpu.sv b/rtl/cpu/cpu.sv index 2ecfd02..d433620 100644 --- a/rtl/cpu/cpu.sv +++ b/rtl/cpu/cpu.sv @@ -116,6 +116,7 @@ module cpu ( assign alu_operand = (op_src == OP_SRC_A) ? rega : (op_src == OP_SRC_OPERAND8) ? operand8 : (op_src == OP_SRC_REG8) ? reg8_rdata : + (op_src == OP_SRC_MEMORY) ? rdata_i : 'X; assign reg8_we = instr_valid & (op_dest == OP_DEST_REG8); @@ -124,9 +125,11 @@ module cpu ( 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 : - (adr_src == ADR_SRC_REG8) ? {8'hFF, reg8_rdata} : - pc; + assign address_o = (adr_src == ADR_SRC_HL) ? hl : + (adr_src == ADR_SRC_REG8) ? {8'hFF, reg8_rdata} : + (adr_src == ADR_SRC_REG16) ? reg16_rdata : + (adr_src == ADR_SRC_OPERAND16) ? operand16 : + pc; assign wdata_o = (op_dest == OP_DEST_MEMORY) ? alu_operand : rega; // ldi/ldd hl, a use the normal control paths for HL diff --git a/rtl/cpu/cpu_pkg.svh b/rtl/cpu/cpu_pkg.svh index 43ea5d2..fa21521 100644 --- a/rtl/cpu/cpu_pkg.svh +++ b/rtl/cpu/cpu_pkg.svh @@ -64,6 +64,7 @@ package cpu_pkg; OP_SRC_A, OP_SRC_REG8, OP_SRC_OPERAND8, + OP_SRC_MEMORY, OP_SRC_OPERAND16, OP_SRC_REG16 } op_src_t; @@ -82,7 +83,9 @@ package cpu_pkg; typedef enum { ADR_SRC_PC, ADR_SRC_HL, - ADR_SRC_REG8 // extended with FF + ADR_SRC_REG8, // extended with FF + ADR_SRC_REG16, + ADR_SRC_OPERAND16 } adr_src_t; typedef enum { diff --git a/rtl/cpu/decode.sv b/rtl/cpu/decode.sv index 88ff0b1..9aac173 100644 --- a/rtl/cpu/decode.sv +++ b/rtl/cpu/decode.sv @@ -42,9 +42,12 @@ module decode ( logic dec_q; logic is_cb; + logic is_ld_r_r; logic is_ld_a_nn; logic is_ld_r_nn; logic is_ldh_c_a; + logic is_ld_rrrr_a; + logic is_ld_nnnn_a; logic is_ld_rr_nnnn; logic is_ld_sp_nnnn; logic is_ldd_hl_a; @@ -65,11 +68,14 @@ module decode ( assign is_cb = (instr0_i == 8'hCB); + assign is_ld_r_r = (dec_x == 2'h1) & ((dec_z != 3'h6) | (dec_y != 3'h6)); 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); + assign is_ld_rrrr_a = (dec_x == 2'h0) & (dec_z == 3'h2) & ~dec_q & (dec_p != 2'h3); + assign is_ld_nnnn_a = (dec_x == 2'h0) & (dec_z == 3'h2) & ~dec_q & (dec_p == 2'h2); assign is_ldh_c_a = instr0_i == 8'hE2; assign is_alu_a_r = (dec_x == 3'h2); @@ -89,7 +95,7 @@ module decode ( 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 | is_inc_r); + assign undef_o = ~(is_ld_r_r | 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 | is_ld_rrrr_a); assign sp_we_o = is_ld_sp_nnnn & (state_i == ST4_EXEC); @@ -101,7 +107,10 @@ module decode ( 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 : + assign op_dest_o = (is_ld_r_r & reg8_dest == REG8_PHL) ? OP_DEST_MEMORY : + (is_ld_r_nn & 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_nn ? OP_DEST_A : is_ld_r_nn ? OP_DEST_REG8 : is_ldh_c_a ? OP_DEST_MEMORY : @@ -111,15 +120,17 @@ module decode ( 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 : - is_ldd_hl_a ? OP_SRC_REG16 : - is_bit_n_r ? OP_SRC_REG8 : - op_src_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 : + (is_alu_a_r & reg8_src != REG8_A) ? OP_SRC_REG8 : + (is_ld_r_r & reg8_src == REG8_PHL) ? OP_SRC_MEMORY : + 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 : + 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; @@ -129,13 +140,17 @@ 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 : + 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_nn & reg8_dest == REG8_PHL) ? ADR_SRC_HL : is_ldh_c_a ? ADR_SRC_REG8 : + is_ld_nnnn_a ? ADR_SRC_OPERAND16 : + is_ld_rrrr_a ? ADR_SRC_REG16: ADR_SRC_PC; assign cc_o = cc_t'(dec_y[1:0]); - assign memory_we_o = is_ldd_hl_a | is_ldh_c_a | (is_ld_r_nn & reg8_dest == REG8_PHL); + assign memory_we_o = is_ldd_hl_a | is_ldh_c_a | is_ld_rrrr_a | (is_ld_r_nn & reg8_dest == REG8_PHL) | (is_ld_r_r & reg8_dest == REG8_PHL); endmodule : decode