在 Verilog 中实现一个 32x64 的寄存器文件

Posted

技术标签:

【中文标题】在 Verilog 中实现一个 32x64 的寄存器文件【英文标题】:Implement a 32x64 register file in Verilog 【发布时间】:2017-03-29 04:14:54 【问题描述】:

这里是寄存器文件的规格:

总线 A、B 和 W 为 64 位宽。

当 RegWr 设置为 1 时,总线 W 上的数据存储在 由 Rw 指定的寄存器,在负(下降)时钟沿。

寄存器 31 必须始终读取为零。

来自寄存器的数据(由 Ra 和 Rb 指定)在总线 A 上发送,并且 总线 B 分别延迟 2 次。

对寄存器文件的写入必须延迟 3 次。

Register File模块应该有如下界面:

module RegisterFile(BusA, BusB, BusW, RA, RB, RW, RegWr, Clk);

这是我当前的程序

module RegisterFile(BusA, BusB, BusW, RA, RB, RW, RegWr, Clk);
 output [63:0] BusA;
 output [63:0] BusB;
 output [63:0] BusW;
 input RA;
 input RB;
 input RW;
 input RegWr;
 input Clk;
 reg [31:0] registers [31:0];

 assign #2 BusA = registers [0];
 assign #2 BusB = registers [1];

 always @ (negedge Clk) begin
  if(RegWr & RW !=0)
    registers[RW] <= #3 BusW;
 end
endmodule

我想知道如何将RA和RB初始化为零,想知道如何将数据从RA和RB正确发送到BusA和BusB

【问题讨论】:

【参考方案1】:

代码中有几处需要先修改

    BusA、BusB 和 BusW 是每个 64 位宽的数据总线。 BusW 用作输入总线,而 BusA 和 BusB 是输出总线。因此,端口的声明需要更改为

    input [63:0] BusW;
    output [63:0] BusA, BusB;
    

    寄存器文件的深度为 32。RA、RB 和 RW 是地址总线。这些地址需要 5 位宽。

    input [4:0] RA,RB,RW;
    

    完整的代码可以重写为

    module RegisterFile(BusA, BusB, BusW, RA, RB, RW, RegWr, Clk);
      output [63:0] BusA, BusB;
      input [63:0] BusW;
      input [4:0] RA, RB, RW;
      input RegWr;
      input Clk;
    
      reg [63:0] registers [31:0];
    
      assign #2 BusA = registers[RA];
      assign #2 BusB = registers[RB];
    
      always @ (negedge Clk) 
      begin
        if(RegWr)
          if (RW != 4'd31)
            registers[RW] <= #3 BusW;
          else 
            // This is done to allow the user to reset the 0th location to a zero value.
            registers[0] <= #3 'd0; 
      end
    endmodule
    

我在 edaplayground 上模拟了这段代码,并创建了一个小型测试台来测试它。这是代码和测试平台的链接 https://www.edaplayground.com/x/5DXC

【讨论】:

以上是关于在 Verilog 中实现一个 32x64 的寄存器文件的主要内容,如果未能解决你的问题,请参考以下文章

在verilog中实现PIPO

如何用verilog语言在fpga中实现双向数据总线?

verilog 二维数组是如何初始化的啊?

verilog 寄存器初始化

verilog的寄存器默认初始值是多少?

verilog中如何实现上电复位给寄存器赋初值?