Menu Close

RISC-V Register File Implementation and Decoder Module(3)Register File

In the RISC-V RV32I CPU core, 32 general purpose registers are required. These registers are a critical part of parsing riscv assembly instructions. Related reference articles:

RISC-V teaching plan

  RISC-V cpu architecture:

fii_riscv_regfile

In each risc-v cpu of RV32I, there are 32 general-purpose registers. The X0 register is always ‘0’ when it is read. When writing to the x0 register, the cpu hardware can ignore it (do nothing). For the RV32E cpu, the 16 general-purpose registers x16-x31 can be omitted, and only the 16 registers x0-x15 are reserved. This design can reduce the size of the cpu, but it is not very general. Because even the cpu size of rv32I is not very big. XLEN can vary according to riscv design, for RV64, XLEN = 64; for RV32, XLEN = 32. Our current riscv cpu design is RV32I, so XLEN = 32.

module regfile_I(
    input sys_clk,              // system clock
    input i_EXE_vld,            // execute the enable signal
    input [ 4: 0 ] i_rs1_idx,   // rs1 in assembly instructions
    input [ 4: 0 ] i_rs2_idx,   // rs2 in assembly instructions
    output [ 31: 0 ] o_rs1_val, // rs1 in the assembly instruction, the value of the selected register among the corresponding 32 general-purpose registers
    output [ 31: 0 ] o_rs2_val, // rs2 in the assembly instruction, the value of the selected register among the corresponding 32 general-purpose registers
    output o_wb_rdy,            // write-back ready, always equal to 1
    input i_wb_wen,             // write general register signal
    input [ 4: 0 ] i_wb_rd_idx, // rd in assembly instructions,
    input [ 31: 0 ] i_wb_val    // rd in the assembly instruction, the value of the selected register among the corresponding 32 general-purpose registers
);

wire[31:0] rf_r[31:1];
wire [ 31: 1 ] rf_wen;

genvar i;
generate
for ( i = 1; i < 32; i = i + 1 )
begin : REG
    assign rf_wen[ i ] = i_EXE_vld & i_wb_wen & ( i_wb_rd_idx == i ) ;
    fii_dffl #( 32 ) rf_dffl ( rf_wen[ i ], i_wb_val, rf_r[ i ], sys_clk );
end
endgenerate

`ifdef sim
    assign o_rs1_val = ( i_rs1_idx == 0 ) ? 32'b0 :
        ( rf_r[ i_rs1_idx ] == 32'hxxxxxxxx ) ? 32'b0 : rf_r[ i_rs1_idx ];
    assign o_rs2_val = ( i_rs2_idx == 0 ) ? 32'b0 :
        ( rf_r[ i_rs2_idx ] == 32'hxxxxxxxx ) ? 32'b0 : rf_r[ i_rs2_idx ];
`else
    assign o_rs1_val = ( i_rs1_idx == 0 ) ? 32'b0 : rf_r[ i_rs1_idx ];
    assign o_rs2_val = ( i_rs2_idx == 0 ) ? 32'b0 : rf_r[ i_rs2_idx ];
`endif

assign o_wb_rdy = 1'b1;

endmodule

input [ 4: 0 ] i_rs1_idx , // rs1 in assembly instructions

input [ 4: 0 ] i_rs2_idx , // rs2 in assembly instructions

output [ 31: 0 ] o_rs1_val , // rs1 in the assembly instruction, the value of the selected register among the corresponding 32 general-purpose registers

output [ 31: 0 ] o_rs2_val , // rs2 in the assembly instruction, the value of the selected register among the corresponding 32 general-purpose registers

output o_wb_rdy, // write-back ready, always equal to 1

input i_wb_wen , // write general register signal

input [ 4: 0 ] i_wb_rd_idx ,// rd in assembly instructions,

input [ 31: 0 ] i_wb_val // rd in the assembly instruction, the value of the selected register among the corresponding 32 general-purpose registers

 

In the code snippet: write operation

genvar i;
generate
    for ( i = 1; i < 32; i = i + 1 )
        begin : REG
            assign rf_wen[ i ] = i_EXE_vld & i_wb_wen & ( i_wb_rd_idx == i ) ;
            fii_dffl #( 32 ) rf_dffl ( rf_wen[ i ], i_wb_val, rf_r[ i ], sys_clk );
        end
endgenerate

fii_dffl file code:

module fii_dffl # (
parameter DW = 32
) (
    input ld,
    input [DW-1:0] din,
    output reg [DW-1:0] q = 0,

    input clk
);

 

always @(posedge clk )
if (ld)
     q <= #1 din;

endmodule

 

In the code snippet: read operation

assign o_rs1_val = ( i_rs1_idx == 0 ) ? 32’b0 : rf_r[ i_rs1_idx ];
assign o_rs2_val = ( i_rs2_idx == 0 ) ? 32’b0 : rf_r[ i_rs2_idx ] ;

When reading x0 (whether rs1 or rs2 reads x0), it returns 0 directly; in other cases (1-31), it returns according to the value in the register.

 

 

Posted in FPGA, IC, RISC-V, RISC-V Textbook, Textbook and Training Project

Related Articles

Leave a Reply

Your email address will not be published.

Leave the field below empty!