From 8f0b8d3a48979b44dbb81a4701c771baa7a2c29d Mon Sep 17 00:00:00 2001 From: Koray Yanik Date: Thu, 18 Feb 2021 23:22:26 +0000 Subject: [PATCH] Implemented LDD (HL), A --- rtl/cpu/alu.sv | 17 ++++++++++++++++- rtl/cpu/control.sv | 13 +++++++++++-- rtl/cpu/cpu.sv | 37 +++++++++++++++++++++++++++++-------- rtl/cpu/cpu_pkg.svh | 11 +++++++++-- rtl/cpu/decode.sv | 23 +++++++++++++++++------ rtl/cpu/registers.sv | 11 +++++++++-- rtl/shared/rom.sv | 2 +- 7 files changed, 92 insertions(+), 22 deletions(-) diff --git a/rtl/cpu/alu.sv b/rtl/cpu/alu.sv index 987b2a4..28dfaae 100644 --- a/rtl/cpu/alu.sv +++ b/rtl/cpu/alu.sv @@ -10,8 +10,14 @@ module alu ( input alu_op_t alu_op_i, input logic [7:0] operand_i, + input alu16_op_t alu16_op_i, + input logic [15:0] inx16_i, + input logic [15:0] iny16_i, + output logic [ 7:0] a_o, - output logic [ 7:0] f_o + output logic [ 7:0] f_o, + + output logic [15:0] out16_o ); logic a_we; @@ -25,6 +31,11 @@ module alu ( logic [ 7:0] a_xor; logic [ 7:0] f_xor; + logic [16:0] out16_add; + logic [ 7:0] f16_add; + logic [15:0] out16_inc; + logic [15:0] out16_dec; + `DEF_FF(a_r, a_next, a_we, '0); `DEF_FF(f_r, f_next, f_we, '0); @@ -39,7 +50,11 @@ module alu ( assign a_xor = (a_r ^ operand_i); assign f_xor = {~(|a_xor), 3'b0, f_r[3:0]}; + assign out16_dec = (inx16_i - 16'h01); + assign a_o = a_r; assign f_o = f_r; + 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 19bf593..7bbe8f0 100644 --- a/rtl/cpu/control.sv +++ b/rtl/cpu/control.sv @@ -22,8 +22,11 @@ module control ( output alu_op_t alu_op_o, output op_src_t op_src_o, output op_dest_t op_dest_o, + output alu16_op_t alu16_op_o, + output reg16_t reg16_src_o, output reg16_t reg16_dest_o, + output logic memory_we_o, output adr_src_t adr_src_o ); @@ -64,6 +67,7 @@ module control ( logic decoder_need_instr1; logic decoder_need_instr2; logic decoder_is_undef; + logic decoder_memory_we; adr_src_t decoder_adr_src; logic is_undef; @@ -132,7 +136,11 @@ module control ( .op_src_o (op_src_o), .op_dest_o (op_dest_o), + .alu16_op_o (alu16_op_o), + .reg16_src_o (reg16_src_o), .reg16_dest_o (reg16_dest_o), + + .memory_we_o (decoder_memory_we), .adr_src_o (decoder_adr_src) ); @@ -155,7 +163,8 @@ module control ( assign operand8_o = operand0_r; assign operand16_o = {operand1_r, operand0_r}; - assign adr_src_o = (state_r == ST2_EXEC) | (state_r == ST4_EXEC) ? decoder_adr_src : - ADR_SRC_PC; + assign memory_we_o = ((state_r == ST2_EXEC) | (state_r == ST4_EXEC)) & decoder_memory_we; + assign adr_src_o = (state_r == ST2_EXEC) | (state_r == ST4_EXEC) ? decoder_adr_src : + ADR_SRC_PC; endmodule : control diff --git a/rtl/cpu/cpu.sv b/rtl/cpu/cpu.sv index 2d04d02..ed2c11c 100644 --- a/rtl/cpu/cpu.sv +++ b/rtl/cpu/cpu.sv @@ -7,7 +7,9 @@ module cpu ( input logic nreset_i, output logic [15:0] address_o, - input logic [ 7:0] rdata_i + input logic [ 7:0] rdata_i, + output logic we_o, + output logic [ 7:0] wdata_o ); state_t state; @@ -16,6 +18,7 @@ module cpu ( alu_op_t alu_op; op_src_t op_src; op_dest_t op_dest; + adr_src_t adr_src; logic [ 7:0] alu_operand; @@ -24,6 +27,7 @@ module cpu ( logic [15:0] pc; logic [15:0] sp; + logic [15:0] hl; logic instr_valid; logic instr_undef; @@ -39,8 +43,12 @@ module cpu ( logic [15:0] reg16_wdata; reg8_t reg8_rselect; reg16_t reg16_rselect; + reg16_t reg16_rselect2; logic [ 7:0] reg8_rdata; logic [15:0] reg16_rdata; + logic [15:0] reg16_rdata2; + alu16_op_t alu16_op; + logic [15:0] alu_out16; control control_inst ( .clk_i (clk_i), @@ -57,7 +65,11 @@ module cpu ( .instr_undef_o (instr_undef), .operand8_o (operand8), .operand16_o (operand16), - .reg16_dest_o (reg16_wselect) + .alu16_op_o (alu16_op), + .reg16_src_o (reg16_rselect), + .reg16_dest_o (reg16_wselect), + .memory_we_o (we_o), + .adr_src_o (adr_src) ); alu alu_inst ( @@ -67,7 +79,11 @@ module cpu ( .alu_op_i (alu_op), .operand_i (alu_operand), .a_o (rega), - .f_o (regf) + .f_o (regf), + .alu16_op_i (alu16_op), + .inx16_i (reg16_rdata2), + .iny16_i (reg16_rdata), + .out16_o (alu_out16) ); registers registers_inst ( @@ -83,7 +99,10 @@ module cpu ( .reg8_rselect_i (reg8_rselect), .reg8_rdata_o (reg8_rdata), .reg16_rselect_i(reg16_rselect), - .reg16_rdata_o (reg16_rdata) + .reg16_rdata_o (reg16_rdata), + .reg16_rselect2_i(reg16_rselect2), + .reg16_rdata2_o (reg16_rdata2), + .hl_o (hl) ); assign alu_operand = (op_src == OP_SRC_A) ? rega : @@ -92,11 +111,13 @@ module cpu ( assign reg8_wselect = reg8_t'('X); assign reg8_we = '0; assign reg8_wdata = operand8; - assign reg16_we = instr_valid & (op_dest == OP_DEST_R16); - assign reg16_wdata = operand16; + assign reg16_we = instr_valid & (op_dest == OP_DEST_REG16); + assign reg16_wdata = (op_src == OP_SRC_OPERAND16) ? operand16 : alu_out16; assign reg8_rselect = reg8_t'('X); - assign reg16_rselect = reg16_t'('X); + assign reg16_rselect2 = reg16_wselect; - assign address_o = pc; + assign address_o = (adr_src == ADR_SRC_HL) ? hl : + pc; + assign wdata_o = rega; endmodule : cpu diff --git a/rtl/cpu/cpu_pkg.svh b/rtl/cpu/cpu_pkg.svh index 76050fd..0baa93d 100644 --- a/rtl/cpu/cpu_pkg.svh +++ b/rtl/cpu/cpu_pkg.svh @@ -40,15 +40,22 @@ package cpu_pkg; ALU_OP_CP = 3'h07 } alu_op_t; + typedef enum logic [1:0] { + ALU16_OP_ADD = 2'h00, + ALU16_INC = 2'h01, + ALU16_DEC = 2'h02 + } alu16_op_t; + typedef enum { OP_SRC_A, OP_SRC_REG8, - OP_SRC_OPERAND16 + OP_SRC_OPERAND16, + OP_SRC_REG16 } op_src_t; typedef enum { OP_DEST_A, - OP_DEST_R16 + OP_DEST_REG16 } op_dest_t; typedef enum { diff --git a/rtl/cpu/decode.sv b/rtl/cpu/decode.sv index f7927d9..50d8048 100644 --- a/rtl/cpu/decode.sv +++ b/rtl/cpu/decode.sv @@ -21,9 +21,12 @@ module decode ( output op_src_t op_src_o, output op_dest_t op_dest_o, + output alu16_op_t alu16_op_o, output reg16_t reg16_dest_o, + output reg16_t reg16_src_o, - output adr_src_t adr_src_o + output adr_src_t adr_src_o, + output logic memory_we_o ); logic [1:0] dec_x; @@ -34,6 +37,7 @@ module decode ( logic is_ld_rr_nnnn; logic is_ld_sp_nnnn; + logic is_ldd_hl_a; logic is_alu_a_n; assign dec_x = instr0_i[7:6]; @@ -44,28 +48,35 @@ module decode ( 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_alu_a_n = (dec_x == 3'h2); assign need_instr1_o = is_ld_sp_nnnn | is_ld_rr_nnnn; 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_n); + assign undef_o = ~(is_ld_sp_nnnn | is_ld_rr_nnnn | is_alu_a_n | is_ldd_hl_a); assign sp_we_o = is_ld_sp_nnnn & (state_i == ST4_EXEC); assign alu_op_valid_o = is_alu_a_n; assign alu_op_o = alu_op_t'(dec_y); - assign op_dest_o = is_alu_a_n ? OP_DEST_A : - is_ld_rr_nnnn ? OP_DEST_R16 : + assign op_dest_o = is_alu_a_n ? OP_DEST_A : + 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_n ? OP_SRC_REG8 : is_ld_rr_nnnn ? OP_SRC_OPERAND16 : + is_ldd_hl_a ? OP_SRC_REG16 : op_src_t'('X); - assign reg16_dest_o = reg16_t'(dec_p); + assign reg16_src_o = is_ldd_hl_a ? REG16_HL : reg16_t'(dec_p); + assign reg16_dest_o = is_ldi_hl_a ? REG16_HL : reg16_t'(dec_p); - assign adr_src_o = ADR_SRC_PC; + assign adr_src_o = is_ldi_hl_a ? ADR_SRC_HL : + ADR_SRC_PC; + + assign memory_we_o = is_ldi_hl_a; endmodule : decode \ No newline at end of file diff --git a/rtl/cpu/registers.sv b/rtl/cpu/registers.sv index 53cf6e8..5f76e56 100644 --- a/rtl/cpu/registers.sv +++ b/rtl/cpu/registers.sv @@ -16,8 +16,12 @@ module registers ( input reg8_t reg8_rselect_i, input reg16_t reg16_rselect_i, + input reg16_t reg16_rselect2_i, output logic [ 7:0] reg8_rdata_o, - output logic [15:0] reg16_rdata_o + output logic [15:0] reg16_rdata_o, + output logic [15:0] reg16_rdata2_o, + + output logic [15:0] hl_o ); logic [15:0] reg_r [0:2]; @@ -44,6 +48,9 @@ module registers ( assign reg8_rdata_o = reg8_rselect_i[0] ? reg_r[reg8_rselect_i[2:1]][15:8] : reg_r[reg8_rselect_i[2:1]][ 7:0]; - assign reg16_rdata_o = reg_r[reg16_rselect_i]; + assign reg16_rdata_o = reg_r[reg16_rselect_i]; + assign reg16_rdata2_o = reg_r[reg16_rselect2_i]; + + assign hl_o = reg_r[REG16_HL]; endmodule : registers diff --git a/rtl/shared/rom.sv b/rtl/shared/rom.sv index e716117..9986ba5 100644 --- a/rtl/shared/rom.sv +++ b/rtl/shared/rom.sv @@ -18,7 +18,7 @@ always_ff @(posedge clk_i) initial begin static integer fd = $fopen(FILE_NAME, "rb"); - void'($fread(rom, fd)); + static integer rv = $fread(rom, fd); end endmodule : rom