u@home:~$

irf的read port是该在上升沿读出数据吗,需要ren吗?

// register file for MIPS 32

module reg_file(
        input clk,
        // input rst,

        input   [ 4:0]                  waddr1,
        input   [ 4:0]                  raddr0_0,
        input   [ 4:0]                  raddr0_1,
        input                                   wen1,
        input   [`GRLEN-1:0]    wdata1,
        output  [`GRLEN-1:0]    rdata0_0,
        output  [`GRLEN-1:0]    rdata0_1,

        input   [ 4:0]                  waddr2,
        input   [ 4:0]                  raddr1_0,
        input   [ 4:0]                  raddr1_1,
        input                                   wen2,
        input   [`GRLEN-1:0]    wdata2,
        output  [`GRLEN-1:0]    rdata1_0,
        output  [`GRLEN-1:0]    rdata1_1,

        input   [ 4:0]                  raddr2_0,
        input   [ 4:0]                  raddr2_1,
        output  [`GRLEN-1:0]    rdata2_0,
        output  [`GRLEN-1:0]    rdata2_1
);

  // registers (r0 excluded)
        reg [`GRLEN-1:0] regs [31:0];

  // read after write (RAW)
        wire r1_1_w1_raw =      wen1 && (raddr0_0 == waddr1);
        wire r1_2_w1_raw =  wen1 && (raddr0_1 == waddr1);
        wire r1_1_w2_raw =      wen2 && (raddr0_0 == waddr2);
        wire r1_2_w2_raw =  wen2 && (raddr0_1 == waddr2);

        wire r2_1_w1_raw =      wen1 && (raddr1_0 == waddr1);
        wire r2_2_w1_raw =  wen1 && (raddr1_1 == waddr1);
        wire r2_1_w2_raw =      wen2 && (raddr1_0 == waddr2);
        wire r2_2_w2_raw =  wen2 && (raddr1_1 == waddr2);

        wire r3_1_w1_raw =      wen1 && (raddr2_0 == waddr1);
        wire r3_2_w1_raw =  wen1 && (raddr2_1 == waddr1);
        wire r3_1_w2_raw =      wen2 && (raddr2_0 == waddr2);
        wire r3_2_w2_raw =  wen2 && (raddr2_1 == waddr2);

        wire r1_1_raw = r1_1_w1_raw || r1_1_w2_raw;     // read port need forwarding
        wire r1_2_raw = r1_2_w1_raw || r1_2_w2_raw;
        wire r2_1_raw = r2_1_w1_raw || r2_1_w2_raw;
        wire r2_2_raw = r2_2_w1_raw || r2_2_w2_raw;
        wire r3_1_raw = r3_1_w1_raw || r3_1_w2_raw;
        wire r3_2_raw = r3_2_w1_raw || r3_2_w2_raw;

        wire [`GRLEN-1:0]       r1_1_raw_data = r1_1_w2_raw ? wdata2 : wdata1;  // forwarding data
        wire [`GRLEN-1:0]       r1_2_raw_data = r1_2_w2_raw ? wdata2 : wdata1;
        wire [`GRLEN-1:0]       r2_1_raw_data = r2_1_w2_raw ? wdata2 : wdata1;
        wire [`GRLEN-1:0]       r2_2_raw_data = r2_2_w2_raw ? wdata2 : wdata1;
        wire [`GRLEN-1:0]       r3_1_raw_data = r3_1_w2_raw ? wdata2 : wdata1;
        wire [`GRLEN-1:0]       r3_2_raw_data = r3_2_w2_raw ? wdata2 : wdata1;

  // write crash
        wire write_crash = (waddr1 == waddr2);
        wire wen1_input = (!write_crash || !wen2) && wen1;
        wire wen2_input = wen2;

  // process read (r0 wired to 0)

        assign rdata0_0 = raddr0_0 == 0 ? 0 : r1_1_raw ? r1_1_raw_data : regs[raddr0_0];
        assign rdata0_1 = raddr0_1 == 0 ? 0 : r1_2_raw ? r1_2_raw_data : regs[raddr0_1];

        assign rdata1_0 = raddr1_0 == 0 ? 0 : r2_1_raw ? r2_1_raw_data : regs[raddr1_0];
        assign rdata1_1 = raddr1_1 == 0 ? 0 : r2_2_raw ? r2_2_raw_data : regs[raddr1_1];

        assign rdata2_0 = raddr2_0 == 0 ? 0 : r3_1_raw ? r3_1_raw_data : regs[raddr2_0];
        assign rdata2_1 = raddr2_1 == 0 ? 0 : r3_2_raw ? r3_2_raw_data : regs[raddr2_1];

  // process write
        always @(posedge clk) begin
                // if(rst) begin
                //      regs[31] <= 32'd0;

                // end
                // else begin
                        case({wen1_input,wen2_input})
                                        2'b11:begin
                                           regs[waddr1] <= wdata1;
                                           regs[waddr2] <= wdata2;
                                           end
                                        2'b10:regs[waddr1] <= wdata1;
                                        2'b01:regs[waddr2] <= wdata2;
                                        default:        ;
                        endcase
                // end
        end

endmodule

6 read 2 write

从代码上看读不需要在上升沿。

那这样读寄存器可以在decode阶段,时间也许够用。


现在用的是chiplab的regfile,读rf也是在decode阶段。

读出来的rs1 rs2,存入流水线寄存器给exe阶段的alu。

screenshot0