Initial
This commit is contained in:
106
cpu_rv32i.srcs/sources_1/new/alu.v
Normal file
106
cpu_rv32i.srcs/sources_1/new/alu.v
Normal file
@@ -0,0 +1,106 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module alu(
|
||||
input [10:0] alu_op ,
|
||||
input [31:0] alu_src1 ,
|
||||
input [31:0] alu_src2 ,
|
||||
output [31:0] alu_result,
|
||||
|
||||
output Carry ,
|
||||
output Sign ,
|
||||
output Overflow ,
|
||||
output Zero
|
||||
);
|
||||
wire op_lui;
|
||||
wire op_add;
|
||||
wire op_sub;
|
||||
wire op_or;
|
||||
wire op_slt;
|
||||
wire op_sltu;
|
||||
wire op_xor;
|
||||
wire op_and;
|
||||
wire op_sll;
|
||||
wire op_srl;
|
||||
wire op_sra;
|
||||
|
||||
assign op_lui = alu_op[ 0];
|
||||
assign op_add = alu_op[ 1];
|
||||
assign op_sub = alu_op[ 2];
|
||||
assign op_slt = alu_op[ 3];
|
||||
assign op_sltu = alu_op[ 4];
|
||||
assign op_xor = alu_op[ 5];
|
||||
assign op_or = alu_op[ 6];
|
||||
assign op_and = alu_op[ 7];
|
||||
assign op_sll = alu_op[ 8];
|
||||
assign op_srl = alu_op[ 9];
|
||||
assign op_sra = alu_op[10];
|
||||
|
||||
|
||||
wire [31:0] lui_result;
|
||||
wire [31:0] add_sub_result;
|
||||
wire [31:0] slt_result;
|
||||
wire [31:0] sltu_result;
|
||||
wire [31:0] xor_result;
|
||||
wire [31:0] or_result;
|
||||
wire [31:0] and_result;
|
||||
wire [31:0] sll_result;
|
||||
wire [31:0] sr64_result;
|
||||
wire [31:0] sr_result;
|
||||
|
||||
// 32-bit adder
|
||||
wire [31:0] adder_a;
|
||||
wire [31:0] adder_b;
|
||||
wire adder_cin;
|
||||
wire [31:0] adder_result;
|
||||
wire adder_cout;
|
||||
|
||||
assign adder_a = alu_src1;
|
||||
assign adder_b = (op_sub | op_slt | op_sltu) ? ~alu_src2 : alu_src2;
|
||||
assign adder_cin = (op_sub | op_slt | op_sltu) ? 1'b1 : 1'b0;
|
||||
assign {adder_cout, adder_result} = adder_a + adder_b + adder_cin;
|
||||
|
||||
// ADD, SUB result
|
||||
assign add_sub_result = adder_result;
|
||||
|
||||
// SLT result
|
||||
assign slt_result[31:1] = 31'b0;
|
||||
assign slt_result[0] = (alu_src1[31] & ~alu_src2[31])
|
||||
| ((alu_src1[31] ~^ alu_src2[31]) & adder_result[31]);
|
||||
|
||||
// SLTU result
|
||||
assign sltu_result[31:1] = 31'b0;
|
||||
assign sltu_result[0] = ~adder_cout;
|
||||
|
||||
// bitwise operation
|
||||
assign or_result = alu_src1 | alu_src2;
|
||||
assign and_result = alu_src1 & alu_src2;
|
||||
assign xor_result = alu_src1 ^ alu_src2;
|
||||
assign lui_result = alu_src2;
|
||||
|
||||
// SLL result
|
||||
assign sll_result = alu_src1 << alu_src2[4:0];
|
||||
|
||||
// SRL, SRA result
|
||||
assign sr64_result = {{32{op_sra & alu_src1[31]}}, alu_src1[31:0]} >> alu_src2[4:0];
|
||||
|
||||
assign sr_result = sr64_result[31:0];
|
||||
|
||||
// final result mux
|
||||
assign alu_result = ({32{op_add|op_sub}} & add_sub_result)
|
||||
| ({32{op_slt }} & slt_result)
|
||||
| ({32{op_sltu }} & sltu_result)
|
||||
| ({32{op_or }} & or_result)
|
||||
| ({32{op_xor }} & xor_result)
|
||||
| ({32{op_and }} & and_result)
|
||||
| ({32{op_lui }} & lui_result)
|
||||
| ({32{op_sll }} & sll_result)
|
||||
| ({32{op_srl|op_sra}} & sr_result);
|
||||
|
||||
assign Carry = op_sub ^ adder_cout;
|
||||
assign Sign = alu_result[31];
|
||||
assign Overflow = (op_add|op_sub) ? ( adder_a[31] & adder_b[31] & adder_cout)
|
||||
| (~adder_a[31] & ~adder_b[31] & ~adder_cout)
|
||||
: 1'b0;
|
||||
assign Zero = (alu_result == 32'b0);
|
||||
|
||||
endmodule
|
||||
22
cpu_rv32i.srcs/sources_1/new/cpu.h
Normal file
22
cpu_rv32i.srcs/sources_1/new/cpu.h
Normal file
@@ -0,0 +1,22 @@
|
||||
`ifndef CPU_H
|
||||
`define CPU_H
|
||||
|
||||
`define BR_BUS_WD 33
|
||||
|
||||
`define DS_TO_FW_BUS_WD 10
|
||||
`define ES_TO_FW_BUS_WD 12
|
||||
`define MS_TO_FW_BUS_WD 6
|
||||
`define FW_TO_ES_BUS_WD 5
|
||||
`define MS_TO_ES_BUS_WD 32
|
||||
`define WS_TO_ES_BUS_WD 32
|
||||
|
||||
`define DS_TO_LU_BUS_WD 10
|
||||
`define ES_TO_LU_BUS_WD 10
|
||||
`define LU_TO_DS_BUS_WD 1
|
||||
|
||||
`define FS_TO_DS_BUS_WD 64
|
||||
`define DS_TO_ES_BUS_WD 178
|
||||
`define ES_TO_MS_BUS_WD 120
|
||||
`define MS_TO_WS_BUS_WD 103
|
||||
`define WS_TO_RF_BUS_WD 38
|
||||
`endif
|
||||
227
cpu_rv32i.srcs/sources_1/new/cpu_top.v
Normal file
227
cpu_rv32i.srcs/sources_1/new/cpu_top.v
Normal file
@@ -0,0 +1,227 @@
|
||||
`timescale 1ns / 1ps
|
||||
`include "cpu.h"
|
||||
|
||||
module cpu_top(
|
||||
input clk,
|
||||
input resetn,
|
||||
// inst ram interface
|
||||
output instr_ram_en,
|
||||
output [ 3:0] instr_ram_wen,
|
||||
output [31:0] instr_ram_addr,
|
||||
output [31:0] instr_ram_wdata,
|
||||
input [31:0] instr_ram_rdata,
|
||||
// data ram interface
|
||||
output data_ram_en,
|
||||
output [ 3:0] data_ram_wen,
|
||||
output [31:0] data_ram_addr,
|
||||
output [31:0] data_ram_wdata,
|
||||
input [31:0] data_ram_rdata,
|
||||
// trace debug interface
|
||||
output [31:0] debug_wb_pc,
|
||||
output [ 3:0] debug_wb_rf_wen,
|
||||
output [ 4:0] debug_wb_rf_wnum,
|
||||
output [31:0] debug_wb_rf_wdata,
|
||||
input [ 4:0] rf_raddr,
|
||||
output [31:0] rf_rdata
|
||||
);
|
||||
|
||||
reg reset;
|
||||
always @(posedge clk) reset <= ~resetn;
|
||||
|
||||
|
||||
wire ds_allowin;
|
||||
wire es_allowin;
|
||||
wire ms_allowin;
|
||||
wire ws_allowin;
|
||||
wire fs_to_ds_valid;
|
||||
wire ds_to_es_valid;
|
||||
wire es_to_ms_valid;
|
||||
wire ms_to_ws_valid;
|
||||
wire [`FS_TO_DS_BUS_WD -1:0] fs_to_ds_bus;
|
||||
wire [`DS_TO_ES_BUS_WD -1:0] ds_to_es_bus;
|
||||
wire [`ES_TO_MS_BUS_WD -1:0] es_to_ms_bus;
|
||||
wire [`MS_TO_WS_BUS_WD -1:0] ms_to_ws_bus;
|
||||
wire [`WS_TO_RF_BUS_WD -1:0] ws_to_rf_bus;
|
||||
|
||||
wire [`BR_BUS_WD -1:0] br_bus;
|
||||
|
||||
wire [`DS_TO_FW_BUS_WD -1:0] ds_to_fw_bus;
|
||||
wire [`ES_TO_FW_BUS_WD -1:0] es_to_fw_bus;
|
||||
wire [`MS_TO_FW_BUS_WD -1:0] ms_to_fw_bus;
|
||||
wire [`FW_TO_ES_BUS_WD -1:0] fw_to_es_bus;
|
||||
wire [`MS_TO_ES_BUS_WD -1:0] ms_to_es_bus;
|
||||
wire [`WS_TO_ES_BUS_WD -1:0] ws_to_es_bus;
|
||||
|
||||
wire [`DS_TO_LU_BUS_WD -1:0] ds_to_lu_bus;
|
||||
wire [`ES_TO_LU_BUS_WD -1:0] es_to_lu_bus;
|
||||
|
||||
wire lu_stall;
|
||||
wire dh_flush;
|
||||
wire dh_stall;
|
||||
|
||||
wire fs_stall;
|
||||
wire fs_flush;
|
||||
wire ds_flush;
|
||||
wire es_flush;
|
||||
wire ms_flush;
|
||||
wire ws_flush;
|
||||
|
||||
// IF stage
|
||||
if_stage if_stage(
|
||||
.clk (clk ),
|
||||
.reset (reset ),
|
||||
.fs_flush (fs_flush ),
|
||||
.fs_stall (fs_stall ),
|
||||
//allowin
|
||||
.ds_allowin (ds_allowin ),
|
||||
//brbus
|
||||
.br_bus (br_bus ),
|
||||
//outputs
|
||||
.fs_to_ds_valid (fs_to_ds_valid ),
|
||||
.fs_to_ds_bus (fs_to_ds_bus ),
|
||||
// inst ram interface
|
||||
.instr_ram_en (instr_ram_en ),
|
||||
.instr_ram_wen (instr_ram_wen ),
|
||||
.instr_ram_addr (instr_ram_addr ),
|
||||
.instr_ram_wdata(instr_ram_wdata),
|
||||
.instr_ram_rdata(instr_ram_rdata)
|
||||
);
|
||||
// ID stage
|
||||
id_stage id_stage(
|
||||
.clk (clk ),
|
||||
.reset (reset ),
|
||||
.ds_flush (ds_flush ),
|
||||
.stall (lu_stall ),
|
||||
//allowin
|
||||
.es_allowin (es_allowin ),
|
||||
.ds_allowin (ds_allowin ),
|
||||
//from fs
|
||||
.fs_to_ds_valid (fs_to_ds_valid ),
|
||||
.fs_to_ds_bus (fs_to_ds_bus ),
|
||||
//to es
|
||||
.ds_to_es_valid (ds_to_es_valid ),
|
||||
.ds_to_es_bus (ds_to_es_bus ),
|
||||
//to fw
|
||||
.ds_to_fw_bus (ds_to_fw_bus ),
|
||||
//to lu
|
||||
.ds_to_lu_bus (ds_to_lu_bus ),
|
||||
//to rf: for write back
|
||||
.ws_to_rf_bus (ws_to_rf_bus ),
|
||||
//to pipctr
|
||||
.dh_flush (dh_flush ),
|
||||
.dh_stall (dh_stall ),
|
||||
|
||||
.rf_raddr (rf_raddr ),
|
||||
.rf_rdata (rf_rdata )
|
||||
|
||||
);
|
||||
// EXE stage
|
||||
exe_stage exe_stage(
|
||||
.clk (clk ),
|
||||
.reset (reset ),
|
||||
.es_flush (es_flush ),
|
||||
//allowin
|
||||
.ms_allowin (ms_allowin ),
|
||||
.es_allowin (es_allowin ),
|
||||
//from ds
|
||||
.ds_to_es_valid (ds_to_es_valid ),
|
||||
.ds_to_es_bus (ds_to_es_bus ),
|
||||
//from ms
|
||||
.ms_to_es_bus (ms_to_es_bus ),
|
||||
//from ws
|
||||
.ws_to_es_bus (ws_to_es_bus ),
|
||||
//from fw
|
||||
.fw_to_es_bus (fw_to_es_bus ),
|
||||
//to lu
|
||||
.es_to_lu_bus (es_to_lu_bus ),
|
||||
//to fw
|
||||
.es_to_fw_bus (es_to_fw_bus ),
|
||||
//to ms
|
||||
.es_to_ms_valid (es_to_ms_valid ),
|
||||
.es_to_ms_bus (es_to_ms_bus ),
|
||||
// data ram interface
|
||||
.data_ram_en (data_ram_en ),
|
||||
.data_ram_wen (data_ram_wen ),
|
||||
.data_ram_addr (data_ram_addr ),
|
||||
.data_ram_wdata (data_ram_wdata )
|
||||
);
|
||||
// MEM stage
|
||||
mem_stage mem_stage(
|
||||
.clk (clk ),
|
||||
.reset (reset ),
|
||||
.ms_flush (ms_flush ),
|
||||
//allowin
|
||||
.ws_allowin (ws_allowin ),
|
||||
.ms_allowin (ms_allowin ),
|
||||
//from es
|
||||
.es_to_ms_valid (es_to_ms_valid ),
|
||||
.es_to_ms_bus (es_to_ms_bus ),
|
||||
//to fs
|
||||
.br_bus (br_bus ),
|
||||
//to es: for forward
|
||||
.ms_to_es_bus (ms_to_es_bus ),
|
||||
//to fw
|
||||
.ms_to_fw_bus (ms_to_fw_bus ),
|
||||
//to ws
|
||||
.ms_to_ws_valid (ms_to_ws_valid ),
|
||||
.ms_to_ws_bus (ms_to_ws_bus ),
|
||||
//from data-ram
|
||||
.data_ram_rdata (data_ram_rdata)
|
||||
);
|
||||
// WB stage
|
||||
wb_stage wb_stage(
|
||||
.clk (clk ),
|
||||
.reset (reset ),
|
||||
.ws_flush (ws_flush ),
|
||||
//allowin
|
||||
.ws_allowin (ws_allowin ),
|
||||
//from ms
|
||||
.ms_to_ws_valid (ms_to_ws_valid ),
|
||||
.ms_to_ws_bus (ms_to_ws_bus ),
|
||||
//to rf: for write back
|
||||
.ws_to_rf_bus (ws_to_rf_bus ),
|
||||
//to es: for forward
|
||||
.ws_to_es_bus (ws_to_es_bus ),
|
||||
//trace debug interface
|
||||
.debug_wb_pc (debug_wb_pc ),
|
||||
.debug_wb_rf_wen (debug_wb_rf_wen ),
|
||||
.debug_wb_rf_wnum (debug_wb_rf_wnum ),
|
||||
.debug_wb_rf_wdata(debug_wb_rf_wdata)
|
||||
);
|
||||
// Forward
|
||||
forward u_forward(
|
||||
.clk (clk ),
|
||||
.ds_to_fw_bus (ds_to_fw_bus),
|
||||
.es_to_fw_bus (es_to_fw_bus),
|
||||
.ms_to_fw_bus (ms_to_fw_bus),
|
||||
|
||||
.fw_to_es_bus (fw_to_es_bus)
|
||||
);
|
||||
// Load Use
|
||||
loaduse u_loaduse(
|
||||
.clk (clk ),
|
||||
.reset (reset ),
|
||||
.ds_to_lu_bus (ds_to_lu_bus),
|
||||
.es_to_lu_bus (es_to_lu_bus),
|
||||
.ds_stall (lu_stall ),
|
||||
.es_flush (lu_flush )
|
||||
);
|
||||
|
||||
piplinectr u_piplinectr(
|
||||
.clk (clk ),
|
||||
.reset (reset ),
|
||||
.lu_flush (lu_flush),
|
||||
.dh_flush (dh_flush),
|
||||
.dh_stall (dh_stall),
|
||||
|
||||
.fs_stall (fs_stall),
|
||||
.fs_flush (fs_flush),
|
||||
.ds_flush (ds_flush),
|
||||
.es_flush (es_flush),
|
||||
.ms_flush (ms_flush),
|
||||
.ws_flush (ws_flush)
|
||||
);
|
||||
|
||||
|
||||
|
||||
endmodule
|
||||
153
cpu_rv32i.srcs/sources_1/new/ctrsignal.v
Normal file
153
cpu_rv32i.srcs/sources_1/new/ctrsignal.v
Normal file
@@ -0,0 +1,153 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module ctrsignal(
|
||||
input [ 6:0] OP,
|
||||
input [ 2:0] func3,
|
||||
input [ 6:0] func7,
|
||||
|
||||
output [ 4:0] ExtOp,
|
||||
output [ 1:0] ALUAsrc,
|
||||
output [ 2:0] ALUBsrc,
|
||||
output [10:0] ALUctr,
|
||||
output RegWr,
|
||||
output MemtoReg,
|
||||
output MemWr,
|
||||
output [ 5:0] Branch,
|
||||
output [ 1:0] Jump,
|
||||
output [ 2:0] Store,
|
||||
output [ 4:0] Load,
|
||||
output shamt
|
||||
);
|
||||
|
||||
wire u_type;
|
||||
wire j_type;
|
||||
wire s_type;
|
||||
wire i_type;
|
||||
wire b_type;
|
||||
wire r_type;
|
||||
|
||||
wire instr_lui ;
|
||||
wire instr_auipc;
|
||||
wire instr_jal ;
|
||||
wire instr_jalr ;
|
||||
wire instr_beq ;
|
||||
wire instr_bne ;
|
||||
wire instr_blt ;
|
||||
wire instr_bge ;
|
||||
wire instr_bltu ;
|
||||
wire instr_bgeu ;
|
||||
wire instr_lb ;
|
||||
wire instr_lh ;
|
||||
wire instr_lw ;
|
||||
wire instr_lbu ;
|
||||
wire instr_lhu ;
|
||||
wire instr_sb ;
|
||||
wire instr_sh ;
|
||||
wire instr_sw ;
|
||||
wire instr_addi ;
|
||||
wire instr_slti ;
|
||||
wire instr_sltiu;
|
||||
wire instr_xori ;
|
||||
wire instr_ori ;
|
||||
wire instr_andi ;
|
||||
wire instr_slli ;
|
||||
wire instr_srli ;
|
||||
wire instr_srai ;
|
||||
wire instr_add ;
|
||||
wire instr_sub ;
|
||||
wire instr_sll ;
|
||||
wire instr_slt ;
|
||||
wire instr_sltu ;
|
||||
wire instr_xor ;
|
||||
wire instr_srl ;
|
||||
wire instr_sra ;
|
||||
wire instr_or ;
|
||||
wire instr_and ;
|
||||
|
||||
assign u_type = (OP == 7'b0110111) || (OP == 7'b0010111);
|
||||
assign j_type = (OP == 7'b1101111);
|
||||
assign s_type = (OP == 7'b0100011);
|
||||
assign i_type = (OP == 7'b1100111) || (OP == 7'b0000011) ||(OP == 7'b0010011);
|
||||
assign b_type = (OP == 7'b1100011);
|
||||
assign r_type = (OP == 7'b0110011);
|
||||
|
||||
assign instr_lui = (OP == 7'b0110111) ;
|
||||
assign instr_auipc = (OP == 7'b0010111) ;
|
||||
assign instr_jal = (OP == 7'b1101111) ;
|
||||
assign instr_jalr = (OP == 7'b1100111) ;
|
||||
assign instr_beq = b_type & (func3 == 3'b000) ;
|
||||
assign instr_bne = b_type & (func3 == 3'b001) ;
|
||||
assign instr_blt = b_type & (func3 == 3'b100) ;
|
||||
assign instr_bge = b_type & (func3 == 3'b101) ;
|
||||
assign instr_bltu = b_type & (func3 == 3'b110) ;
|
||||
assign instr_bgeu = b_type & (func3 == 3'b111) ;
|
||||
assign instr_lb = (OP == 7'b0000011) & (func3 == 3'b000) ;
|
||||
assign instr_lh = (OP == 7'b0000011) & (func3 == 3'b001) ;
|
||||
assign instr_lw = (OP == 7'b0000011) & (func3 == 3'b010) ;
|
||||
assign instr_lbu = (OP == 7'b0000011) & (func3 == 3'b100) ;
|
||||
assign instr_lhu = (OP == 7'b0000011) & (func3 == 3'b101) ;
|
||||
assign instr_sb = s_type & (func3 == 3'b000) ;
|
||||
assign instr_sh = s_type & (func3 == 3'b001) ;
|
||||
assign instr_sw = s_type & (func3 == 3'b010) ;
|
||||
assign instr_addi = (OP == 7'b0010011) & (func3 == 3'b000) ;
|
||||
assign instr_slti = (OP == 7'b0010011) & (func3 == 3'b010) ;
|
||||
assign instr_sltiu = (OP == 7'b0010011) & (func3 == 3'b011) ;
|
||||
assign instr_xori = (OP == 7'b0010011) & (func3 == 3'b100) ;
|
||||
assign instr_ori = (OP == 7'b0010011) & (func3 == 3'b110) ;
|
||||
assign instr_andi = (OP == 7'b0010011) & (func3 == 3'b111) ;
|
||||
assign instr_slli = (OP == 7'b0010011) & (func3 == 3'b001) & (func7 == 7'b0000000);
|
||||
assign instr_srli = (OP == 7'b0010011) & (func3 == 3'b101) & (func7 == 7'b0000000);
|
||||
assign instr_srai = (OP == 7'b0010011) & (func3 == 3'b101) & (func7 == 7'b0100000);
|
||||
assign instr_add = r_type & (func3 == 3'b000) & (func7 == 7'b0000000);
|
||||
assign instr_sub = r_type & (func3 == 3'b000) & (func7 == 7'b0100000);
|
||||
assign instr_sll = r_type & (func3 == 3'b001) & (func7 == 7'b0000000);
|
||||
assign instr_slt = r_type & (func3 == 3'b010) & (func7 == 7'b0000000);
|
||||
assign instr_sltu = r_type & (func3 == 3'b011) & (func7 == 7'b0000000);
|
||||
assign instr_xor = r_type & (func3 == 3'b100) & (func7 == 7'b0000000);
|
||||
assign instr_srl = r_type & (func3 == 3'b101) & (func7 == 7'b0000000);
|
||||
assign instr_sra = r_type & (func3 == 3'b101) & (func7 == 7'b0100000);
|
||||
assign instr_or = r_type & (func3 == 3'b110) & (func7 == 7'b0000000);
|
||||
assign instr_and = r_type & (func3 == 3'b111) & (func7 == 7'b0000000);
|
||||
|
||||
assign ExtOp = {u_type,
|
||||
j_type,
|
||||
s_type,
|
||||
i_type,
|
||||
b_type
|
||||
};
|
||||
|
||||
assign ALUAsrc = { j_type | instr_auipc, // pc
|
||||
~j_type & ~instr_auipc // rs1_value
|
||||
};
|
||||
assign ALUBsrc = { u_type | s_type | i_type, // imm
|
||||
j_type, // 4
|
||||
b_type | r_type // rs2_value
|
||||
};
|
||||
|
||||
assign ALUctr[ 0] = instr_lui ;
|
||||
assign ALUctr[ 1] = instr_lb | instr_lh | instr_lw | instr_lbu
|
||||
| instr_lhu | instr_sb | instr_sh | instr_sw
|
||||
| instr_addi | instr_add | instr_auipc | j_type ;
|
||||
assign ALUctr[ 2] = instr_sub | b_type ;
|
||||
assign ALUctr[ 3] = instr_slt | instr_slti ;
|
||||
assign ALUctr[ 4] = instr_sltu | instr_sltiu ;
|
||||
assign ALUctr[ 5] = instr_xori | instr_xor ;
|
||||
assign ALUctr[ 6] = instr_ori | instr_or ;
|
||||
assign ALUctr[ 7] = instr_and | instr_andi ;
|
||||
assign ALUctr[ 8] = instr_slli | instr_sll ;
|
||||
assign ALUctr[ 9] = instr_srli | instr_srl ;
|
||||
assign ALUctr[10] = instr_srai | instr_sra ;
|
||||
|
||||
|
||||
assign RegWr = ~(instr_sw | instr_sh | instr_sb) & ~b_type;
|
||||
assign MemtoReg = instr_lb | instr_lh | instr_lw | instr_lbu | instr_lhu;
|
||||
assign MemWr = s_type;
|
||||
assign Branch = { instr_bgeu, instr_bltu , instr_bge, instr_blt , instr_bne, instr_beq};
|
||||
assign Jump = { instr_jalr, instr_jal};
|
||||
assign Load = { instr_lhu , instr_lbu , instr_lw , instr_lh , instr_lb};
|
||||
assign Store = { instr_sw , instr_sh , instr_sb};
|
||||
|
||||
assign shamt = instr_slli | instr_srli | instr_srai;
|
||||
|
||||
endmodule
|
||||
|
||||
192
cpu_rv32i.srcs/sources_1/new/exe_stage.v
Normal file
192
cpu_rv32i.srcs/sources_1/new/exe_stage.v
Normal file
@@ -0,0 +1,192 @@
|
||||
`timescale 1ns / 1ps
|
||||
`include "cpu.h"
|
||||
|
||||
module exe_stage(
|
||||
input clk ,
|
||||
input reset ,
|
||||
input es_flush,
|
||||
|
||||
input ms_allowin ,
|
||||
output es_allowin ,
|
||||
|
||||
input ds_to_es_valid,
|
||||
input [`DS_TO_ES_BUS_WD -1:0] ds_to_es_bus ,
|
||||
|
||||
input [`MS_TO_ES_BUS_WD -1:0] ms_to_es_bus ,
|
||||
input [`WS_TO_ES_BUS_WD -1:0] ws_to_es_bus ,
|
||||
input [`FW_TO_ES_BUS_WD -1:0] fw_to_es_bus ,
|
||||
output [`ES_TO_FW_BUS_WD -1:0] es_to_fw_bus ,
|
||||
|
||||
output [`ES_TO_LU_BUS_WD -1:0] es_to_lu_bus ,
|
||||
|
||||
output es_to_ms_valid,
|
||||
output [`ES_TO_MS_BUS_WD -1:0] es_to_ms_bus ,
|
||||
|
||||
output data_ram_en ,
|
||||
output [ 3:0] data_ram_wen ,
|
||||
output [31:0] data_ram_addr ,
|
||||
output [31:0] data_ram_wdata
|
||||
);
|
||||
|
||||
reg es_valid ;
|
||||
wire es_ready_go ;
|
||||
|
||||
reg [`DS_TO_ES_BUS_WD -1:0] ds_to_es_bus_r;
|
||||
|
||||
wire [ 1:0] es_ALUAsrc ;
|
||||
wire [ 2:0] es_ALUBsrc ;
|
||||
wire [10:0] es_ALUctr ;
|
||||
wire [ 5:0] es_Branch ;
|
||||
wire [ 1:0] es_Jump ;
|
||||
wire es_MemtoReg ;
|
||||
wire es_MemWr ;
|
||||
wire es_RegWr ;
|
||||
wire [ 4:0] es_Load ;
|
||||
wire [ 2:0] es_Store ;
|
||||
wire es_shamt ;
|
||||
wire [31:0] es_imm ;
|
||||
wire [31:0] es_rs1_value;
|
||||
wire [31:0] es_rs2_value;
|
||||
wire [ 4:0] es_rd ;
|
||||
wire [ 4:0] es_rs1 ;
|
||||
wire [ 4:0] es_rs2 ;
|
||||
wire [31:0] es_pc ;
|
||||
|
||||
assign { es_ALUctr , //177:167
|
||||
es_shamt , //166:166
|
||||
es_Load , //166:162
|
||||
es_Store , //161:159
|
||||
es_MemWr , //158:158
|
||||
es_Branch , //157:152
|
||||
es_Jump , //151:150
|
||||
es_MemtoReg , //149:149
|
||||
es_RegWr , //148:148
|
||||
es_ALUAsrc , //147:146
|
||||
es_ALUBsrc , //145:143
|
||||
es_rd , //142:138
|
||||
es_rs1 , //137:133
|
||||
es_rs2 , //132:128
|
||||
es_imm , //127:96
|
||||
es_rs1_value , //95 :64
|
||||
es_rs2_value , //63 :32
|
||||
es_pc //31 :0
|
||||
} = ds_to_es_bus_r;
|
||||
|
||||
wire [ 31:0] br_target ;
|
||||
|
||||
wire [31:0] es_alu_src1 ;
|
||||
wire [31:0] es_alu_src2 ;
|
||||
wire [31:0] es_alu_result;
|
||||
wire es_Carry ;
|
||||
wire es_Sign ;
|
||||
wire es_Overflow ;
|
||||
wire es_Zero ;
|
||||
|
||||
assign es_to_ms_bus = { es_Carry , //119:119
|
||||
es_Sign , //118:118
|
||||
es_Overflow , //117:117
|
||||
es_Zero , //116:116
|
||||
br_target , //115:84
|
||||
es_Load , //83 :79
|
||||
es_Branch , //78 :73
|
||||
es_Jump , //72 :71
|
||||
es_MemtoReg , //70 :70
|
||||
es_RegWr , //69 :69
|
||||
es_rd , //68 :64
|
||||
es_alu_result , //63 :32
|
||||
es_pc //31 :0
|
||||
};
|
||||
|
||||
wire [ 1:0] BusAFw;
|
||||
wire [ 1:0] BusBFw;
|
||||
wire DiSrc;
|
||||
|
||||
assign {BusAFw,
|
||||
BusBFw,
|
||||
DiSrc } = fw_to_es_bus;
|
||||
|
||||
wire [31:0] rf_wdata;
|
||||
wire [31:0] ms_alu_result;
|
||||
|
||||
assign rf_wdata = ws_to_es_bus[31:0];
|
||||
assign ms_alu_result = ms_to_es_bus[31:0];
|
||||
assign es_to_fw_bus = {es_rs2, es_rd, es_RegWr, es_MemWr};
|
||||
|
||||
assign es_to_lu_bus = {es_rd, es_Load};
|
||||
|
||||
wire [31:0] es_rs1_forward;
|
||||
wire [31:0] es_rs2_forward;
|
||||
|
||||
assign es_ready_go = 1'b1;
|
||||
assign es_allowin = !es_valid || es_ready_go && ms_allowin;
|
||||
assign es_to_ms_valid = es_valid && es_ready_go;
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
es_valid <= 1'b0;
|
||||
end
|
||||
else if (es_allowin) begin
|
||||
es_valid <= ds_to_es_valid;
|
||||
end
|
||||
|
||||
if (reset || es_flush) begin
|
||||
ds_to_es_bus_r <= 0;
|
||||
end
|
||||
else if (ds_to_es_valid && es_allowin) begin
|
||||
ds_to_es_bus_r <= ds_to_es_bus;
|
||||
end
|
||||
// else begin
|
||||
// ds_to_es_bus_r <= 0;
|
||||
// end
|
||||
end
|
||||
|
||||
assign es_rs1_forward = (BusAFw == 2'b00) ? es_rs1_value :
|
||||
(BusAFw == 2'b01) ? rf_wdata :
|
||||
(BusAFw == 2'b10) ? ms_alu_result :
|
||||
32'b0;
|
||||
assign es_rs2_forward = (BusBFw == 2'b00) ? es_rs2_value :
|
||||
(BusBFw == 2'b01) ? rf_wdata :
|
||||
(BusBFw == 2'b10) ? ms_alu_result :
|
||||
32'b0;
|
||||
|
||||
assign es_alu_src1 = ({32{es_ALUAsrc[1]}} & es_pc)
|
||||
| ({32{es_ALUAsrc[0]}} & es_rs1_forward);
|
||||
assign es_alu_src2 = ({32{es_ALUBsrc[2]}} & (es_shamt ? {27'b0, es_imm[4:0]} : es_imm))
|
||||
| ({32{es_ALUBsrc[1]}} & 32'd4)
|
||||
| ({32{es_ALUBsrc[0]}} & es_rs2_forward);
|
||||
|
||||
alu u_alu(
|
||||
.alu_op (es_ALUctr ),
|
||||
.alu_src1 (es_alu_src1 ),
|
||||
.alu_src2 (es_alu_src2 ),
|
||||
.alu_result (es_alu_result),
|
||||
|
||||
.Carry (es_Carry ),
|
||||
.Sign (es_Sign ),
|
||||
.Overflow (es_Overflow ),
|
||||
.Zero (es_Zero )
|
||||
);
|
||||
|
||||
|
||||
assign data_ram_en = 1'b1;
|
||||
assign data_ram_wen = (es_MemWr && es_valid) ?
|
||||
(({4{es_Store[0]}} &
|
||||
({4{es_alu_result[1:0] == 2'b00}} & 4'b0001)
|
||||
| ({4{es_alu_result[1:0] == 2'b01}} & 4'b0010)
|
||||
| ({4{es_alu_result[1:0] == 2'b10}} & 4'b0100)
|
||||
| ({4{es_alu_result[1:0] == 2'b11}} & 4'b1000))
|
||||
| ({4{es_Store[1]}} &
|
||||
({4{es_alu_result[1:0] == 2'b01}} & 4'b0011 )
|
||||
| ({4{es_alu_result[1:0] == 2'b10}} & 4'b1100 ))
|
||||
| ({4{es_Store[2]}} & 4'b1111 ))
|
||||
: 4'b0000 ;
|
||||
assign data_ram_addr = es_alu_result;
|
||||
assign data_ram_wdata = DiSrc ? rf_wdata :
|
||||
(es_Store[0] ? {4{es_rs2_value[ 7:0]}} :
|
||||
es_Store[1] ? {2{es_rs2_value[15:0]}} :
|
||||
es_Store[2] ? es_rs2_value :
|
||||
32'b0 );
|
||||
|
||||
assign br_target = ({{31{es_Jump[1] }}, 1'b0} & (es_alu_src1 + es_imm))
|
||||
| ( {32{es_Jump[0] | (^es_Branch)}} & (es_pc + es_imm));
|
||||
|
||||
endmodule
|
||||
136
cpu_rv32i.srcs/sources_1/new/hazards.v
Normal file
136
cpu_rv32i.srcs/sources_1/new/hazards.v
Normal file
@@ -0,0 +1,136 @@
|
||||
`timescale 1ns / 1ps
|
||||
`include "cpu.h"
|
||||
|
||||
module forward(
|
||||
input clk,
|
||||
|
||||
input [`DS_TO_FW_BUS_WD - 1:0] ds_to_fw_bus,
|
||||
input [`ES_TO_FW_BUS_WD - 1:0] es_to_fw_bus,
|
||||
input [`MS_TO_FW_BUS_WD - 1:0] ms_to_fw_bus,
|
||||
|
||||
|
||||
output [`FW_TO_ES_BUS_WD - 1:0] fw_to_es_bus
|
||||
);
|
||||
|
||||
wire [4:0] ds_rs1;
|
||||
wire [4:0] ds_rs2;
|
||||
wire [4:0] es_rs2;
|
||||
wire [4:0] es_rd ;
|
||||
wire es_MemWr;
|
||||
wire es_RegWr;
|
||||
wire [4:0] ms_rd ;
|
||||
wire ms_RegWr;
|
||||
|
||||
|
||||
|
||||
wire [1:0] BusAFw;
|
||||
wire [1:0] BusBFw;
|
||||
wire DiSrc;
|
||||
|
||||
reg [`FW_TO_ES_BUS_WD - 1:0] fw_to_es_bus_r;
|
||||
|
||||
|
||||
assign {ds_rs1, ds_rs2} = ds_to_fw_bus;
|
||||
assign {es_rs2, es_rd , es_RegWr, es_MemWr} = es_to_fw_bus;
|
||||
assign {ms_rd , ms_RegWr } = ms_to_fw_bus;
|
||||
|
||||
|
||||
assign BusAFw[0] = ms_RegWr && (ms_rd != 5'b0) && (es_rd != ds_rs1) && (ms_rd == ds_rs1);
|
||||
assign BusAFw[1] = es_RegWr && (es_rd != 5'b0) && (es_rd == ds_rs1) ;
|
||||
assign BusBFw[0] = ms_RegWr && (ms_rd != 5'b0) && (es_rd != ds_rs2) && (ms_rd == ds_rs2);
|
||||
assign BusBFw[1] = es_RegWr && (es_rd != 5'b0) && (es_rd == ds_rs2) ;
|
||||
assign DiSrc = ms_RegWr && (ms_rd != 5'b0) && (ms_rd == es_rs2) && es_MemWr ;
|
||||
|
||||
always @(posedge clk) begin
|
||||
fw_to_es_bus_r <= {BusAFw, BusBFw, DiSrc};
|
||||
end
|
||||
|
||||
assign fw_to_es_bus = fw_to_es_bus_r;
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module loaduse(
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input [`DS_TO_LU_BUS_WD -1:0] ds_to_lu_bus,
|
||||
input [`ES_TO_LU_BUS_WD -1:0] es_to_lu_bus,
|
||||
|
||||
output ds_stall,
|
||||
output es_flush
|
||||
);
|
||||
|
||||
wire [4:0] ds_sr1;
|
||||
wire [4:0] ds_sr2;
|
||||
wire [4:0] es_Load;
|
||||
wire [4:0] es_rd;
|
||||
|
||||
wire stall;
|
||||
|
||||
assign {ds_sr1, ds_sr2 } = ds_to_lu_bus;
|
||||
assign {es_rd , es_Load} = es_to_lu_bus;
|
||||
|
||||
assign stall = ^es_Load &&
|
||||
(((ds_sr1 == es_rd) && (ds_sr1 != 5'b0)) || ((ds_sr2 == es_rd) && (ds_sr2 != 5'b0)));
|
||||
|
||||
assign ds_stall = stall;
|
||||
assign es_flush = stall;
|
||||
endmodule
|
||||
|
||||
|
||||
module piplinectr(
|
||||
input clk,
|
||||
input reset,
|
||||
input lu_flush,
|
||||
input dh_flush,
|
||||
input dh_stall,
|
||||
|
||||
output fs_stall,
|
||||
output fs_flush,
|
||||
output ds_flush,
|
||||
output es_flush,
|
||||
output ms_flush,
|
||||
output ws_flush
|
||||
);
|
||||
|
||||
reg [7:0] flush;
|
||||
reg [1:0] stall;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(reset) begin
|
||||
flush <= 5'b0;
|
||||
end
|
||||
else if(lu_flush) begin
|
||||
flush <= {flush[6] , lu_flush , flush[4:0], 1'b0};
|
||||
end
|
||||
else if(dh_flush) begin
|
||||
flush <= {flush[6:5], {3{dh_flush}}, flush[1:0], 1'b0};
|
||||
end
|
||||
else begin
|
||||
flush <= {flush[6:0] , 1'b0};
|
||||
end
|
||||
|
||||
if(reset) begin
|
||||
stall <= 2'b0;
|
||||
end
|
||||
else if(dh_stall) begin
|
||||
stall <= {stall[0], dh_stall};
|
||||
end
|
||||
else begin
|
||||
stall <= {stall[0], 1'b0};
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
assign {ws_flush,
|
||||
ms_flush,
|
||||
es_flush,
|
||||
ds_flush,
|
||||
fs_flush} = flush[7:3] | {2'b0, lu_flush, 2'b0} | {3'b0, dh_flush, dh_flush};
|
||||
|
||||
assign fs_stall = ^stall | dh_stall;
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
185
cpu_rv32i.srcs/sources_1/new/id_stage.v
Normal file
185
cpu_rv32i.srcs/sources_1/new/id_stage.v
Normal file
@@ -0,0 +1,185 @@
|
||||
`timescale 1ns / 1ps
|
||||
`include "cpu.h"
|
||||
|
||||
module id_stage(
|
||||
input clk,
|
||||
input reset,
|
||||
input ds_flush,
|
||||
|
||||
input es_allowin,
|
||||
output ds_allowin,
|
||||
|
||||
input fs_to_ds_valid,
|
||||
input [`FS_TO_DS_BUS_WD -1:0] fs_to_ds_bus,
|
||||
|
||||
output ds_to_es_valid,
|
||||
output [`DS_TO_ES_BUS_WD -1:0] ds_to_es_bus,
|
||||
|
||||
output [`DS_TO_FW_BUS_WD -1:0] ds_to_fw_bus,
|
||||
|
||||
input stall,
|
||||
output [`DS_TO_LU_BUS_WD -1:0] ds_to_lu_bus,
|
||||
|
||||
input [`WS_TO_RF_BUS_WD -1:0] ws_to_rf_bus,
|
||||
|
||||
output dh_flush,
|
||||
output dh_stall,
|
||||
|
||||
input [ 4 :0] rf_raddr,
|
||||
output [31 :0] rf_rdata
|
||||
);
|
||||
|
||||
reg ds_valid;
|
||||
wire ds_ready_go;
|
||||
|
||||
wire [31 :0] fs_pc;
|
||||
reg [`FS_TO_DS_BUS_WD -1:0] fs_to_ds_bus_r;
|
||||
assign fs_pc = fs_to_ds_bus[31:0];
|
||||
|
||||
wire [31:0] ds_instr;
|
||||
wire [31:0] ds_pc;
|
||||
assign {ds_instr,
|
||||
ds_pc } = fs_to_ds_bus_r;
|
||||
|
||||
wire rf_we;
|
||||
wire [ 4:0] rf_waddr;
|
||||
wire [31:0] rf_wdata;
|
||||
assign {rf_we , //37:37
|
||||
rf_waddr, //36:32
|
||||
rf_wdata //31:0
|
||||
} = ws_to_rf_bus;
|
||||
|
||||
wire [ 4:0] ExtOp;
|
||||
wire [ 1:0] ALUAsrc;
|
||||
wire [ 2:0] ALUBsrc;
|
||||
wire [10:0] ALUctr;
|
||||
wire [ 5:0] Branch;
|
||||
wire [ 1:0] Jump;
|
||||
wire MemtoReg;
|
||||
wire MemWr;
|
||||
wire RegWr;
|
||||
wire [ 4:0] Load;
|
||||
wire [ 2:0] Store;
|
||||
wire shamt;
|
||||
wire [31:0] imm;
|
||||
wire [31:0] rs1_value;
|
||||
wire [31:0] rs2_value;
|
||||
|
||||
wire [ 6:0] op;
|
||||
wire [ 6:0] func7;
|
||||
wire [ 2:0] func3;
|
||||
wire [ 4:0] rs2;
|
||||
wire [ 4:0] rs1;
|
||||
wire [ 4:0] rd;
|
||||
wire [31:0] immI;
|
||||
wire [31:0] immS;
|
||||
wire [31:0] immB;
|
||||
wire [31:0] immU;
|
||||
wire [31:0] immJ;
|
||||
|
||||
wire [ 4:0] rf_raddr1;
|
||||
wire [ 31:0] rf_rdata1;
|
||||
wire [ 4:0] rf_raddr2;
|
||||
wire [ 31:0] rf_rdata2;
|
||||
|
||||
assign ds_to_es_bus= { ALUctr , //177:167
|
||||
shamt , //166:166
|
||||
Load , //166:162
|
||||
Store , //161:159
|
||||
MemWr , //158:158
|
||||
Branch , //157:152
|
||||
Jump , //151:150
|
||||
MemtoReg , //149:149
|
||||
RegWr , //148:148
|
||||
ALUAsrc , //147:146
|
||||
ALUBsrc , //145:143
|
||||
rd , //142:138
|
||||
rs1 , //137:133
|
||||
rs2 , //132:128
|
||||
imm , //127:96
|
||||
rs1_value , //95 :64
|
||||
rs2_value , //63 :32
|
||||
ds_pc //31 :0
|
||||
};
|
||||
|
||||
assign ds_to_fw_bus = {rs1, rs2};
|
||||
|
||||
assign ds_to_lu_bus = {rs1, rs2};
|
||||
|
||||
assign ds_ready_go = !stall;
|
||||
assign ds_allowin = !ds_valid || ds_ready_go && es_allowin;
|
||||
assign ds_to_es_valid = ds_valid && ds_ready_go;
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
ds_valid <= 1'b0;
|
||||
end
|
||||
else if (ds_allowin) begin
|
||||
ds_valid <= fs_to_ds_valid;
|
||||
end
|
||||
|
||||
if (reset || ds_flush) begin
|
||||
fs_to_ds_bus_r <= 0;
|
||||
end
|
||||
else if (fs_to_ds_valid && ds_allowin) begin
|
||||
fs_to_ds_bus_r <= fs_to_ds_bus;
|
||||
end
|
||||
end
|
||||
|
||||
assign op = ds_instr[ 6: 0];
|
||||
assign func7 = ds_instr[31:25];
|
||||
assign func3 = ds_instr[14:12];
|
||||
assign rs2 = ds_instr[24:20];
|
||||
assign rs1 = ds_instr[19:15];
|
||||
assign rd = ds_instr[11: 7];
|
||||
assign immI = {{20{ds_instr[31]}}, ds_instr[31:20]};
|
||||
assign immU = { ds_instr[31:12] , 12'b0};
|
||||
assign immS = {{20{ds_instr[31]}}, ds_instr[31:25], ds_instr[11: 7]};
|
||||
assign immB = {{20{ds_instr[31]}}, ds_instr[7] , ds_instr[30:25], ds_instr[11: 8], 1'b0};
|
||||
assign immJ = {{12{ds_instr[31]}}, ds_instr[19:12], ds_instr[20] , ds_instr[30:21], 1'b0};
|
||||
|
||||
ctrsignal u_ctrsignal(
|
||||
.OP(op),
|
||||
.func3 (func3 ),
|
||||
.func7 (func7 ),
|
||||
|
||||
.ExtOp (ExtOp ),
|
||||
.ALUAsrc (ALUAsrc ),
|
||||
.ALUBsrc (ALUBsrc ),
|
||||
.ALUctr (ALUctr ),
|
||||
.RegWr (RegWr ),
|
||||
.MemtoReg (MemtoReg),
|
||||
.MemWr (MemWr ),
|
||||
.Branch (Branch ),
|
||||
.Jump (Jump ),
|
||||
.Load (Load ),
|
||||
.Store (Store ),
|
||||
.shamt (shamt )
|
||||
);
|
||||
|
||||
assign imm = ({32{ExtOp[4]}} & immU)
|
||||
| ({32{ExtOp[3]}} & immJ)
|
||||
| ({32{ExtOp[2]}} & immS)
|
||||
| ({32{ExtOp[1]}} & immI)
|
||||
| ({32{ExtOp[0]}} & immB);
|
||||
|
||||
assign rf_raddr1 = rs1;
|
||||
assign rf_raddr2 = rs2;
|
||||
regfile u_regfile(
|
||||
.clk (clk ),
|
||||
.reset (reset ),
|
||||
.raddr1 (rf_raddr1),
|
||||
.rdata1 (rf_rdata1),
|
||||
.raddr2 (rf_raddr2),
|
||||
.rdata2 (rf_rdata2),
|
||||
.raddr3 (rf_raddr ),
|
||||
.rdata3 (rf_rdata ),
|
||||
.we (rf_we ),
|
||||
.waddr (rf_waddr ),
|
||||
.wdata (rf_wdata )
|
||||
);
|
||||
assign rs1_value = rf_rdata1;
|
||||
assign rs2_value = rf_rdata2;
|
||||
|
||||
assign dh_flush = ^Jump || ^Branch;
|
||||
assign dh_stall = ^Branch;
|
||||
endmodule
|
||||
73
cpu_rv32i.srcs/sources_1/new/if_stage.v
Normal file
73
cpu_rv32i.srcs/sources_1/new/if_stage.v
Normal file
@@ -0,0 +1,73 @@
|
||||
`timescale 1ns / 1ps
|
||||
`include "cpu.h"
|
||||
|
||||
module if_stage(
|
||||
input clk,
|
||||
input reset,
|
||||
input fs_flush,
|
||||
input fs_stall,
|
||||
|
||||
input ds_allowin,
|
||||
input [`BR_BUS_WD -1:0] br_bus,
|
||||
|
||||
output fs_to_ds_valid,
|
||||
output [`FS_TO_DS_BUS_WD -1:0] fs_to_ds_bus,
|
||||
|
||||
output instr_ram_en,
|
||||
output [ 3:0] instr_ram_wen,
|
||||
output [31:0] instr_ram_addr,
|
||||
output [31:0] instr_ram_wdata,
|
||||
input [31:0] instr_ram_rdata
|
||||
);
|
||||
|
||||
reg fs_valid;
|
||||
wire fs_ready_go;
|
||||
wire fs_allowin;
|
||||
wire to_fs_valid;
|
||||
|
||||
wire [31:0] seq_pc;
|
||||
wire [31:0] nextpc;
|
||||
|
||||
wire br_taken;
|
||||
wire [31:0] br_target;
|
||||
assign {br_taken, br_target} = br_bus;
|
||||
|
||||
|
||||
wire [31:0] fs_instr;
|
||||
reg [31:0] fs_pc;
|
||||
assign fs_to_ds_bus = {fs_instr, fs_pc};
|
||||
|
||||
assign to_fs_valid = ~reset;
|
||||
assign seq_pc = fs_pc + 3'h4;
|
||||
assign nextpc = br_taken ? br_target :
|
||||
fs_stall ? fs_pc :
|
||||
seq_pc;
|
||||
|
||||
// IF stage
|
||||
assign fs_ready_go = !(fs_flush);
|
||||
assign fs_allowin = !fs_valid || fs_ready_go && ds_allowin;
|
||||
assign fs_to_ds_valid = fs_valid && fs_ready_go;
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
fs_valid <= 1'b0;
|
||||
end
|
||||
else if (fs_allowin) begin
|
||||
fs_valid <= to_fs_valid;
|
||||
end
|
||||
|
||||
if (reset || (fs_flush && !fs_stall)) begin
|
||||
fs_pc <= 32'hfffffffc;
|
||||
end
|
||||
else if (to_fs_valid && fs_allowin) begin
|
||||
fs_pc <= nextpc;
|
||||
end
|
||||
end
|
||||
|
||||
assign instr_ram_en = to_fs_valid && fs_allowin;
|
||||
assign instr_ram_wen = 4'h0;
|
||||
assign instr_ram_addr = nextpc;
|
||||
assign instr_ram_wdata = 32'b0;
|
||||
|
||||
|
||||
assign fs_instr = instr_ram_rdata;
|
||||
endmodule
|
||||
125
cpu_rv32i.srcs/sources_1/new/mem_stage.v
Normal file
125
cpu_rv32i.srcs/sources_1/new/mem_stage.v
Normal file
@@ -0,0 +1,125 @@
|
||||
`timescale 1ns / 1ps
|
||||
`include "cpu.h"
|
||||
|
||||
module mem_stage(
|
||||
input clk ,
|
||||
input reset ,
|
||||
input ms_flush,
|
||||
|
||||
input ws_allowin ,
|
||||
output ms_allowin ,
|
||||
|
||||
//from es
|
||||
input es_to_ms_valid,
|
||||
input [`ES_TO_MS_BUS_WD -1:0] es_to_ms_bus ,
|
||||
//to es
|
||||
output [`MS_TO_ES_BUS_WD -1:0] ms_to_es_bus ,
|
||||
//to fw
|
||||
output [`MS_TO_FW_BUS_WD -1:0] ms_to_fw_bus ,
|
||||
//to ws
|
||||
output ms_to_ws_valid,
|
||||
output [`MS_TO_WS_BUS_WD -1:0] ms_to_ws_bus ,
|
||||
|
||||
output [`BR_BUS_WD -1:0] br_bus ,
|
||||
//from data-sram
|
||||
input [31 :0] data_ram_rdata
|
||||
);
|
||||
|
||||
reg ms_valid;
|
||||
wire ms_ready_go;
|
||||
|
||||
reg [`ES_TO_MS_BUS_WD -1:0] es_to_ms_bus_r;
|
||||
wire [ 5:0] ms_Branch ;
|
||||
wire [ 1:0] ms_Jump ;
|
||||
wire ms_MemtoReg ;
|
||||
wire ms_MemWr ;
|
||||
wire ms_RegWr ;
|
||||
wire [ 4:0] ms_Load ;
|
||||
wire [ 4:0] ms_rd ;
|
||||
wire [ 4:0] ms_rs1 ;
|
||||
wire [ 4:0] ms_rs2 ;
|
||||
wire [31:0] ms_alu_result;
|
||||
wire [31:0] ms_pc ;
|
||||
wire [31:0] br_target ;
|
||||
wire ms_Carry ;
|
||||
wire ms_Sign ;
|
||||
wire ms_Overflow ;
|
||||
wire ms_Zero ;
|
||||
|
||||
wire br_taken ;
|
||||
|
||||
assign { ms_Carry , //119:119
|
||||
ms_Sign , //118:118
|
||||
ms_Overflow , //117:117
|
||||
ms_Zero , //116:116
|
||||
br_target , //115:84
|
||||
ms_Load , //83 :79
|
||||
ms_Branch , //78 :73
|
||||
ms_Jump , //72 :71
|
||||
ms_MemtoReg , //70 :70
|
||||
ms_RegWr , //69 :69
|
||||
ms_rd , //68 :64
|
||||
ms_alu_result , //63 :32
|
||||
ms_pc //31 :0
|
||||
} = es_to_ms_bus_r;
|
||||
|
||||
wire [31:0] mem_result;
|
||||
|
||||
assign br_bus = { br_taken, //32:32
|
||||
br_target //31:0
|
||||
};
|
||||
|
||||
assign ms_to_es_bus = { ms_alu_result};
|
||||
assign ms_to_fw_bus = { ms_rd , ms_RegWr};
|
||||
|
||||
assign ms_to_ws_bus = { ms_MemtoReg , //102:102
|
||||
ms_RegWr , //101:101
|
||||
mem_result , //100:69
|
||||
ms_rd , //68 :64
|
||||
ms_alu_result , //63 :32
|
||||
ms_pc //31 :0
|
||||
};
|
||||
|
||||
assign ms_ready_go = 1'b1;
|
||||
assign ms_allowin = !ms_valid || ms_ready_go && ws_allowin;
|
||||
assign ms_to_ws_valid = ms_valid && ms_ready_go;
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
ms_valid <= 1'b0;
|
||||
end
|
||||
else if (ms_allowin) begin
|
||||
ms_valid <= es_to_ms_valid;
|
||||
end
|
||||
|
||||
if (reset || ms_flush) begin
|
||||
es_to_ms_bus_r <= 0;
|
||||
end
|
||||
else if (es_to_ms_valid && ms_allowin) begin
|
||||
es_to_ms_bus_r <= es_to_ms_bus;
|
||||
end
|
||||
// else begin
|
||||
// es_to_ms_bus_r <= 0;
|
||||
// end
|
||||
end
|
||||
|
||||
assign mem_result = (ms_Load[0] || ms_Load[3]) ? ((ms_alu_result[1:0] == 2'b00) ? {{24{ms_Load[3] ? data_ram_rdata[ 7] : 1'b0 }}, data_ram_rdata[ 7:0] }:
|
||||
(ms_alu_result[1:0] == 2'b01) ? {{16{ms_Load[3] ? data_ram_rdata[ 7] : 1'b0 }}, data_ram_rdata[ 7:0], 8'b0}:
|
||||
(ms_alu_result[1:0] == 2'b10) ? {{ 8{ms_Load[3] ? data_ram_rdata[ 7] : 1'b0 }}, data_ram_rdata[ 7:0], 16'b0}:
|
||||
{ data_ram_rdata[ 7:0], 24'b0}
|
||||
) :
|
||||
(ms_Load[1] || ms_Load[4]) ? ((ms_alu_result[1:0] == 2'b00) ? {{16{ms_Load[4] ? data_ram_rdata[15] : 1'b0 }}, data_ram_rdata[15:0] }:
|
||||
{ data_ram_rdata[15:0], 16'b0}
|
||||
) :
|
||||
ms_Load[2] ? ( data_ram_rdata
|
||||
) : 32'b0;
|
||||
|
||||
|
||||
assign br_taken = ( ms_Branch[0] & ms_Zero )
|
||||
| ( ms_Branch[1] & ~ms_Zero )
|
||||
| ( ms_Branch[2] & (ms_Sign != ms_Overflow) )
|
||||
| ( ms_Branch[3] & (ms_Zero | (ms_Sign == ms_Overflow)))
|
||||
| ( ms_Branch[4] & ms_Carry )
|
||||
| ( ms_Branch[5] & (ms_Zero | ~ms_Carry ))
|
||||
| (^ms_Jump );
|
||||
|
||||
endmodule
|
||||
45
cpu_rv32i.srcs/sources_1/new/regfile.v
Normal file
45
cpu_rv32i.srcs/sources_1/new/regfile.v
Normal file
@@ -0,0 +1,45 @@
|
||||
module regfile(
|
||||
input clk,
|
||||
input reset,
|
||||
// READ PORT 1
|
||||
input [ 4:0] raddr1,
|
||||
output [31:0] rdata1,
|
||||
// READ PORT 2
|
||||
input [ 4:0] raddr2,
|
||||
output [31:0] rdata2,
|
||||
// READ PORT 3
|
||||
input [ 4:0] raddr3,
|
||||
output [31:0] rdata3,
|
||||
// WRITE PORT
|
||||
input we, //write enable, HIGH valid
|
||||
input [ 4:0] waddr,
|
||||
input [31:0] wdata
|
||||
);
|
||||
reg [31:0] rf[31:0];
|
||||
integer i = 0;
|
||||
//WRITE
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
for(i = 0; i < 32; i = i + 1) begin
|
||||
rf[i] <= 32'b0;
|
||||
end
|
||||
end
|
||||
else if (we) begin
|
||||
rf[waddr]<= wdata;
|
||||
end
|
||||
end
|
||||
|
||||
//READ OUT 1
|
||||
assign rdata1 = (we & (raddr1 == waddr)) ? wdata :
|
||||
( raddr1 == 5'b0 ) ? 32'b0 :
|
||||
rf[raddr1];
|
||||
|
||||
//READ OUT 2
|
||||
assign rdata2 = (we & (raddr2 == waddr)) ? wdata :
|
||||
( raddr2 == 5'b0 ) ? 32'b0 :
|
||||
rf[raddr2];
|
||||
//READ OUT 3
|
||||
assign rdata3 = (we & (raddr3 == waddr)) ? wdata :
|
||||
( raddr3 == 5'b0 ) ? 32'b0 :
|
||||
rf[raddr3];
|
||||
endmodule
|
||||
95
cpu_rv32i.srcs/sources_1/new/soc_top.v
Normal file
95
cpu_rv32i.srcs/sources_1/new/soc_top.v
Normal file
@@ -0,0 +1,95 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module soc_top(
|
||||
input resetn,
|
||||
input clk,
|
||||
input [ 4:0] switch,
|
||||
output [15:0] led
|
||||
);
|
||||
|
||||
wire cpu_clk;
|
||||
reg cpu_resetn;
|
||||
wire [31:0] led32;
|
||||
assign led = led32[15:0];
|
||||
|
||||
|
||||
|
||||
always @(posedge cpu_clk)
|
||||
begin
|
||||
cpu_resetn <= resetn;
|
||||
end
|
||||
|
||||
pll u_pll(
|
||||
.clk_in1 (clk),
|
||||
.clk_out1 (cpu_clk)
|
||||
);
|
||||
|
||||
|
||||
//cpu instr ram
|
||||
wire cpu_instr_en;
|
||||
wire [ 3:0] cpu_instr_wen;
|
||||
wire [31:0] cpu_instr_addr;
|
||||
wire [31:0] cpu_instr_wdata;
|
||||
wire [31:0] cpu_instr_rdata;
|
||||
//cpu data ram
|
||||
wire cpu_data_en;
|
||||
wire [ 3:0] cpu_data_wen;
|
||||
wire [31:0] cpu_data_addr;
|
||||
wire [31:0] cpu_data_wdata;
|
||||
wire [31:0] cpu_data_rdata;
|
||||
//debug signals
|
||||
wire [31:0] debug_wb_pc;
|
||||
wire [ 3:0] debug_wb_rf_wen;
|
||||
wire [ 4:0] debug_wb_rf_wnum;
|
||||
wire [31:0] debug_wb_rf_wdata;
|
||||
|
||||
cpu_top cpu(
|
||||
.clk (cpu_clk ),
|
||||
.resetn (cpu_resetn),
|
||||
|
||||
.instr_ram_en (cpu_instr_en ),
|
||||
.instr_ram_wen (cpu_instr_wen ),
|
||||
.instr_ram_addr (cpu_instr_addr ),
|
||||
.instr_ram_wdata (cpu_instr_wdata),
|
||||
.instr_ram_rdata (cpu_instr_rdata),
|
||||
|
||||
.data_ram_en (cpu_data_en ),
|
||||
.data_ram_wen (cpu_data_wen ),
|
||||
.data_ram_addr (cpu_data_addr ),
|
||||
.data_ram_wdata (cpu_data_wdata),
|
||||
.data_ram_rdata (cpu_data_rdata),
|
||||
|
||||
//debug
|
||||
.debug_wb_pc (debug_wb_pc ),
|
||||
.debug_wb_rf_wen (debug_wb_rf_wen ),
|
||||
.debug_wb_rf_wnum (debug_wb_rf_wnum ),
|
||||
.debug_wb_rf_wdata(debug_wb_rf_wdata),
|
||||
|
||||
.rf_raddr (switch ),
|
||||
.rf_rdata (led32 )
|
||||
);
|
||||
|
||||
//instr ram
|
||||
instr_ram instr_ram
|
||||
(
|
||||
.clka (cpu_clk ),
|
||||
.ena (cpu_instr_en ),
|
||||
.wea (cpu_instr_wen ), //3:0
|
||||
.addra (cpu_instr_addr[17:2]), //15:0
|
||||
.dina (cpu_instr_wdata ), //31:0
|
||||
.douta (cpu_instr_rdata ) //31:0
|
||||
);
|
||||
|
||||
|
||||
//data ram
|
||||
data_ram data_ram
|
||||
(
|
||||
.clka (cpu_clk ),
|
||||
.ena (cpu_data_en ),
|
||||
.wea (cpu_data_wen ), //3:0
|
||||
.addra (cpu_data_addr[17:2] ), //15:0
|
||||
.dina (cpu_data_wdata ), //31:0
|
||||
.douta (cpu_data_rdata ) //31:0
|
||||
);
|
||||
|
||||
endmodule
|
||||
84
cpu_rv32i.srcs/sources_1/new/wb_stage.v
Normal file
84
cpu_rv32i.srcs/sources_1/new/wb_stage.v
Normal file
@@ -0,0 +1,84 @@
|
||||
`timescale 1ns / 1ps
|
||||
`include "cpu.h"
|
||||
|
||||
module wb_stage(
|
||||
input clk ,
|
||||
input reset ,
|
||||
input ws_flush,
|
||||
|
||||
output ws_allowin ,
|
||||
|
||||
input ms_to_ws_valid,
|
||||
input [`MS_TO_WS_BUS_WD -1:0] ms_to_ws_bus,
|
||||
//to rf: for write back
|
||||
output [`WS_TO_RF_BUS_WD -1:0] ws_to_rf_bus,
|
||||
//to es
|
||||
output [`WS_TO_ES_BUS_WD -1:0] ws_to_es_bus,
|
||||
//trace debug interface
|
||||
output [31:0] debug_wb_pc,
|
||||
output [ 3:0] debug_wb_rf_wen ,
|
||||
output [ 4:0] debug_wb_rf_wnum,
|
||||
output [31:0] debug_wb_rf_wdata
|
||||
);
|
||||
|
||||
reg ws_valid;
|
||||
wire ws_ready_go;
|
||||
|
||||
reg [`MS_TO_WS_BUS_WD -1:0] ms_to_ws_bus_r;
|
||||
wire ws_MemtoReg ;
|
||||
wire ws_RegWr ;
|
||||
wire [31:0] ws_mem_result ;
|
||||
wire [ 4:0] ws_rd ;
|
||||
wire [31:0] ws_alu_result ;
|
||||
wire [31:0] ws_pc ;
|
||||
|
||||
assign { ws_MemtoReg , //102:102
|
||||
ws_RegWr , //101:101
|
||||
ws_mem_result , //100:69
|
||||
ws_rd , //68 :64
|
||||
ws_alu_result , //63 :32
|
||||
ws_pc //31 :0
|
||||
} = ms_to_ws_bus_r;
|
||||
|
||||
wire rf_we;
|
||||
wire [4 :0] rf_waddr;
|
||||
wire [31:0] rf_wdata;
|
||||
assign ws_to_rf_bus = {rf_we , //37:37
|
||||
rf_waddr, //36:32
|
||||
rf_wdata //31:0
|
||||
};
|
||||
|
||||
assign ws_to_es_bus = {rf_wdata};
|
||||
|
||||
assign ws_ready_go = 1'b1;
|
||||
assign ws_allowin = !ws_valid || ws_ready_go;
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
ws_valid <= 1'b0;
|
||||
end
|
||||
else if (ws_allowin) begin
|
||||
ws_valid <= ms_to_ws_valid;
|
||||
end
|
||||
|
||||
if (reset || ws_flush) begin
|
||||
ms_to_ws_bus_r <= 0;
|
||||
end
|
||||
else if (ms_to_ws_valid && ws_allowin) begin
|
||||
ms_to_ws_bus_r <= ms_to_ws_bus;
|
||||
end
|
||||
// else begin
|
||||
// ms_to_ws_bus_r <= 0;
|
||||
// end
|
||||
end
|
||||
|
||||
assign rf_we = ws_RegWr && ws_valid;
|
||||
assign rf_waddr = ws_rd;
|
||||
assign rf_wdata = ws_MemtoReg ? ws_mem_result :
|
||||
ws_alu_result;
|
||||
|
||||
// debug info generate
|
||||
assign debug_wb_pc = ws_pc;
|
||||
assign debug_wb_rf_wen = {4{rf_we}};
|
||||
assign debug_wb_rf_wnum = ws_rd;
|
||||
assign debug_wb_rf_wdata = rf_wdata;
|
||||
endmodule
|
||||
Reference in New Issue
Block a user