Implement JR CC, $nn
This commit is contained in:
parent
93912e2089
commit
7327ecffb9
@ -8,6 +8,8 @@ module control (
|
|||||||
|
|
||||||
input logic [ 7:0] rdata_i,
|
input logic [ 7:0] rdata_i,
|
||||||
|
|
||||||
|
input logic [ 7:0] f_i,
|
||||||
|
|
||||||
output state_t state_o,
|
output state_t state_o,
|
||||||
|
|
||||||
output logic [15:0] pc_o,
|
output logic [15:0] pc_o,
|
||||||
@ -74,8 +76,12 @@ module control (
|
|||||||
logic is_undef;
|
logic is_undef;
|
||||||
logic pc_incr;
|
logic pc_incr;
|
||||||
logic instr_valid;
|
logic instr_valid;
|
||||||
|
logic branch_taken;
|
||||||
|
logic branch_cc_true;
|
||||||
|
|
||||||
sp_src_t sp_src;
|
sp_src_t sp_src;
|
||||||
|
pc_src_t pc_src;
|
||||||
|
cc_t cc;
|
||||||
|
|
||||||
always_ff @(posedge clk_i) begin
|
always_ff @(posedge clk_i) begin
|
||||||
nreset_r <= nreset_i;
|
nreset_r <= nreset_i;
|
||||||
@ -89,8 +95,9 @@ module control (
|
|||||||
`DEF_FF(operand0_r, operand0_next, operand0_we, '0);
|
`DEF_FF(operand0_r, operand0_next, operand0_we, '0);
|
||||||
`DEF_FF(operand1_r, operand1_next, operand1_we, '0);
|
`DEF_FF(operand1_r, operand1_next, operand1_we, '0);
|
||||||
|
|
||||||
assign pc_we = nreset_r & pc_incr & ~is_undef;
|
assign pc_we = (nreset_r & pc_incr & ~is_undef) | branch_taken;
|
||||||
assign pc_next = (pc_r + 16'b1);
|
assign pc_next = (branch_taken & pc_src == PC_SRC_OPERAND8) ? (pc_r + {{8{operand0_r[7]}}, operand0_r}) :
|
||||||
|
(pc_r + 16'b1);
|
||||||
|
|
||||||
assign sp_next = (sp_src == SP_SRC_OPERAND16) ? {operand1_r, operand0_r} : '0;
|
assign sp_next = (sp_src == SP_SRC_OPERAND16) ? {operand1_r, operand0_r} : '0;
|
||||||
|
|
||||||
@ -145,7 +152,9 @@ module control (
|
|||||||
.reg16_dest_o (reg16_dest_o),
|
.reg16_dest_o (reg16_dest_o),
|
||||||
|
|
||||||
.memory_we_o (decoder_memory_we),
|
.memory_we_o (decoder_memory_we),
|
||||||
.adr_src_o (decoder_adr_src)
|
.adr_src_o (decoder_adr_src),
|
||||||
|
.cc_o (cc),
|
||||||
|
.pc_src_o (pc_src)
|
||||||
);
|
);
|
||||||
|
|
||||||
assign decoder_instr0_selected = (state_r == ST1_DEC) ? rdata_i : instr_r;
|
assign decoder_instr0_selected = (state_r == ST1_DEC) ? rdata_i : instr_r;
|
||||||
@ -157,6 +166,12 @@ module control (
|
|||||||
|
|
||||||
assign pc_incr = (state_r == ST0_ADDR) | (state_r == ST1_DEC & decoder_need_instr1) | (state_r == ST2_DEC & decoder_need_instr2);
|
assign pc_incr = (state_r == ST0_ADDR) | (state_r == ST1_DEC & decoder_need_instr1) | (state_r == ST2_DEC & decoder_need_instr2);
|
||||||
|
|
||||||
|
assign branch_taken = instr_valid & (pc_src != PC_SRC_SEQ) & branch_cc_true;
|
||||||
|
assign branch_cc_true = ((cc == CC_NZ) & ~f_i[7]) |
|
||||||
|
((cc == CC_Z) & f_i[7]) |
|
||||||
|
((cc == CC_NC) & ~f_i[4]) |
|
||||||
|
((cc == CC_C) & f_i[4]);
|
||||||
|
|
||||||
assign state_o = state_r;
|
assign state_o = state_r;
|
||||||
assign pc_o = pc_r;
|
assign pc_o = pc_r;
|
||||||
assign sp_o = sp_r;
|
assign sp_o = sp_r;
|
||||||
|
@ -55,6 +55,7 @@ module cpu (
|
|||||||
.nreset_i (nreset_i),
|
.nreset_i (nreset_i),
|
||||||
.rdata_i (rdata_i),
|
.rdata_i (rdata_i),
|
||||||
.state_o (state),
|
.state_o (state),
|
||||||
|
.f_i (regf),
|
||||||
.pc_o (pc),
|
.pc_o (pc),
|
||||||
.sp_o (sp),
|
.sp_o (sp),
|
||||||
.alu_op_valid_o(alu_op_valid),
|
.alu_op_valid_o(alu_op_valid),
|
||||||
|
@ -32,6 +32,13 @@ package cpu_pkg;
|
|||||||
REG16_SP_AF = 2'h03
|
REG16_SP_AF = 2'h03
|
||||||
} reg16_t;
|
} reg16_t;
|
||||||
|
|
||||||
|
typedef enum logic [1:0] {
|
||||||
|
CC_NZ = 2'h00,
|
||||||
|
CC_Z = 2'h01,
|
||||||
|
CC_NC = 2'h02,
|
||||||
|
CC_C = 2'h03
|
||||||
|
} cc_t;
|
||||||
|
|
||||||
typedef enum logic [3:0] {
|
typedef enum logic [3:0] {
|
||||||
ALU_OP_ADD = 4'h00,
|
ALU_OP_ADD = 4'h00,
|
||||||
ALU_OP_ADC = 4'h01,
|
ALU_OP_ADC = 4'h01,
|
||||||
@ -72,6 +79,11 @@ package cpu_pkg;
|
|||||||
ADR_SRC_HL
|
ADR_SRC_HL
|
||||||
} adr_src_t;
|
} adr_src_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PC_SRC_SEQ,
|
||||||
|
PC_SRC_OPERAND8
|
||||||
|
} pc_src_t;
|
||||||
|
|
||||||
endpackage
|
endpackage
|
||||||
|
|
||||||
`define DEF_FF(register, next, we, rst_value) \
|
`define DEF_FF(register, next, we, rst_value) \
|
||||||
|
@ -26,6 +26,9 @@ module decode (
|
|||||||
output reg16_t reg16_dest_o,
|
output reg16_t reg16_dest_o,
|
||||||
output reg16_t reg16_src_o,
|
output reg16_t reg16_src_o,
|
||||||
|
|
||||||
|
output cc_t cc_o,
|
||||||
|
|
||||||
|
output pc_src_t pc_src_o,
|
||||||
output adr_src_t adr_src_o,
|
output adr_src_t adr_src_o,
|
||||||
output logic memory_we_o
|
output logic memory_we_o
|
||||||
);
|
);
|
||||||
@ -42,6 +45,7 @@ module decode (
|
|||||||
logic is_ldd_hl_a;
|
logic is_ldd_hl_a;
|
||||||
logic is_alu_a_r;
|
logic is_alu_a_r;
|
||||||
logic is_bit_n_r;
|
logic is_bit_n_r;
|
||||||
|
logic is_jr_cc_n;
|
||||||
|
|
||||||
reg8_t reg8_src;
|
reg8_t reg8_src;
|
||||||
|
|
||||||
@ -60,15 +64,16 @@ module decode (
|
|||||||
assign is_alu_a_r = (dec_x == 3'h2);
|
assign is_alu_a_r = (dec_x == 3'h2);
|
||||||
assign is_bit_n_r = (is_cb & instr1_i[7:6] == 2'h1);
|
assign is_bit_n_r = (is_cb & instr1_i[7:6] == 2'h1);
|
||||||
|
|
||||||
|
assign is_jr_cc_n = (dec_x == 2'h0) & (dec_z == 2'h0) & dec_y[2];
|
||||||
|
|
||||||
assign reg8_src = is_cb ? reg8_t'(instr1_i[2:0]) :
|
assign reg8_src = is_cb ? reg8_t'(instr1_i[2:0]) :
|
||||||
reg8_t'(dec_z);
|
reg8_t'(dec_z);
|
||||||
|
|
||||||
|
|
||||||
assign need_instr1_o = is_ld_sp_nnnn | is_ld_rr_nnnn | is_cb;
|
assign need_instr1_o = is_ld_sp_nnnn | is_ld_rr_nnnn | is_cb | is_jr_cc_n;
|
||||||
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);
|
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 sp_we_o = is_ld_sp_nnnn & (state_i == ST4_EXEC);
|
assign sp_we_o = is_ld_sp_nnnn & (state_i == ST4_EXEC);
|
||||||
|
|
||||||
@ -91,9 +96,14 @@ module decode (
|
|||||||
assign reg16_src_o = is_ldd_hl_a ? REG16_HL : reg16_t'(dec_p);
|
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);
|
assign reg16_dest_o = is_ldd_hl_a ? REG16_HL : reg16_t'(dec_p);
|
||||||
|
|
||||||
|
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_ldd_hl_a ? ADR_SRC_HL :
|
||||||
ADR_SRC_PC;
|
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;
|
||||||
|
|
||||||
endmodule : decode
|
endmodule : decode
|
||||||
|
Loading…
Reference in New Issue
Block a user