Implemented BIT $n, r

First of the CB prefixed opcodes.
This commit is contained in:
Koray Yanik 2021-02-19 21:53:13 +00:00
parent 8c65e4a669
commit 93912e2089
5 changed files with 59 additions and 26 deletions

View File

@ -9,6 +9,7 @@ module alu (
input logic alu_op_valid_i,
input alu_op_t alu_op_i,
input logic [7:0] operand_i,
input logic [2:0] inx8_i, // Only used for bit/set/res
input alu16_op_t alu16_op_i,
input logic [15:0] inx16_i,
@ -31,6 +32,9 @@ module alu (
logic [ 7:0] a_xor;
logic [ 7:0] f_xor;
logic [ 7:0] a_bit; // Never written, only to test
logic [ 7:0] f_bit;
logic [16:0] out16_add;
logic [ 7:0] f16_add;
logic [15:0] out16_inc;
@ -41,15 +45,19 @@ module alu (
assign a_we = alu_op_valid_i;
assign a_next = (alu_op_i == ALU_OP_XOR) ? a_xor :
a_xor;
a_r;
assign f_we = alu_op_valid_i;
assign f_next = (alu_op_i == ALU_OP_XOR) ? f_xor :
f_xor;
(alu_op_i == ALU_OP_BIT) ? f_bit :
f_r;
assign a_xor = (a_r ^ operand_i);
assign f_xor = {~(|a_xor), 3'b0, f_r[3:0]};
assign a_bit = (operand_i - {4'b0, inx8_i});
assign f_bit = {~(|a_bit), 2'b10, f_r[4:0]};
assign out16_dec = (inx16_i - 16'h01);
assign a_o = a_r;

View File

@ -22,6 +22,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_src_o,
output alu16_op_t alu16_op_o,
output reg16_t reg16_src_o,
output reg16_t reg16_dest_o,
@ -112,8 +113,9 @@ module control (
ST1_DEC: state_next = decoder_need_instr1 ? ST2_DEC : ST2_EXEC;
ST2_EXEC: state_next = ST0_ADDR;
ST2_DEC: state_next = decoder_need_instr2 ? ST3_DEC : ST0_ADDR;
ST2_DEC: state_next = decoder_need_instr2 ? ST3_DEC : ST3_EXEC;
ST3_DEC: state_next = ST4_EXEC;
ST3_EXEC: state_next = ST0_ADDR;
ST4_EXEC: state_next = ST0_ADDR;
endcase
end
@ -136,6 +138,8 @@ module control (
.op_src_o (op_src_o),
.op_dest_o (op_dest_o),
.reg8_src_o (reg8_src_o),
.alu16_op_o (alu16_op_o),
.reg16_src_o (reg16_src_o),
.reg16_dest_o (reg16_dest_o),
@ -148,8 +152,8 @@ module control (
assign decoder_instr1_selected = (state_r == ST2_DEC) ? rdata_i : operand0_r;
assign decoder_instr2_selected = (state_r == ST3_DEC) ? rdata_i : operand1_r;
assign is_undef = (state_r != ST0_ADDR & decoder_is_undef);
assign instr_valid = (state_r == ST2_EXEC | state_r == ST4_EXEC);
assign is_undef = instr_valid & decoder_is_undef;
assign instr_valid = (state_r == ST2_EXEC | state_r == ST3_EXEC | state_r == ST4_EXEC);
assign pc_incr = (state_r == ST0_ADDR) | (state_r == ST1_DEC & decoder_need_instr1) | (state_r == ST2_DEC & decoder_need_instr2);
@ -163,8 +167,8 @@ module control (
assign operand8_o = operand0_r;
assign operand16_o = {operand1_r, operand0_r};
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;
assign memory_we_o = instr_valid & decoder_memory_we;
assign adr_src_o = instr_valid ? decoder_adr_src :
ADR_SRC_PC;
endmodule : control

View File

@ -65,6 +65,7 @@ module cpu (
.instr_undef_o (instr_undef),
.operand8_o (operand8),
.operand16_o (operand16),
.reg8_src_o (reg8_rselect),
.alu16_op_o (alu16_op),
.reg16_src_o (reg16_rselect),
.reg16_dest_o (reg16_wselect),
@ -78,6 +79,7 @@ module cpu (
.alu_op_valid_i(alu_op_valid),
.alu_op_i (alu_op),
.operand_i (alu_operand),
.inx8_i (operand8[5:3]), // Used for bit/set/res
.a_o (rega),
.f_o (regf),
.alu16_op_i (alu16_op),
@ -105,15 +107,16 @@ module cpu (
.hl_o (hl)
);
assign alu_operand = (op_src == OP_SRC_A) ? rega :
'0;
assign alu_operand = (op_src == OP_SRC_A) ? rega :
(op_src == OP_SRC_OPERAND8) ? operand8 :
(op_src == OP_SRC_REG8) ? reg8_rdata :
'0;
assign reg8_wselect = reg8_t'('X);
assign reg8_we = '0;
assign reg8_wdata = operand8;
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_rselect2 = reg16_wselect;
assign address_o = (adr_src == ADR_SRC_HL) ? hl :

View File

@ -10,6 +10,7 @@ package cpu_pkg;
ST2_EXEC,
ST2_DEC,
ST3_DEC,
ST3_EXEC,
ST4_EXEC
} state_t;
@ -19,7 +20,9 @@ package cpu_pkg;
REG8_D = 3'h02,
REG8_E = 3'h03,
REG8_H = 3'h04,
REG8_L = 3'h05
REG8_L = 3'h05,
REG8_PHL = 3'h06,
REG8_A = 3'h07
} reg8_t;
typedef enum logic [1:0] {
@ -29,15 +32,16 @@ package cpu_pkg;
REG16_SP_AF = 2'h03
} reg16_t;
typedef enum logic [2:0] {
ALU_OP_ADD = 3'h00,
ALU_OP_ADC = 3'h01,
ALU_OP_SUB = 3'h02,
ALU_OP_SBC = 3'h03,
ALU_OP_AND = 3'h04,
ALU_OP_XOR = 3'h05,
ALU_OP_OR = 3'h06,
ALU_OP_CP = 3'h07
typedef enum logic [3:0] {
ALU_OP_ADD = 4'h00,
ALU_OP_ADC = 4'h01,
ALU_OP_SUB = 4'h02,
ALU_OP_SBC = 4'h03,
ALU_OP_AND = 4'h04,
ALU_OP_XOR = 4'h05,
ALU_OP_OR = 4'h06,
ALU_OP_CP = 4'h07,
ALU_OP_BIT = 4'h08
} alu_op_t;
typedef enum logic [1:0] {
@ -49,12 +53,13 @@ package cpu_pkg;
typedef enum {
OP_SRC_A,
OP_SRC_REG8,
OP_SRC_OPERAND8,
OP_SRC_OPERAND16,
OP_SRC_REG16
} op_src_t;
typedef enum {
OP_DEST_A,
OP_DEST_REG8,
OP_DEST_REG16
} op_dest_t;

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_src_o,
output alu16_op_t alu16_op_o,
output reg16_t reg16_dest_o,
output reg16_t reg16_src_o,
@ -35,10 +36,12 @@ module decode (
logic [1:0] dec_p;
logic dec_q;
logic is_cb;
logic is_ld_rr_nnnn;
logic is_ld_sp_nnnn;
logic is_ldd_hl_a;
logic is_alu_a_r;
logic is_bit_n_r;
reg8_t reg8_src;
@ -48,21 +51,30 @@ module decode (
assign dec_p = instr0_i[5:4];
assign dec_q = instr0_i[3];
assign is_cb = (instr0_i == 8'hCB);
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_r = (dec_x == 3'h2);
assign is_bit_n_r = (is_cb & instr1_i[7:6] == 2'h1);
assign need_instr1_o = is_ld_sp_nnnn | is_ld_rr_nnnn;
assign reg8_src = is_cb ? reg8_t'(instr1_i[2:0]) :
reg8_t'(dec_z);
assign need_instr1_o = is_ld_sp_nnnn | is_ld_rr_nnnn | is_cb;
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);
assign undef_o = ~(is_ld_sp_nnnn | is_ld_rr_nnnn | is_alu_a_r | is_ldd_hl_a | is_bit_n_r);
assign sp_we_o = is_ld_sp_nnnn & (state_i == ST4_EXEC);
assign alu_op_o = alu_op_t'(dec_y);
assign alu_op_valid_o = is_alu_a_r;
assign alu_op_valid_o = is_alu_a_r | is_bit_n_r;
assign alu_op_o = is_bit_n_r ? ALU_OP_BIT :
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 :
@ -72,6 +84,7 @@ module decode (
(is_alu_a_r & reg8_src != REG8_A) ? OP_SRC_REG8 :
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_src_o = reg8_src;