Menu Close

RISC-V32个寄存器和译码模块(3)寄存器文件

在RISC-V RV32I CPU 核中,需要32个通用的寄存器。这些寄存器是解析riscv 汇编指令的关键部分。

相关参考文章:

RISC-V 教学教案

 

RISC-V cpu 架构:

%title插图%num

%title插图%num

 

每一个RV32I 的risc-v 的cpu 中,都有32个通用的寄存器。 其中X0寄存器 在读取时,永远为‘0’。 写x0 寄存器 时,cpu 硬件可以进行忽略(不做任何处理)。对于RV32E cpu 来说, 可以省略掉x16-x31 这16个通用寄存器,只是保留x0-x15 这16个寄存器,这样的设计可以减少cpu 的尺寸,但并不是非常通用。因为即使是rv32I 的cpu 尺寸也不是很大。

%title插图%num
fii_32reg

XLEN 是根据riscv 的 设计可以有所不同,对于RV64 来说, XLEN = 64; 对于RV32 来说,XLEN = 32。 我们当前设计的riscv cpu 为RV32I, 所以XLEN = 32。

 

module regfile_I(
input sys_clk, // 系统时钟

input i_EXE_vld, // 执行enable 信号

input [ 4: 0 ] i_rs1_idx, // 汇编指令中的rs1
input [ 4: 0 ] i_rs2_idx, // 汇编指令中的rs2

output [ 31: 0 ] o_rs1_val, // 汇编指令中的rs1,所对应的32个通用寄存器当中选中的寄存器的值
output [ 31: 0 ] o_rs2_val, // 汇编指令中的rs2,所对应的32个通用寄存器当中选中的寄存器的值

output o_wb_rdy, // 回写准备好,一直 等于 1
input i_wb_wen, // 写通用寄存器 信号
input [ 4: 0 ] i_wb_rd_idx, // 汇编指令中的rd,
input [ 31: 0 ] i_wb_val // 汇编指令中的rd,所对应的32个通用寄存器当中选中的寄存器的值
);

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

input [ 4: 0 ] i_rs2_idx, // 汇编指令中的rs2

output [ 31: 0 ] o_rs1_val, // 汇编指令中的rs1,所对应的32个通用寄存器当中选中的寄存器的值

output [ 31: 0 ] o_rs2_val, // 汇编指令中的rs2,所对应的32个通用寄存器当中选中的寄存器的值

output o_wb_rdy, // 回写准备好,一直 等于 1

input i_wb_wen, // 写通用寄存器 信号

input [ 4: 0 ] i_wb_rd_idx,// 汇编指令中的rd,

input [ 31: 0 ] i_wb_val // 汇编指令中的rd,所对应的32个通用寄存器当中选中的寄存器的值

 

在代码段中:写操作

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 文件代码:

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

 

在代码段中:读操作

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 ];

在读取x0时(不论是rs1,还是rs2 读取x0), 直接返回0; 其他情况(1-31) 根据寄存器当中的值进行返回。

Posted in FPGA, FPGA, IC, RISC-V, RISC-V IPcore设计, RISC-V 教案, 教材与教案, 文章

发表评论

相关链接