Implement LD r, $nn

This commit is contained in:
Koray Yanik 2021-02-20 15:56:22 +00:00
parent 7327ecffb9
commit 67361093ec
5 changed files with 41 additions and 19 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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 {

View File

@ -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