Implement ld r, r

This commit is contained in:
Koray Yanik 2021-02-22 21:42:40 +00:00
parent ded64a8954
commit dc32757dfc
4 changed files with 39 additions and 17 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
build/.Xil build/.Xil
build/xsim.dir build/xsim.dir
build/*.wcfg build/*.wcfg
build/vivado_*

View File

@ -116,6 +116,7 @@ module cpu (
assign alu_operand = (op_src == OP_SRC_A) ? rega : assign alu_operand = (op_src == OP_SRC_A) ? rega :
(op_src == OP_SRC_OPERAND8) ? operand8 : (op_src == OP_SRC_OPERAND8) ? operand8 :
(op_src == OP_SRC_REG8) ? reg8_rdata : (op_src == OP_SRC_REG8) ? reg8_rdata :
(op_src == OP_SRC_MEMORY) ? rdata_i :
'X; 'X;
assign reg8_we = instr_valid & (op_dest == OP_DEST_REG8); 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_wdata = (op_src == OP_SRC_OPERAND16) ? operand16 : alu_out16;
assign reg16_rselect2 = reg16_wselect; assign reg16_rselect2 = reg16_wselect;
assign address_o = (adr_src == ADR_SRC_HL) ? hl : assign address_o = (adr_src == ADR_SRC_HL) ? hl :
(adr_src == ADR_SRC_REG8) ? {8'hFF, reg8_rdata} : (adr_src == ADR_SRC_REG8) ? {8'hFF, reg8_rdata} :
pc; (adr_src == ADR_SRC_REG16) ? reg16_rdata :
(adr_src == ADR_SRC_OPERAND16) ? operand16 :
pc;
assign wdata_o = (op_dest == OP_DEST_MEMORY) ? alu_operand : assign wdata_o = (op_dest == OP_DEST_MEMORY) ? alu_operand :
rega; // ldi/ldd hl, a use the normal control paths for HL rega; // ldi/ldd hl, a use the normal control paths for HL

View File

@ -64,6 +64,7 @@ package cpu_pkg;
OP_SRC_A, OP_SRC_A,
OP_SRC_REG8, OP_SRC_REG8,
OP_SRC_OPERAND8, OP_SRC_OPERAND8,
OP_SRC_MEMORY,
OP_SRC_OPERAND16, OP_SRC_OPERAND16,
OP_SRC_REG16 OP_SRC_REG16
} op_src_t; } op_src_t;
@ -82,7 +83,9 @@ package cpu_pkg;
typedef enum { typedef enum {
ADR_SRC_PC, ADR_SRC_PC,
ADR_SRC_HL, ADR_SRC_HL,
ADR_SRC_REG8 // extended with FF ADR_SRC_REG8, // extended with FF
ADR_SRC_REG16,
ADR_SRC_OPERAND16
} adr_src_t; } adr_src_t;
typedef enum { typedef enum {

View File

@ -42,9 +42,12 @@ module decode (
logic dec_q; logic dec_q;
logic is_cb; logic is_cb;
logic is_ld_r_r;
logic is_ld_a_nn; logic is_ld_a_nn;
logic is_ld_r_nn; logic is_ld_r_nn;
logic is_ldh_c_a; logic is_ldh_c_a;
logic is_ld_rrrr_a;
logic is_ld_nnnn_a;
logic is_ld_rr_nnnn; logic is_ld_rr_nnnn;
logic is_ld_sp_nnnn; logic is_ld_sp_nnnn;
logic is_ldd_hl_a; logic is_ldd_hl_a;
@ -65,11 +68,14 @@ module decode (
assign is_cb = (instr0_i == 8'hCB); 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_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_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_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_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_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_ldh_c_a = instr0_i == 8'hE2;
assign is_alu_a_r = (dec_x == 3'h2); 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_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 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); 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}); alu_op_t'({1'b0, dec_y});
assign reg_write_alu_o = is_inc_r; 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_a_nn ? OP_DEST_A :
is_ld_r_nn ? OP_DEST_REG8 : is_ld_r_nn ? OP_DEST_REG8 :
is_ldh_c_a ? OP_DEST_MEMORY : is_ldh_c_a ? OP_DEST_MEMORY :
@ -111,15 +120,17 @@ module decode (
is_inc_r ? OP_DEST_REG8 : is_inc_r ? OP_DEST_REG8 :
op_dest_t'('X); op_dest_t'('X);
assign op_src_o = (is_alu_a_r & reg8_src == REG8_A) ? OP_SRC_A : 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_REG8 : (is_alu_a_r & reg8_src == REG8_A) ? OP_SRC_A :
is_inc_r ? OP_SRC_REG8 : (is_alu_a_r & reg8_src != REG8_A) ? OP_SRC_REG8 :
is_ld_r_nn ? OP_SRC_OPERAND8 : (is_ld_r_r & reg8_src == REG8_PHL) ? OP_SRC_MEMORY :
is_ldh_c_a ? OP_SRC_A : is_inc_r ? OP_SRC_REG8 :
is_ld_rr_nnnn ? OP_SRC_OPERAND16 : is_ld_r_nn ? OP_SRC_OPERAND8 :
is_ldd_hl_a ? OP_SRC_REG16 : is_ldh_c_a ? OP_SRC_A :
is_bit_n_r ? OP_SRC_REG8 : is_ld_rr_nnnn ? OP_SRC_OPERAND16 :
op_src_t'('X); 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_dest_o = reg8_dest;
assign reg8_src_o = reg8_src; assign reg8_src_o = reg8_src;
@ -129,13 +140,17 @@ module decode (
assign pc_src_o = is_jr_cc_n ? PC_SRC_OPERAND8 : assign pc_src_o = is_jr_cc_n ? PC_SRC_OPERAND8 :
PC_SRC_SEQ; 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_ld_r_nn & reg8_dest == REG8_PHL) ? ADR_SRC_HL :
is_ldh_c_a ? ADR_SRC_REG8 : is_ldh_c_a ? ADR_SRC_REG8 :
is_ld_nnnn_a ? ADR_SRC_OPERAND16 :
is_ld_rrrr_a ? ADR_SRC_REG16:
ADR_SRC_PC; ADR_SRC_PC;
assign cc_o = cc_t'(dec_y[1:0]); 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 endmodule : decode