`timescale 1ns / 1ps `default_nettype none // ----------------------------------------------------------------------------- // 寄存器堆:32 x 32 位,x0 恒为 0。 // // 读端口为组合读,并对同周期的 WB 写回做"写优先"旁路,因此 ID 级可以 // 立刻看到正在写回的结果,无需额外的寄存器堆相关冒险处理。 // ----------------------------------------------------------------------------- module cpu21_riscv_regfile ( input wire clk, input wire reset, // 读端口(组合) input wire [ 4:0] rs1_idx_i, input wire [ 4:0] rs2_idx_i, output wire [31:0] rs1_data_o, output wire [31:0] rs2_data_o, // 写端口(WB 级) input wire we_i, input wire [ 4:0] waddr_i, input wire [31:0] wdata_i ); reg [31:0] regs[0:31]; integer i; // 写优先旁路:同周期写回且地址相同的读请求返回新值。 wire [31:0] rs1_raw = regs[rs1_idx_i]; wire [31:0] rs2_raw = regs[rs2_idx_i]; assign rs1_data_o = (rs1_idx_i == 5'd0) ? 32'b0 : ((we_i && (waddr_i == rs1_idx_i)) ? wdata_i : rs1_raw); assign rs2_data_o = (rs2_idx_i == 5'd0) ? 32'b0 : ((we_i && (waddr_i == rs2_idx_i)) ? wdata_i : rs2_raw); always @(posedge clk or posedge reset) begin if (reset) begin for (i = 0; i < 32; i = i + 1) regs[i] <= 32'b0; end else begin if (we_i && (waddr_i != 5'd0)) regs[waddr_i] <= wdata_i; regs[0] <= 32'b0; end end endmodule `default_nettype wire