10 05 20 Hf过来

记录了Hf为明天面试所做的准备以及作者今天的工作情况,包括被Bls折腾的经历和下午出现的问题。

今天中午Hf过来了,准备明天去面试,她下定决心了gz干活了,真爽。今天被Bls折腾了一天,弄到1点才回到宿舍。下午mzr发现我弄的东西出现了问题,自己还写了失误报告,唉,为何呢?老弄这种事情!

 

读在今天:***
想在今天:坚持就是胜利,要耐得住

`timescale 1ns / 1ps module if_stage( input clk , input reset , //allwoin input ds_allowin , //brbus input [33:0] br_bus , //to ds output fs_to_ds_valid , output [63: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 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`timescale 1ns / 1ps module id_stage( input clk , input reset , 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, //allowin input es_allowin , output ds_allowin , //from fs input fs_to_ds_valid, input [63:0] fs_to_ds_bus , //to es output ds_to_es_valid, output [151:0] ds_to_es_bus , //to fs output [33:0] br_bus , //to rf: for write back input [37:0] ws_to_rf_bus ); wire br_taken; wire [31:0] br_target; wire br_stall; wire load_stall; 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; 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_bus = {br_stall,br_taken, br_target}; reg [63: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; 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)); endmodule`timescale 1ns / 1ps module exe_stage( input clk , input reset , output es_to_ds_load_op, output [ 4:0] es_to_ds_dest, //执行级目的操作数寄存器号 //allowin input ms_allowin , output es_allowin , //from ds input ds_to_es_valid, input [151:0] ds_to_es_bus , //to ms output es_to_ms_valid, output [70: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 ); reg es_valid ; wire es_ready_go ; reg [151: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 `timescale 1ns / 1ps module mem_stage( input wire clk , input wire reset , output wire [ 4:0] ms_to_ds_dest, //访存级目的操作数寄存器号 //allowin input wire ws_allowin , output wire ms_allowin , //from es input wire es_to_ms_valid, input wire [70:0] es_to_ms_bus , //to ws output wire ms_to_ws_valid, output wire [69:0] ms_to_ws_bus , //from data-sram input wire [31 :0] data_sram_rdata ); reg ms_valid; wire ms_ready_go; reg [70: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 `timescale 1ns / 1ps module wb_stage( input clk , input reset , output wire [ 4:0] ws_to_ds_dest, //写回级目的操作数寄存器号 //allowin output ws_allowin , //from ms input ms_to_ws_valid, input [69:0] ms_to_ws_bus , //to rf: for write back output [37:0] ws_to_rf_bus , //trace debug interface output [31:0] debug_wb_pc , output [ 3:0] debug_wb_rf_we , output [ 4:0] debug_wb_rf_wnum, output [31:0] debug_wb_rf_wdata ); reg ws_valid; wire ws_ready_go; reg [69: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 检查代码逻辑,分析上面代码能否实现用阻塞技术解决读后写的冲突,实现五段流水线的基本功能;仿真时debug_wb_pc的值一直为0xxxxxxxxx,原因是什么,复位信号正常,运行时间足够长
07-05
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这些,在我让你写代码之前你不要生成任何代码,首先告诉我你想要怎么做
07-11
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值