Implemented BIT $n, r
First of the CB prefixed opcodes.
This commit is contained in:
parent
8c65e4a669
commit
93912e2089
@ -9,6 +9,7 @@ module alu (
|
|||||||
input logic alu_op_valid_i,
|
input logic alu_op_valid_i,
|
||||||
input alu_op_t alu_op_i,
|
input alu_op_t alu_op_i,
|
||||||
input logic [7:0] operand_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 alu16_op_t alu16_op_i,
|
||||||
input logic [15:0] inx16_i,
|
input logic [15:0] inx16_i,
|
||||||
@ -31,6 +32,9 @@ module alu (
|
|||||||
logic [ 7:0] a_xor;
|
logic [ 7:0] a_xor;
|
||||||
logic [ 7:0] f_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 [16:0] out16_add;
|
||||||
logic [ 7:0] f16_add;
|
logic [ 7:0] f16_add;
|
||||||
logic [15:0] out16_inc;
|
logic [15:0] out16_inc;
|
||||||
@ -41,15 +45,19 @@ module alu (
|
|||||||
|
|
||||||
assign a_we = alu_op_valid_i;
|
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 :
|
||||||
a_xor;
|
a_r;
|
||||||
|
|
||||||
assign f_we = alu_op_valid_i;
|
assign f_we = alu_op_valid_i;
|
||||||
assign f_next = (alu_op_i == ALU_OP_XOR) ? f_xor :
|
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 a_xor = (a_r ^ operand_i);
|
||||||
assign f_xor = {~(|a_xor), 3'b0, f_r[3:0]};
|
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 out16_dec = (inx16_i - 16'h01);
|
||||||
|
|
||||||
assign a_o = a_r;
|
assign a_o = a_r;
|
||||||
|
@ -22,6 +22,7 @@ module control (
|
|||||||
output alu_op_t alu_op_o,
|
output alu_op_t alu_op_o,
|
||||||
output op_src_t op_src_o,
|
output op_src_t op_src_o,
|
||||||
output op_dest_t op_dest_o,
|
output op_dest_t op_dest_o,
|
||||||
|
output reg8_t reg8_src_o,
|
||||||
output alu16_op_t alu16_op_o,
|
output alu16_op_t alu16_op_o,
|
||||||
output reg16_t reg16_src_o,
|
output reg16_t reg16_src_o,
|
||||||
output reg16_t reg16_dest_o,
|
output reg16_t reg16_dest_o,
|
||||||
@ -112,8 +113,9 @@ module control (
|
|||||||
ST1_DEC: state_next = decoder_need_instr1 ? ST2_DEC : ST2_EXEC;
|
ST1_DEC: state_next = decoder_need_instr1 ? ST2_DEC : ST2_EXEC;
|
||||||
ST2_EXEC: state_next = ST0_ADDR;
|
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_DEC: state_next = ST4_EXEC;
|
||||||
|
ST3_EXEC: state_next = ST0_ADDR;
|
||||||
ST4_EXEC: state_next = ST0_ADDR;
|
ST4_EXEC: state_next = ST0_ADDR;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
@ -136,6 +138,8 @@ module control (
|
|||||||
.op_src_o (op_src_o),
|
.op_src_o (op_src_o),
|
||||||
.op_dest_o (op_dest_o),
|
.op_dest_o (op_dest_o),
|
||||||
|
|
||||||
|
.reg8_src_o (reg8_src_o),
|
||||||
|
|
||||||
.alu16_op_o (alu16_op_o),
|
.alu16_op_o (alu16_op_o),
|
||||||
.reg16_src_o (reg16_src_o),
|
.reg16_src_o (reg16_src_o),
|
||||||
.reg16_dest_o (reg16_dest_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_instr1_selected = (state_r == ST2_DEC) ? rdata_i : operand0_r;
|
||||||
assign decoder_instr2_selected = (state_r == ST3_DEC) ? rdata_i : operand1_r;
|
assign decoder_instr2_selected = (state_r == ST3_DEC) ? rdata_i : operand1_r;
|
||||||
|
|
||||||
assign is_undef = (state_r != ST0_ADDR & decoder_is_undef);
|
assign is_undef = instr_valid & decoder_is_undef;
|
||||||
assign instr_valid = (state_r == ST2_EXEC | state_r == ST4_EXEC);
|
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);
|
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 operand8_o = operand0_r;
|
||||||
assign operand16_o = {operand1_r, 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 memory_we_o = instr_valid & decoder_memory_we;
|
||||||
assign adr_src_o = (state_r == ST2_EXEC) | (state_r == ST4_EXEC) ? decoder_adr_src :
|
assign adr_src_o = instr_valid ? decoder_adr_src :
|
||||||
ADR_SRC_PC;
|
ADR_SRC_PC;
|
||||||
|
|
||||||
endmodule : control
|
endmodule : control
|
||||||
|
@ -65,6 +65,7 @@ module cpu (
|
|||||||
.instr_undef_o (instr_undef),
|
.instr_undef_o (instr_undef),
|
||||||
.operand8_o (operand8),
|
.operand8_o (operand8),
|
||||||
.operand16_o (operand16),
|
.operand16_o (operand16),
|
||||||
|
.reg8_src_o (reg8_rselect),
|
||||||
.alu16_op_o (alu16_op),
|
.alu16_op_o (alu16_op),
|
||||||
.reg16_src_o (reg16_rselect),
|
.reg16_src_o (reg16_rselect),
|
||||||
.reg16_dest_o (reg16_wselect),
|
.reg16_dest_o (reg16_wselect),
|
||||||
@ -78,6 +79,7 @@ module cpu (
|
|||||||
.alu_op_valid_i(alu_op_valid),
|
.alu_op_valid_i(alu_op_valid),
|
||||||
.alu_op_i (alu_op),
|
.alu_op_i (alu_op),
|
||||||
.operand_i (alu_operand),
|
.operand_i (alu_operand),
|
||||||
|
.inx8_i (operand8[5:3]), // Used for bit/set/res
|
||||||
.a_o (rega),
|
.a_o (rega),
|
||||||
.f_o (regf),
|
.f_o (regf),
|
||||||
.alu16_op_i (alu16_op),
|
.alu16_op_i (alu16_op),
|
||||||
@ -105,15 +107,16 @@ module cpu (
|
|||||||
.hl_o (hl)
|
.hl_o (hl)
|
||||||
);
|
);
|
||||||
|
|
||||||
assign alu_operand = (op_src == OP_SRC_A) ? rega :
|
assign alu_operand = (op_src == OP_SRC_A) ? rega :
|
||||||
'0;
|
(op_src == OP_SRC_OPERAND8) ? operand8 :
|
||||||
|
(op_src == OP_SRC_REG8) ? reg8_rdata :
|
||||||
|
'0;
|
||||||
|
|
||||||
assign reg8_wselect = reg8_t'('X);
|
assign reg8_wselect = reg8_t'('X);
|
||||||
assign reg8_we = '0;
|
assign reg8_we = '0;
|
||||||
assign reg8_wdata = operand8;
|
assign reg8_wdata = operand8;
|
||||||
assign reg16_we = instr_valid & (op_dest == OP_DEST_REG16);
|
assign reg16_we = instr_valid & (op_dest == OP_DEST_REG16);
|
||||||
assign reg16_wdata = (op_src == OP_SRC_OPERAND16) ? operand16 : alu_out16;
|
assign reg16_wdata = (op_src == OP_SRC_OPERAND16) ? operand16 : alu_out16;
|
||||||
assign reg8_rselect = reg8_t'('X);
|
|
||||||
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 :
|
||||||
|
@ -10,6 +10,7 @@ package cpu_pkg;
|
|||||||
ST2_EXEC,
|
ST2_EXEC,
|
||||||
ST2_DEC,
|
ST2_DEC,
|
||||||
ST3_DEC,
|
ST3_DEC,
|
||||||
|
ST3_EXEC,
|
||||||
ST4_EXEC
|
ST4_EXEC
|
||||||
} state_t;
|
} state_t;
|
||||||
|
|
||||||
@ -19,7 +20,9 @@ package cpu_pkg;
|
|||||||
REG8_D = 3'h02,
|
REG8_D = 3'h02,
|
||||||
REG8_E = 3'h03,
|
REG8_E = 3'h03,
|
||||||
REG8_H = 3'h04,
|
REG8_H = 3'h04,
|
||||||
REG8_L = 3'h05
|
REG8_L = 3'h05,
|
||||||
|
REG8_PHL = 3'h06,
|
||||||
|
REG8_A = 3'h07
|
||||||
} reg8_t;
|
} reg8_t;
|
||||||
|
|
||||||
typedef enum logic [1:0] {
|
typedef enum logic [1:0] {
|
||||||
@ -29,15 +32,16 @@ package cpu_pkg;
|
|||||||
REG16_SP_AF = 2'h03
|
REG16_SP_AF = 2'h03
|
||||||
} reg16_t;
|
} reg16_t;
|
||||||
|
|
||||||
typedef enum logic [2:0] {
|
typedef enum logic [3:0] {
|
||||||
ALU_OP_ADD = 3'h00,
|
ALU_OP_ADD = 4'h00,
|
||||||
ALU_OP_ADC = 3'h01,
|
ALU_OP_ADC = 4'h01,
|
||||||
ALU_OP_SUB = 3'h02,
|
ALU_OP_SUB = 4'h02,
|
||||||
ALU_OP_SBC = 3'h03,
|
ALU_OP_SBC = 4'h03,
|
||||||
ALU_OP_AND = 3'h04,
|
ALU_OP_AND = 4'h04,
|
||||||
ALU_OP_XOR = 3'h05,
|
ALU_OP_XOR = 4'h05,
|
||||||
ALU_OP_OR = 3'h06,
|
ALU_OP_OR = 4'h06,
|
||||||
ALU_OP_CP = 3'h07
|
ALU_OP_CP = 4'h07,
|
||||||
|
ALU_OP_BIT = 4'h08
|
||||||
} alu_op_t;
|
} alu_op_t;
|
||||||
|
|
||||||
typedef enum logic [1:0] {
|
typedef enum logic [1:0] {
|
||||||
@ -49,12 +53,13 @@ package cpu_pkg;
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
OP_SRC_A,
|
OP_SRC_A,
|
||||||
OP_SRC_REG8,
|
OP_SRC_REG8,
|
||||||
|
OP_SRC_OPERAND8,
|
||||||
OP_SRC_OPERAND16,
|
OP_SRC_OPERAND16,
|
||||||
OP_SRC_REG16
|
OP_SRC_REG16
|
||||||
} op_src_t;
|
} op_src_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
OP_DEST_A,
|
OP_DEST_REG8,
|
||||||
OP_DEST_REG16
|
OP_DEST_REG16
|
||||||
} op_dest_t;
|
} op_dest_t;
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ module decode (
|
|||||||
output op_src_t op_src_o,
|
output op_src_t op_src_o,
|
||||||
output op_dest_t op_dest_o,
|
output op_dest_t op_dest_o,
|
||||||
|
|
||||||
|
output reg8_t reg8_src_o,
|
||||||
output alu16_op_t alu16_op_o,
|
output alu16_op_t alu16_op_o,
|
||||||
output reg16_t reg16_dest_o,
|
output reg16_t reg16_dest_o,
|
||||||
output reg16_t reg16_src_o,
|
output reg16_t reg16_src_o,
|
||||||
@ -35,10 +36,12 @@ module decode (
|
|||||||
logic [1:0] dec_p;
|
logic [1:0] dec_p;
|
||||||
logic dec_q;
|
logic dec_q;
|
||||||
|
|
||||||
|
logic is_cb;
|
||||||
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;
|
||||||
logic is_alu_a_r;
|
logic is_alu_a_r;
|
||||||
|
logic is_bit_n_r;
|
||||||
|
|
||||||
reg8_t reg8_src;
|
reg8_t reg8_src;
|
||||||
|
|
||||||
@ -48,21 +51,30 @@ module decode (
|
|||||||
assign dec_p = instr0_i[5:4];
|
assign dec_p = instr0_i[5:4];
|
||||||
assign dec_q = instr0_i[3];
|
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_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_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 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 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 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 | is_bit_n_r;
|
||||||
assign alu_op_valid_o = is_alu_a_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 :
|
assign op_dest_o = is_ld_rr_nnnn ? OP_DEST_REG16 :
|
||||||
is_ldd_hl_a ? 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_alu_a_r & reg8_src != REG8_A) ? OP_SRC_REG8 :
|
||||||
is_ld_rr_nnnn ? OP_SRC_OPERAND16 :
|
is_ld_rr_nnnn ? OP_SRC_OPERAND16 :
|
||||||
is_ldd_hl_a ? OP_SRC_REG16 :
|
is_ldd_hl_a ? OP_SRC_REG16 :
|
||||||
|
is_bit_n_r ? OP_SRC_REG8 :
|
||||||
op_src_t'('X);
|
op_src_t'('X);
|
||||||
|
|
||||||
assign reg8_src_o = reg8_src;
|
assign reg8_src_o = reg8_src;
|
||||||
|
Loading…
Reference in New Issue
Block a user