Implemented SP, $nnnn and XOR A instructions
This commit is contained in:
parent
aa92344d10
commit
237a5f1489
@ -1,8 +1,9 @@
|
||||
TB = tb_top
|
||||
SOURCES = gb.sv cpu.sv registers.sv control.sv decode.sv rom.sv tb_top.sv clkgen.sv
|
||||
SOURCES = gb.sv cpu.sv alu.sv registers.sv control.sv decode.sv rom.sv tb_top.sv clkgen.sv
|
||||
PATH_SRC = ../rtl:../rtl/cpu:../rtl/shared:../sim/tbench:../sim/shared
|
||||
|
||||
gb.sdb: cpu.sdb rom.sdb
|
||||
cpu.sdb: control.sdb fetch.sdb registers.sdb
|
||||
cpu.sdb: control.sdb registers.sdb alu.sdb
|
||||
control.sdb: decode.sdb
|
||||
|
||||
include ../synthflow/vivado/Makefile.rules
|
54
rtl/cpu/alu.sv
Normal file
54
rtl/cpu/alu.sv
Normal file
@ -0,0 +1,54 @@
|
||||
`include "cpu_pkg.svh"
|
||||
|
||||
import cpu_pkg::*;
|
||||
|
||||
module alu (
|
||||
input logic clk_i,
|
||||
input logic nreset_i,
|
||||
|
||||
input logic alu_op_valid_i,
|
||||
input alu_op_t alu_op_i,
|
||||
input logic [7:0] operand_i,
|
||||
|
||||
output logic [ 7:0] a_o,
|
||||
output logic [ 7:0] f_o
|
||||
);
|
||||
|
||||
logic a_we;
|
||||
logic [ 7:0] a_r;
|
||||
logic [ 7:0] a_next;
|
||||
|
||||
logic f_we;
|
||||
logic [ 7:0] f_r;
|
||||
logic [ 7:0] f_next;
|
||||
|
||||
logic [ 7:0] a_xor;
|
||||
logic [ 7:0] f_xor;
|
||||
|
||||
`define DEF_FF(register, next, we, rst_value) \
|
||||
always_ff @(posedge clk_i or negedge nreset_i) begin \
|
||||
if (~nreset_i) begin \
|
||||
register <= (rst_value); \
|
||||
end else if ((we)) begin \
|
||||
register <= (next); \
|
||||
end \
|
||||
end
|
||||
|
||||
`DEF_FF(a_r, a_next, a_we, '0);
|
||||
`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 :
|
||||
a_xor;
|
||||
|
||||
assign f_we = alu_op_valid_i;
|
||||
assign f_next = (alu_op_i == ALU_OP_XOR) ? f_xor :
|
||||
f_xor;
|
||||
|
||||
assign a_xor = (a_r ^ operand_i);
|
||||
assign f_xor = {~(|a_xor), 3'b0, f_r[3:0]};
|
||||
|
||||
assign a_o = a_r;
|
||||
assign f_o = f_r;
|
||||
|
||||
endmodule : alu
|
@ -11,11 +11,17 @@ module control (
|
||||
output state_t state_o,
|
||||
|
||||
output logic [15:0] pc_o,
|
||||
output logic [15:0] sp_o,
|
||||
|
||||
output logic instr_valid_o,
|
||||
output logic instr_undef_o,
|
||||
output logic [ 7:0] operand8_o,
|
||||
output logic [15:0] operand16_o
|
||||
output logic [15:0] operand16_o,
|
||||
|
||||
output logic alu_op_valid_o,
|
||||
output alu_op_t alu_op_o,
|
||||
output op_src_t op_src_o,
|
||||
output op_dest_t op_dest_o
|
||||
);
|
||||
|
||||
logic nreset_r;
|
||||
@ -29,6 +35,10 @@ module control (
|
||||
logic [15:0] pc_next;
|
||||
|
||||
|
||||
logic sp_we;
|
||||
logic [15:0] sp_r;
|
||||
logic [15:0] sp_next;
|
||||
|
||||
logic instr_pc_we;
|
||||
logic [15:0] instr_pc_r;
|
||||
logic [15:0] instr_pc_next;
|
||||
@ -56,6 +66,8 @@ module control (
|
||||
logic pc_incr;
|
||||
logic instr_valid;
|
||||
|
||||
sp_src_t sp_src;
|
||||
|
||||
`define DEF_FF(register, next, we, rst_value) \
|
||||
always_ff @(posedge clk_i or negedge nreset_i) begin \
|
||||
if (~nreset_i) begin \
|
||||
@ -71,6 +83,7 @@ module control (
|
||||
|
||||
`DEF_FF(state_r, state_next, state_we, ST0_ADDR);
|
||||
`DEF_FF(pc_r, pc_next, pc_we, '0);
|
||||
`DEF_FF(sp_r, sp_next, sp_we, '0);
|
||||
`DEF_FF(instr_pc_r, instr_pc_next, instr_pc_we, '0);
|
||||
`DEF_FF(instr_r, instr_next, instr_we, '0);
|
||||
`DEF_FF(operand0_r, operand0_next, operand0_we, '0);
|
||||
@ -79,6 +92,8 @@ module control (
|
||||
assign pc_we = nreset_r & pc_incr & ~is_undef;
|
||||
assign pc_next = (pc_r + 16'b1);
|
||||
|
||||
assign sp_next = (sp_src == SP_SRC_OPERAND16) ? {operand1_r, operand0_r} : '0;
|
||||
|
||||
assign instr_we = (state_r == ST1_DEC);
|
||||
assign instr_next = rdata_i;
|
||||
|
||||
@ -108,9 +123,21 @@ module control (
|
||||
.instr0_i (decoder_instr0_selected),
|
||||
.instr1_i (decoder_instr1_selected),
|
||||
.instr2_i (decoder_instr2_selected),
|
||||
.state_i (state_r),
|
||||
|
||||
.need_instr1_o(decoder_need_instr1),
|
||||
.need_instr2_o(decoder_need_instr2),
|
||||
.undef_o (decoder_is_undef)
|
||||
.undef_o (decoder_is_undef),
|
||||
|
||||
.sp_we_o (sp_we),
|
||||
.sp_src_o (sp_src),
|
||||
|
||||
.alu_op_valid_o(alu_op_valid_o),
|
||||
.alu_op_o (alu_op_o),
|
||||
.op_src_o (op_src_o),
|
||||
.op_dest_o (op_dest_o)
|
||||
|
||||
|
||||
);
|
||||
|
||||
assign decoder_instr0_selected = (state_r == ST1_DEC) ? rdata_i : instr_r;
|
||||
@ -124,6 +151,7 @@ module control (
|
||||
|
||||
assign state_o = state_r;
|
||||
assign pc_o = pc_r;
|
||||
assign sp_o = sp_r;
|
||||
|
||||
assign instr_valid_o = instr_valid;
|
||||
assign instr_undef_o = is_undef;
|
||||
|
@ -10,16 +10,42 @@ module cpu (
|
||||
input logic [ 7:0] rdata_i
|
||||
);
|
||||
|
||||
state_t state;
|
||||
state_t state;
|
||||
|
||||
logic alu_op_valid;
|
||||
alu_op_t alu_op;
|
||||
op_src_t op_src;
|
||||
op_dest_t op_dest;
|
||||
|
||||
logic [ 7:0] alu_operand;
|
||||
|
||||
logic [ 7:0] rega;
|
||||
logic [ 7:0] regf;
|
||||
|
||||
logic [15:0] pc;
|
||||
logic [15:0] sp;
|
||||
|
||||
control control_inst (
|
||||
.clk_i (clk_i),
|
||||
.nreset_i(nreset_i),
|
||||
.rdata_i (rdata_i),
|
||||
.state_o (state),
|
||||
.pc_o (pc)
|
||||
.clk_i (clk_i),
|
||||
.nreset_i (nreset_i),
|
||||
.rdata_i (rdata_i),
|
||||
.state_o (state),
|
||||
.pc_o (pc),
|
||||
.sp_o (sp),
|
||||
.alu_op_valid_o(alu_op_valid),
|
||||
.alu_op_o (alu_op),
|
||||
.op_src_o (op_src),
|
||||
.op_dest_o (op_dest)
|
||||
);
|
||||
|
||||
alu alu_inst (
|
||||
.clk_i (clk_i),
|
||||
.nreset_i (nreset_i),
|
||||
.alu_op_valid_i(alu_op_valid),
|
||||
.alu_op_i (alu_op),
|
||||
.operand_i (alu_operand),
|
||||
.a_o (rega),
|
||||
.f_o (regf)
|
||||
);
|
||||
|
||||
registers registers_inst (
|
||||
@ -27,6 +53,9 @@ module cpu (
|
||||
.nreset_i(nreset_i)
|
||||
);
|
||||
|
||||
assign alu_operand = (op_src == OP_SRC_A) ? rega :
|
||||
'0;
|
||||
|
||||
assign address_o = pc;
|
||||
|
||||
endmodule : cpu
|
||||
|
@ -1,13 +1,49 @@
|
||||
package cpu_pkg;
|
||||
|
||||
//
|
||||
// 4 | ST0_ADDR -> ST1_DEC -> ST2_EXEC -> ST3_NOP
|
||||
// 12 | '-> ST2_DEC -> ST3_DEC -> ST4_EXEC -> .... -> ST11_NOP
|
||||
//
|
||||
typedef enum {
|
||||
ST0_ADDR,
|
||||
ST1_DEC,
|
||||
ST2_EXEC,
|
||||
ST2_DEC,
|
||||
ST3_INC_ADDR,
|
||||
ST3_DEC,
|
||||
ST4_EXEC
|
||||
} state_t;
|
||||
|
||||
typedef enum logic [2:0] {
|
||||
REG8_B = 3'h00,
|
||||
REG8_C = 3'h01,
|
||||
REG8_D = 3'h02,
|
||||
REG8_E = 3'h03,
|
||||
REG8_H = 3'h04,
|
||||
REG8_L = 3'h05
|
||||
} reg8_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
|
||||
} alu_op_t;
|
||||
|
||||
typedef enum {
|
||||
OP_SRC_A,
|
||||
OP_SRC_REG8
|
||||
} op_src_t;
|
||||
|
||||
typedef enum {
|
||||
OP_DEST_A
|
||||
} op_dest_t;
|
||||
|
||||
typedef enum {
|
||||
SP_SRC_OPERAND16
|
||||
} sp_src_t;
|
||||
|
||||
endpackage
|
||||
|
@ -1,21 +1,58 @@
|
||||
module decode (
|
||||
input [7:0] instr0_i,
|
||||
input [7:0] instr1_i,
|
||||
input [7:0] instr2_i,
|
||||
`include "cpu_pkg.svh"
|
||||
|
||||
output logic need_instr1_o,
|
||||
output logic need_instr2_o,
|
||||
output logic undef_o
|
||||
import cpu_pkg::*;
|
||||
|
||||
module decode (
|
||||
input logic [7:0] instr0_i,
|
||||
input logic [7:0] instr1_i,
|
||||
input logic [7:0] instr2_i,
|
||||
|
||||
input state_t state_i,
|
||||
|
||||
output logic need_instr1_o,
|
||||
output logic need_instr2_o,
|
||||
output logic undef_o,
|
||||
|
||||
output logic sp_we_o,
|
||||
output sp_src_t sp_src_o,
|
||||
|
||||
output logic alu_op_valid_o,
|
||||
output alu_op_t alu_op_o,
|
||||
output op_src_t op_src_o,
|
||||
output op_dest_t op_dest_o
|
||||
);
|
||||
|
||||
logic [1:0] dec_x;
|
||||
logic [2:0] dec_y;
|
||||
logic [2:0] dec_z;
|
||||
logic [1:0] dec_p;
|
||||
logic dec_q;
|
||||
|
||||
logic is_ld_rr_nnnn;
|
||||
logic is_ld_sp_nnnn;
|
||||
logic is_alu_a_n;
|
||||
|
||||
assign dec_x = instr0_i[7:6];
|
||||
assign dec_y = instr0_i[5:3];
|
||||
assign dec_z = instr0_i[2:0];
|
||||
assign dec_p = instr0_i[5:4];
|
||||
assign dec_q = instr0_i[3];
|
||||
|
||||
assign is_ld_sp_nnnn = (instr0_i == 7'h31);
|
||||
assign is_ld_rr_nnnn = (dec_z == 3'h1) & ~dec_q & (dec_p != 2'h3);
|
||||
assign is_ld_sp_nnnn = (dec_z == 3'h1) & ~dec_q & (dec_p == 2'h3);
|
||||
|
||||
assign is_alu_a_n = (dec_x == 3'h2);
|
||||
|
||||
assign need_instr1_o = is_ld_sp_nnnn;
|
||||
assign need_instr2_o = is_ld_sp_nnnn;
|
||||
|
||||
assign undef_o = ~is_ld_sp_nnnn;
|
||||
assign undef_o = ~(is_ld_sp_nnnn | is_alu_a_n);
|
||||
|
||||
assign sp_we_o = is_ld_sp_nnnn & (state_i == ST4_EXEC);
|
||||
|
||||
assign alu_op_valid_o = is_alu_a_n;
|
||||
assign alu_op_o = alu_op_t'(dec_y);
|
||||
assign op_dest_o = is_alu_a_n ? OP_DEST_A : op_dest_t'('X);
|
||||
assign op_src_o = is_alu_a_n ? OP_SRC_REG8 : op_src_t'('X);
|
||||
|
||||
endmodule : decode
|
Loading…
Reference in New Issue
Block a user