Verilog 将第一个寄存器赋值为零,不写入

Verilog 将第一个寄存器赋值为零,不写入,verilog,cpu-registers,test-bench,Verilog,Cpu Registers,Test Bench,我是Verilog的新手,尝试创建一个包含32位寄存器的寄存器文件。我能够正确地写入和读取所有内容,但是,位于地址5'b00000处的第一个寄存器(我们将其命名为R0)必须始终等于0,并且在任何时候都不得更改。在测试台上读取时,当R0突然变为“xxxxxxxx”而不是0或00000000时,就会出现问题。其余寄存器被正确读取。我在代码中可能做错了什么?这个问题的解决方法是什么?代码如下: module regfile ( clk, nrst, rd_addrA,

我是Verilog的新手,尝试创建一个包含32位寄存器的寄存器文件。我能够正确地写入和读取所有内容,但是,位于地址5'b00000处的第一个寄存器(我们将其命名为R0)必须始终等于0,并且在任何时候都不得更改。在测试台上读取时,当R0突然变为“xxxxxxxx”而不是0或00000000时,就会出现问题。其余寄存器被正确读取。我在代码中可能做错了什么?这个问题的解决方法是什么?代码如下:

module regfile (
    clk,
    nrst,
    rd_addrA,
    rd_addrB,
    wr_addr,
    wr_en,
    wr_data,
    rd_dataA,
    rd_dataB
);

//Input and output ports
input wire clk;
input wire nrst;
input wire [4:0] rd_addrA;
input wire [4:0] rd_addrB;
input wire [4:0] wr_addr;
input wire wr_en;
input wire [31:0] wr_data;
output reg [31:0] rd_dataA;
output reg [31:0] rd_dataB;

reg [31:0] regfile[0:31];
integer i;

always @ (nrst)
    begin: RESET
        if(nrst == 0) begin
            for(i = 0; i < 32; i++) begin
                regfile[i] = 0;
            end
        end
    end

always @(rd_addrA or rd_addrB)
    begin: READ
        if(rd_addrA) begin
            case (rd_addrA)
                5'b00000: rd_dataA = regfile[0];
                5'b00001: rd_dataA = regfile[1];
                5'b00010: rd_dataA = regfile[2];
                5'b00011: rd_dataA = regfile[3];
                5'b00100: rd_dataA = regfile[4];
                5'b00101: rd_dataA = regfile[5];
                5'b00110: rd_dataA = regfile[6];
                5'b00111: rd_dataA = regfile[7];
                5'b01000: rd_dataA = regfile[8];
                5'b01001: rd_dataA = regfile[9];
                5'b01010: rd_dataA = regfile[10];
                5'b01011: rd_dataA = regfile[11];
                5'b01100: rd_dataA = regfile[12];
                5'b01101: rd_dataA = regfile[13];
                5'b01110: rd_dataA = regfile[14];
                5'b01111: rd_dataA = regfile[15];
                5'b10000: rd_dataA = regfile[16];
                5'b10001: rd_dataA = regfile[17];
                5'b10010: rd_dataA = regfile[18];
                5'b10011: rd_dataA = regfile[19];
                5'b10100: rd_dataA = regfile[20];
                5'b10101: rd_dataA = regfile[21];
                5'b10110: rd_dataA = regfile[22];
                5'b10111: rd_dataA = regfile[23];
                5'b11000: rd_dataA = regfile[24];
                5'b11001: rd_dataA = regfile[25];
                5'b11010: rd_dataA = regfile[26];
                5'b11011: rd_dataA = regfile[27];
                5'b11100: rd_dataA = regfile[28];
                5'b11101: rd_dataA = regfile[29];
                5'b11110: rd_dataA = regfile[30];
                5'b11111: rd_dataA = regfile[31];
                default: rd_dataA = 16'hXXXX;
            endcase
        end

        if(rd_addrB) begin
            case (rd_addrB)
                5'b00000: rd_dataB = regfile[0];
                5'b00001: rd_dataB = regfile[1];
                5'b00010: rd_dataB = regfile[2];
                5'b00011: rd_dataB = regfile[3];
                5'b00100: rd_dataB = regfile[4];
                5'b00101: rd_dataB = regfile[5];
                5'b00110: rd_dataB = regfile[6];
                5'b00111: rd_dataB = regfile[7];
                5'b01000: rd_dataB = regfile[8];
                5'b01001: rd_dataB = regfile[9];
                5'b01010: rd_dataB = regfile[10];
                5'b01011: rd_dataB = regfile[11];
                5'b01100: rd_dataB = regfile[12];
                5'b01101: rd_dataB = regfile[13];
                5'b01110: rd_dataB = regfile[14];
                5'b01111: rd_dataB = regfile[15];
                5'b10000: rd_dataB = regfile[16];
                5'b10001: rd_dataB = regfile[17];
                5'b10010: rd_dataB = regfile[18];
                5'b10011: rd_dataB = regfile[19];
                5'b10100: rd_dataB = regfile[20];
                5'b10101: rd_dataB = regfile[21];
                5'b10110: rd_dataB = regfile[22];
                5'b10111: rd_dataB = regfile[23];
                5'b11000: rd_dataB = regfile[24];
                5'b11001: rd_dataB = regfile[25];
                5'b11010: rd_dataB = regfile[26];
                5'b11011: rd_dataB = regfile[27];
                5'b11100: rd_dataB = regfile[28];
                5'b11101: rd_dataB = regfile[29];
                5'b11110: rd_dataB = regfile[30];
                5'b11111: rd_dataB = regfile[31];
                default: rd_dataB = 16'hXXXX;
            endcase
        end
    end

always @ (posedge clk)
    begin: WRITE
        if(wr_en == 1'b1) begin
            if(wr_addr != 5'd0) begin
                regfile[wr_addr] = #1 wr_data;
                //$display("%X", regfile[wr_addr]);
            end
            else begin
                $display("R0: %X", regfile[wr_addr]);
            end
        end
    end

endmodule
模块注册表文件(
中华电力有限公司,
nrst,
阿德拉,
rd_addrB,
地址:,
嗯,,
wr_数据,
德乌达塔,
rd_数据库
);
//输入和输出端口
输入线时钟;
输入线nrst;
输入线[4:0]rd_addrA;
输入线[4:0]rd_addrB;
输入线[4:0]wr_addr;
输入线wr_en;
输入线[31:0]wr_数据;
输出寄存器[31:0]rd_数据a;
输出寄存器[31:0]rd_数据;
reg[31:0]regfile[0:31];
整数i;
始终@(nrst)
开始:重置
如果(nrst==0)开始
对于(i=0;i<32;i++)开始
regfile[i]=0;
结束
结束
结束
始终@(rd_addrA或rd_addrB)
开始:阅读
如果(rd_addrA)开始
案件(rd_addrA)
5'b00000:rd_dataA=regfile[0];
5'b00001:rd_dataA=regfile[1];
5'b00010:rd_dataA=regfile[2];
5'b00011:rd_dataA=regfile[3];
5'b00100:rd_dataA=regfile[4];
5'b00101:rd_dataA=regfile[5];
5'b00110:rd_dataA=regfile[6];
5'b00111:rd_dataA=regfile[7];
5'b01000:rd_dataA=regfile[8];
5'b01001:rd_dataA=regfile[9];
5'b01010:rd_dataA=regfile[10];
5'b01011:rd_dataA=regfile[11];
5'b01100:rd_dataA=regfile[12];
5'b01101:rd_dataA=regfile[13];
5'b01110:rd_dataA=regfile[14];
5'b01111:rd_dataA=regfile[15];
5'b10000:rd_dataA=regfile[16];
5'b10001:rd_dataA=regfile[17];
5'b10010:rd_dataA=regfile[18];
5'b10011:rd_dataA=regfile[19];
5'b10100:rd_dataA=regfile[20];
5'b10101:rd_dataA=regfile[21];
5'b10110:rd_dataA=regfile[22];
5'b10111:rd_dataA=regfile[23];
5'b11000:rd_dataA=regfile[24];
5'b11001:rd_dataA=regfile[25];
5'b11010:rd_dataA=regfile[26];
5'b11011:rd_dataA=regfile[27];
5'b11100:rd_dataA=regfile[28];
5'b11101:rd_dataA=regfile[29];
5'b11110:rd_dataA=regfile[30];
5'b11111:rd_dataA=regfile[31];
默认值:rd_dataA=16'hXXXX;
尾声
结束
如果(rd_addrB)开始
案例(rd_addrB)
5'b00000:rd_dataB=regfile[0];
5'b00001:rd_dataB=regfile[1];
5'b00010:rd_dataB=regfile[2];
5'b00011:rd_dataB=regfile[3];
5'b00100:rd_dataB=regfile[4];
5'b00101:rd_dataB=regfile[5];
5'b00110:rd_dataB=regfile[6];
5'b00111:rd_dataB=regfile[7];
5'b01000:rd_dataB=regfile[8];
5'b01001:rd_dataB=regfile[9];
5'b01010:rd_dataB=regfile[10];
5'b01011:rd_dataB=regfile[11];
5'b01100:rd_dataB=regfile[12];
5'b01101:rd_dataB=regfile[13];
5'b01110:rd_dataB=regfile[14];
5'b01111:rd_dataB=regfile[15];
5'b10000:rd_dataB=regfile[16];
5'b10001:rd_dataB=regfile[17];
5'b10010:rd_dataB=regfile[18];
5'b10011:rd_dataB=regfile[19];
5'b10100:rd_dataB=regfile[20];
5'b10101:rd_dataB=regfile[21];
5'b10110:rd_dataB=regfile[22];
5'b10111:rd_dataB=regfile[23];
5'b11000:rd_dataB=regfile[24];
5'b11001:rd_dataB=regfile[25];
5'b11010:rd_dataB=regfile[26];
5'b11011:rd_dataB=regfile[27];
5'b11100:rd_dataB=regfile[28];
5'b11101:rd_dataB=regfile[29];
5'b11110:rd_dataB=regfile[30];
5'b11111:rd_dataB=regfile[31];
默认值:rd_数据=16'hXXXX;
尾声
结束
结束
始终@(posedge clk)
开始:写
如果(wr_en==1'b1)开始
如果(wr_addr!=5'd0)开始
regfile[wr#u addr]=#1 wr#u数据;
//$display(“%X”,regfile[wr_addr]);
结束
否则开始
$display(“R0:%X”,regfile[wr_addr]);
结束
结束
结束
端模
非常感谢您的帮助。

if(rd\u addrA)
被解释为
if(rd\u addrA>0)
。因此,无法读取
regfile[0]
。因为所有条目都是有效的,所以不需要if语句

与您的主要问题无关的其他问题:

您的代码不可合成,因为
regfile
分配在两个不同的always块中。您需要将
regfile
的重置和写入合并到一个always块中<代码>始终@(posedge clk)用于同步复位(FPGA重新开始)<代码>始终@(posedge clk或negedge nrst)用于异步复位(对于ASIC重新开始)

在组合块中指定灵敏度是老式的,仅在1995年版中需要。自2001年以来,自动选择(
always@*
或同义的
always@(*)
)是启动组合块的完美方式。模块标题样式建议