module alu(
input wire [11:0] alu_op,
input wire [31:0] alu_src1,
input wire [31:0] alu_src2,
output wire [31:0] alu_result
);
wire op_add; //add operation
wire op_sub; //sub operation
wire op_slt; //signed compared and set less than
wire op_sltu; //unsigned compared and set less than
wire op_and; //bitwise and
wire op_nor; //bitwise nor
wire op_or; //bitwise or
wire op_xor; //bitwise xor
wire op_sll; //logic left shift
wire op_srl; //logic right shift
wire op_sra; //arithmetic right shift
wire op_lui; //Load Upper Immediate
// control code decomposition
assign op_add = alu_op[ 0];
assign op_sub = alu_op[ 1];
assign op_slt = alu_op[ 2];
assign op_sltu = alu_op[ 3];
assign op_and = alu_op[ 4];
assign op_nor = alu_op[ 5];
assign op_or = alu_op[ 6];
assign op_xor = alu_op[ 7];
assign op_sll = alu_op[ 8];
assign op_srl = alu_op[ 9];
assign op_sra = alu_op[10];
assign op_lui = alu_op[11];
wire [31:0] add_sub_result;
wire [31:0] slt_result;
wire [31:0] sltu_result;
wire [31:0] and_result;
wire [31:0] nor_result;
wire [31:0] or_result;
wire [31:0] xor_result;
wire [31:0] lui_result;
wire [31:0] sll_result;
wire [63: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; //src1 - src2 rj-rk
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; //rj < rk 1
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 and_result = alu_src1 & alu_src2;
assign or_result = alu_src1 | alu_src2;
assign nor_result = ~or_result;
assign xor_result = alu_src1 ^ alu_src2;
assign lui_result = alu_src2;
// SLL result
assign sll_result = alu_src1 << alu_src2[4:0]; //rj << ui5
// SRL, SRA result
assign sr64_result = {{32{op_sra & alu_src1[31]}}, alu_src1[31:0]} >> alu_src2[4:0]; //rj >> i5
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_and }} & and_result)
| ({32{op_nor }} & nor_result)
| ({32{op_or }} & or_result)
| ({32{op_xor }} & xor_result)
| ({32{op_lui }} & lui_result)
| ({32{op_sll }} & sll_result)
| ({32{op_srl|op_sra}} & sr_result);
endmodule
############################################################
`include "mycpu.h"
module exe_stage(
input clk ,
input reset ,
//allowin
input ms_allowin ,
output es_allowin ,
//from ds
input ds_to_es_valid,
input [`DS_TO_ES_BUS_WD -1:0] ds_to_es_bus ,
//to ms
output es_to_ms_valid,
output [`ES_TO_MS_BUS_WD -1:0] es_to_ms_bus ,
// data sram interface(write)
output data_sram_en ,
output [ 3:0] data_sram_we ,
output [31:0] data_sram_addr ,
output [31:0] data_sram_wdata,
output [ 4:0] es_to_ds_dest ,
output es_to_ds_load_op
);
reg es_valid ;
wire es_ready_go ;
reg [`DS_TO_ES_BUS_WD -1:0] ds_to_es_bus_r;
wire [11:0] alu_op ;
wire es_load_op;
wire src1_is_pc;
wire src2_is_imm;
wire src2_is_4;
wire res_from_mem;
wire dst_is_r1;
wire gr_we;
wire es_mem_we;
wire [4: 0] dest;
wire [31:0] rj_value;
wire [31:0] rkd_value;
wire [31:0] imm;
wire [31:0] es_pc;
assign {alu_op,
es_load_op,
src1_is_pc,
src2_is_imm,
src2_is_4,
gr_we,
es_mem_we,
dest,
imm,
rj_value,
rkd_value,
es_pc,
res_from_mem
} = ds_to_es_bus_r;
wire [31:0] alu_src1 ;
wire [31:0] alu_src2 ;
wire [31:0] alu_result ;
// did't use in lab7
wire es_res_from_mem;
assign es_res_from_mem = es_load_op;
assign es_to_ms_bus = {res_from_mem, //70:70 1
gr_we , //69:69 1
dest , //68:64 5
alu_result , //63:32 32
es_pc //31:0 32
};
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 (ds_to_es_valid && es_allowin) begin
ds_to_es_bus_r <= ds_to_es_bus;
end
end
assign alu_src1 = src1_is_pc ? es_pc : rj_value;
assign alu_src2 = src2_is_imm ? imm : rkd_value;
alu u_alu(
.alu_op (alu_op ),
.alu_src1 (alu_src1 ),
.alu_src2 (alu_src2 ),
.alu_result (alu_result)
);
assign data_sram_en = 1'b1;
assign data_sram_we = es_mem_we && es_valid ? 4'hf : 4'h0;
assign data_sram_addr = alu_result;
assign data_sram_wdata = rkd_value;
assign es_to_ds_dest = dest & {5{es_valid}};
endmodule
#############################################################
`include "mycpu.h"
module id_stage(
input clk ,
input reset ,
//allowin
input es_allowin ,
output ds_allowin ,
//from fs
input fs_to_ds_valid,
input [`FS_TO_DS_BUS_WD -1:0] fs_to_ds_bus ,
//to es
output ds_to_es_valid,
output [`DS_TO_ES_BUS_WD -1:0] ds_to_es_bus ,
//to fs
output [`BR_BUS_WD -1:0] br_bus ,
//to rf: for write back
input [`WS_TO_RF_BUS_WD -1:0] ws_to_rf_bus ,
input [4 :0] es_to_ds_dest ,
input [4 :0] ms_to_ds_dest ,
input [4 :0] ws_to_ds_dest ,
input es_to_ds_load_op
);
wire br_taken;
wire [31:0] br_target;
wire [31:0] ds_pc;
wire [31:0] ds_inst;
reg ds_valid ;
wire ds_ready_go;
wire [11:0] alu_op;
wire load_op;
wire src1_is_pc;
wire src2_is_imm;
wire res_from_mem;
wire dst_is_r1;
wire gr_we;
wire mem_we;
wire src_reg_is_rd;
wire [4: 0] dest;
wire [31:0] rj_value;
wire [31:0] rkd_value;
wire [31:0] imm;
wire [31:0] br_offs;
wire [31:0] jirl_offs;
wire [ 5:0] op_31_26;
wire [ 3:0] op_25_22;
wire [ 1:0] op_21_20;
wire [ 4:0] op_19_15;
wire [ 4:0] rd;
wire [ 4:0] rj;
wire [ 4:0] rk;
wire [11:0] i12;
wire [19:0] i20;
wire [15:0] i16;
wire [25:0] i26;
wire [63:0] op_31_26_d;
wire [15:0] op_25_22_d;
wire [ 3:0] op_21_20_d;
wire [31:0] op_19_15_d;
wire inst_add_w;
wire inst_sub_w;
wire inst_slt;
wire inst_sltu;
wire inst_nor;
wire inst_and;
wire inst_or;
wire inst_xor;
wire inst_slli_w;
wire inst_srli_w;
wire inst_srai_w;
wire inst_addi_w;
wire inst_ld_w;
wire inst_st_w;
wire inst_jirl;
wire inst_b;
wire inst_bl;
wire inst_beq;
wire inst_bne;
wire inst_lu12i_w;
wire need_ui5;
wire need_si12;
wire need_si16;
wire need_si20;
wire need_si26;
wire src2_is_4;
wire [ 4:0] rf_raddr1;
wire [31:0] rf_rdata1;
wire [ 4:0] rf_raddr2;
wire [31:0] rf_rdata2;
wire rf_we ;
wire [ 4:0] rf_waddr;
wire [31:0] rf_wdata;
wire [31:0] alu_src1 ;
wire [31:0] alu_src2 ;
wire [31:0] alu_result ;
wire [31:0] mem_result;
wire [31:0] final_result;
wire inst_no_dest;
wire src_no_rj;
wire src_no_rk;
wire src_no_rd;
wire rj_wait;
wire rk_wait;
wire rd_wait;
wire no_wait;
wire br_stall;
wire load_stall;
assign op_31_26 = ds_inst[31:26];
assign op_25_22 = ds_inst[25:22];
assign op_21_20 = ds_inst[21:20];
assign op_19_15 = ds_inst[19:15];
assign rd = ds_inst[ 4: 0];
assign rj = ds_inst[ 9: 5];
assign rk = ds_inst[14:10];
assign i12 = ds_inst[21:10];
assign i20 = ds_inst[24: 5];
assign i16 = ds_inst[25:10];
assign i26 = {ds_inst[ 9: 0], ds_inst[25:10]};
decoder_6_64 u_dec0(.in(op_31_26 ), .out(op_31_26_d ));
decoder_4_16 u_dec1(.in(op_25_22 ), .out(op_25_22_d ));
decoder_2_4 u_dec2(.in(op_21_20 ), .out(op_21_20_d ));
decoder_5_32 u_dec3(.in(op_19_15 ), .out(op_19_15_d ));
assign inst_add_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h00];
assign inst_sub_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h02];
assign inst_slt = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h04];
assign inst_sltu = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h05];
assign inst_nor = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h08];
assign inst_and = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h09];
assign inst_or = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h0a];
assign inst_xor = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h0b];
assign inst_slli_w = op_31_26_d[6'h00] & op_25_22_d[4'h1] & op_21_20_d[2'h0] & op_19_15_d[5'h01];
assign inst_srli_w = op_31_26_d[6'h00] & op_25_22_d[4'h1] & op_21_20_d[2'h0] & op_19_15_d[5'h09];
assign inst_srai_w = op_31_26_d[6'h00] & op_25_22_d[4'h1] & op_21_20_d[2'h0] & op_19_15_d[5'h11];
assign inst_addi_w = op_31_26_d[6'h00] & op_25_22_d[4'ha];
assign inst_ld_w = op_31_26_d[6'h0a] & op_25_22_d[4'h2];
assign inst_st_w = op_31_26_d[6'h0a] & op_25_22_d[4'h6];
assign inst_jirl = op_31_26_d[6'h13];
assign inst_b = op_31_26_d[6'h14];
assign inst_bl = op_31_26_d[6'h15];
assign inst_beq = op_31_26_d[6'h16];
assign inst_bne = op_31_26_d[6'h17];
assign inst_lu12i_w= op_31_26_d[6'h05] & ~ds_inst[25];
assign alu_op[ 0] = inst_add_w | inst_addi_w | inst_ld_w | inst_st_w
| inst_jirl | inst_bl;
assign alu_op[ 1] = inst_sub_w;
assign alu_op[ 2] = inst_slt;
assign alu_op[ 3] = inst_sltu;
assign alu_op[ 4] = inst_and;
assign alu_op[ 5] = inst_nor;
assign alu_op[ 6] = inst_or;
assign alu_op[ 7] = inst_xor;
assign alu_op[ 8] = inst_slli_w;
assign alu_op[ 9] = inst_srli_w;
assign alu_op[10] = inst_srai_w;
assign alu_op[11] = inst_lu12i_w;
assign need_ui5 = inst_slli_w | inst_srli_w | inst_srai_w;
assign need_si12 = inst_addi_w | inst_ld_w | inst_st_w;
assign need_si16 = inst_jirl | inst_beq | inst_bne;
assign need_si20 = inst_lu12i_w;
assign need_si26 = inst_b | inst_bl;
assign src2_is_4 = inst_jirl | inst_bl;
assign imm = src2_is_4 ? 32'h4 :
need_si20 ? {i20[19:0], 12'b0} :
need_ui5 ? rk :
/*need_si12*/{{20{i12[11]}}, i12[11:0]} ;
assign br_offs = need_si26 ? {{ 4{i26[25]}}, i26[25:0], 2'b0} :
{{14{i16[15]}}, i16[15:0], 2'b0} ;
assign jirl_offs = {{14{i16[15]}}, i16[15:0], 2'b0};
assign src_reg_is_rd = inst_beq | inst_bne | inst_st_w;
assign src1_is_pc = inst_jirl | inst_bl;
assign src2_is_imm = inst_slli_w |
inst_srli_w |
inst_srai_w |
inst_addi_w |
inst_ld_w |
inst_st_w |
inst_lu12i_w|
inst_jirl |
inst_bl ;
assign res_from_mem = inst_ld_w;
assign dst_is_r1 = inst_bl;
assign gr_we = ~inst_st_w & ~inst_beq & ~inst_bne & ~inst_b;
assign mem_we = inst_st_w;
assign dest = dst_is_r1 ? 5'd1 : rd;
assign rf_raddr1 = rj;
assign rf_raddr2 = src_reg_is_rd ? rd :rk;
regfile u_regfile(
.clk (clk ),
.raddr1 (rf_raddr1),
.rdata1 (rf_rdata1),
.raddr2 (rf_raddr2),
.rdata2 (rf_rdata2),
.we (rf_we ),
.waddr (rf_waddr ),
.wdata (rf_wdata )
);
assign rj_value = rf_rdata1;
assign rkd_value = rf_rdata2;
assign rj_eq_rd = (rj_value == rkd_value);
assign br_taken = ( inst_beq && rj_eq_rd
|| inst_bne && !rj_eq_rd
|| inst_jirl
|| inst_bl
|| inst_b
) && ds_valid & no_wait;
assign br_target = (inst_beq || inst_bne || inst_bl || inst_b) ? (ds_pc + br_offs) :
/*inst_jirl*/ (rj_value + jirl_offs);
assign br_stall = load_stall & br_taken & ds_valid;
assign load_stall = es_to_ds_load_op & (((rj == es_to_ds_dest) & rj_wait) |
((rk == es_to_ds_dest) & rk_wait) |
((rd == es_to_ds_dest) & rd_wait));
assign br_bus = {br_stall,br_taken,br_target};
reg [`FS_TO_DS_BUS_WD -1:0] fs_to_ds_bus_r;
assign {ds_inst,
ds_pc } = fs_to_ds_bus_r;
assign {rf_we , //37:37
rf_waddr, //36:32
rf_wdata //31:0
} = ws_to_rf_bus;
assign ds_to_es_bus = {alu_op , // 12
load_op , // 1
src1_is_pc , // 1
src2_is_imm , // 1
src2_is_4 , // 1
gr_we , // 1
mem_we , // 1
dest , // 5
imm , // 32
rj_value , // 32
rkd_value , // 32
ds_pc , // 32
res_from_mem
};
assign ds_ready_go = no_wait;
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 (fs_to_ds_valid && ds_allowin) begin
fs_to_ds_bus_r <= fs_to_ds_bus;
end
end
assign inst_no_dest = inst_st_w | inst_b | inst_beq | inst_bne;
assign src_no_rj = inst_b | inst_bl | inst_lu12i_w;
assign src_no_rk = inst_slli_w | inst_srli_w | inst_srai_w | inst_addi_w | inst_ld_w | inst_st_w | inst_jirl |
inst_b | inst_bl | inst_beq | inst_bne | inst_lu12i_w;
assign src_no_rd = ~inst_st_w & ~inst_beq & ~inst_bne;
assign rj_wait = ~src_no_rj && (rj != 5'b00000) && ((rj == es_to_ds_dest) || (rj == ms_to_ds_dest) || (rj == ws_to_ds_dest));
assign rk_wait = ~src_no_rk && (rk != 5'b00000) && ((rk == es_to_ds_dest) || (rk == ms_to_ds_dest) || (rk == ws_to_ds_dest));
assign rd_wait = ~src_no_rd && (rd != 5'b00000) && ((rd == es_to_ds_dest) || (rd == ms_to_ds_dest) || (rd == ws_to_ds_dest));
assign no_wait = ~rj_wait & ~rk_wait & ~rd_wait;
endmodule
##########################################################
`include "mycpu.h"
module if_stage(
input clk ,
input reset ,
//allwoin
input ds_allowin ,
//brbus
input [`BR_BUS_WD -1:0] br_bus ,
//to ds
output fs_to_ds_valid ,
output [`FS_TO_DS_BUS_WD -1:0] fs_to_ds_bus ,
// inst sram interface
output inst_sram_en ,
output [ 3:0] inst_sram_we ,
output [31:0] inst_sram_addr ,
output [31:0] inst_sram_wdata,
input [31:0] inst_sram_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;
wire br_stall;
wire pre_if_ready_go;
assign {br_stall, br_taken, br_target} = br_bus;
wire [31:0] fs_inst;
reg [31:0] fs_pc;
assign fs_to_ds_bus = {fs_inst ,
fs_pc };
// pre-IF stage
assign to_fs_valid = ~reset && pre_if_ready_go;
assign pre_if_ready_go = ~br_stall;
// because after sending fs_pc to ds, the seq_pc = fs_pc + 4 immediately
// Actually, the seq_pc is just a delay slot instruction
// if we use inst pc, here need to -4, it's more troublesome
assign seq_pc = fs_pc + 3'h4;
assign nextpc = br_taken ? br_target : seq_pc;
// IF stage
assign fs_ready_go = ~br_taken; //
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
end
always @(posedge clk) begin
if (reset) begin
fs_pc <= 32'h1bfffffc; //trick: to make nextpc be 0x1c000000 during reset
end
else if (to_fs_valid && (fs_allowin || br_taken)) begin
// if taken is valid, to skip the delay slot instruction, next_pc should be the instruction after the jump inst
fs_pc <= nextpc;
end
end
assign inst_sram_en = to_fs_valid && (fs_allowin || br_taken) && pre_if_ready_go;
assign inst_sram_we = 4'h0;
assign inst_sram_addr = nextpc;
assign inst_sram_wdata = 32'b0;
assign fs_inst = inst_sram_rdata;
endmodule
############################################################
`include "mycpu.h"
module mem_stage(
input clk ,
input reset ,
//allowin
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 ws
output ms_to_ws_valid,
output [`MS_TO_WS_BUS_WD -1:0] ms_to_ws_bus ,
//from data-sram
input [31 :0] data_sram_rdata,
output [4 :0] ms_to_ds_dest
);
reg ms_valid;
wire ms_ready_go;
reg [`ES_TO_MS_BUS_WD -1:0] es_to_ms_bus_r;
wire ms_res_from_mem;
wire ms_gr_we;
wire [ 4:0] ms_dest;
wire [31:0] ms_alu_result;
wire [31:0] ms_pc;
wire [31:0] mem_result;
wire [31:0] ms_final_result;
assign {ms_res_from_mem, //70:70
ms_gr_we , //69:69
ms_dest , //68:64
ms_alu_result , //63:32
ms_pc //31:0
} = es_to_ms_bus_r;
assign ms_to_ws_bus = {ms_gr_we , //69:69
ms_dest , //68:64
ms_final_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 (es_to_ms_valid && ms_allowin) begin
es_to_ms_bus_r = es_to_ms_bus;
end
end
assign mem_result = data_sram_rdata;
assign ms_final_result = ms_res_from_mem ? mem_result : ms_alu_result;
assign ms_to_ds_dest = ms_dest & {5{ms_valid}};
endmodule
###################################################
`include "mycpu.h"
module mycpu_top(
input wire clk,
input wire resetn,
// inst sram interface
output wire inst_sram_en,
output wire [ 3:0] inst_sram_we,
output wire [31:0] inst_sram_addr,
output wire [31:0] inst_sram_wdata,
input wire [31:0] inst_sram_rdata,
// data sram interface
output wire data_sram_en,
output wire [ 3:0] data_sram_we,
output wire [31:0] data_sram_addr,
output wire [31:0] data_sram_wdata,
input wire [31:0] data_sram_rdata,
// trace debug interface
output wire [31:0] debug_wb_pc,
output wire [ 3:0] debug_wb_rf_we,
output wire [ 4:0] debug_wb_rf_wnum,
output wire [31:0] debug_wb_rf_wdata
);
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 [4 :0] es_to_ds_dest;
wire [4 :0] ms_to_ds_dest;
wire [4 :0] ws_to_ds_dest;
wire es_to_ds_load_op;
// IF stage
if_stage if_stage(
.clk (clk ),
.reset (reset ),
//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 sram interface
.inst_sram_en (inst_sram_en ),
.inst_sram_we (inst_sram_we ),
.inst_sram_addr (inst_sram_addr ),
.inst_sram_wdata(inst_sram_wdata),
.inst_sram_rdata(inst_sram_rdata)
);
// ID stage
id_stage id_stage(
.clk (clk ),
.reset (reset ),
//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 fs
.br_bus (br_bus ),
//to rf: for write back
.ws_to_rf_bus (ws_to_rf_bus ),
//Hazard detection signals
.es_to_ds_dest (es_to_ds_dest ),
.ms_to_ds_dest (ms_to_ds_dest ),
.ws_to_ds_dest (ws_to_ds_dest ),
.es_to_ds_load_op(es_to_ds_load_op)
);
// EXE stage
exe_stage exe_stage(
.clk (clk ),
.reset (reset ),
//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 ),
//to ms
.es_to_ms_valid (es_to_ms_valid ),
.es_to_ms_bus (es_to_ms_bus ),
//data sram interface
.data_sram_en (data_sram_en ),
.data_sram_we (data_sram_we ),
.data_sram_addr (data_sram_addr ),
.data_sram_wdata(data_sram_wdata),
//Hazard detection signals
.es_to_ds_dest (es_to_ds_dest ),
.es_to_ds_load_op(es_to_ds_load_op)
);
// MEM stage
mem_stage mem_stage(
.clk (clk ),
.reset (reset ),
//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 ws
.ms_to_ws_valid (ms_to_ws_valid ),
.ms_to_ws_bus (ms_to_ws_bus ),
//from data-sram
.data_sram_rdata(data_sram_rdata),
//Hazard detection signals
.ms_to_ds_dest (ms_to_ds_dest )
);
// WB stage
wb_stage wb_stage(
.clk (clk ),
.reset (reset ),
//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 ),
//trace debug interface
.debug_wb_pc (debug_wb_pc ),
.debug_wb_rf_we (debug_wb_rf_we ),
.debug_wb_rf_wnum (debug_wb_rf_wnum ),
.debug_wb_rf_wdata(debug_wb_rf_wdata),
//Hazard detection signals
.ws_to_ds_dest (ws_to_ds_dest )
);
endmodule
##################################################
`include "mycpu.h"
module wb_stage(
input wire clk,
input wire reset,
//allowin
output wire ws_allowin,
//from ms
input wire ms_to_ws_valid,
input wire [`MS_TO_WS_BUS_WD -1:0] ms_to_ws_bus,
//to rf: for write back
output wire [`WS_TO_RF_BUS_WD -1:0] ws_to_rf_bus,
//trace debug interface
output wire [31:0] debug_wb_pc ,
output wire [ 3:0] debug_wb_rf_we ,
output wire [ 4:0] debug_wb_rf_wnum,
output wire [31:0] debug_wb_rf_wdata,
output wire [ 4:0] ws_to_ds_dest
);
reg ws_valid;
wire ws_ready_go;
reg [`MS_TO_WS_BUS_WD -1:0] ms_to_ws_bus_r;
wire ws_gr_we;
wire [ 4:0] ws_dest;
wire [31:0] ws_final_result;
wire [31:0] ws_pc;
assign {ws_gr_we , //69:69
ws_dest , //68:64
ws_final_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_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 (ms_to_ws_valid && ws_allowin) begin
ms_to_ws_bus_r <= ms_to_ws_bus;
end
end
assign rf_we = ws_gr_we && ws_valid;
assign rf_waddr = ws_dest;
assign rf_wdata = ws_final_result;
// debug info generate
assign debug_wb_pc = ws_pc;
assign debug_wb_rf_we = {4{rf_we}};
assign debug_wb_rf_wnum = ws_dest;
assign debug_wb_rf_wdata = ws_final_result;
assign ws_to_ds_dest = ws_dest & {5{ws_valid}};
endmodule这是我的实验的代码,我想要在我这个代码的基础上进行修改,实现前递的功能,我用的是loongarch32指令架构,然后我要实现的指令有add.w,addi.w,sub.w,ld.w,st.w,beq,bne,b,bl,jirl,slt,sltu,slli.w,srli.w,srai.w,lu12i.w,and,nor,or,xor这些,在我让你写代码之前你不要生成任何代码,首先告诉我你想要怎么做