我看到未定义的输出序列在模拟中读取内存

问题描述 投票:0回答:1

我有一个与时钟 SRAM 存储器的实现相关的问题,该存储器应该存储用户写入的数据,然后显示存储器内容。此外,我创建了一个名为

display
的模块,它简化了读取过程,因此无需通过在每次读取后递增寄存器来提供应从中提取数据的内存地址。然而,当我模拟电路时,我看不到正确的输出;因此,当我读取内存时,我注意到一些未定义的输出序列。我在下面发布了相应的代码。

//stores output data
module sram_1port_data(
    input clk,//clocked memory
    input wr_en,//when high, data is written, otherwise is read
    input [15:0] address_in,//suppose timer cannout count more than 13ms
    input [3:0] wr_data,//memory does not sotre values greater than 13(ms)
    output reg [3:0] rd_data
);

reg [3:0] memory [2 ** 15 - 1 : 0];

always @(posedge clk) begin
    if(wr_en) memory[address_in] <= wr_data;
    else rd_data <= memory[address_in];
end

endmodule

//display interfacedesigned for the second memory
module display(
    input clk,
    input wr_en,
    input [15:0] address_in,
    input [3:0] wr_data,
    output [3:0] rd_data
);

reg [15:0] pointer,address;

initial pointer = 16'd0;

sram_1port_data i0(.clk(clk),.wr_en(wr_en),.address_in(address),.wr_data(wr_data),.rd_data(rd_data));

always @(posedge clk) begin
    if(!wr_en) begin
        address <= pointer;
        pointer <= pointer + 1;
    end 
    else address <= address_in;
end

endmodule

//tb for display
module display_tb(
    output reg clk,
    output reg wr_en,
    output reg [15:0] address_in,
    output reg [3:0] wr_data,
    output [3:0] rd_data
);

display i0(.clk(clk),.wr_en(wr_en),.address_in(address_in),.wr_data(wr_data),.rd_data(rd_data));

initial $dumpvars(0,display_tb);

initial begin
    clk = 1'd1;
    repeat (2000)
    #100 clk = ~clk;
end

initial begin
    wr_en = 1'd1;
    #100000 wr_en = 1'd0;
end

integer i;

initial begin
    wr_data = 3'd0;
    for(i = 1;i < 500;i = i + 1) begin
    #200 wr_data = i;
    end
end

initial begin
    address_in = 16'd0;
    for(i = 1;i < 500;i = i + 1) begin
    #200 address_in = i;
    end
end

endmodule
memory verilog simulation test-bench iverilog
1个回答
1
投票

当我查看波形时,我发现每次读取时

rd_data
都是未知的 (X)。 查看内部地址信号,我发现未知数仅适用于偶数地址。 在模拟的早期,您只写入偶数地址。

在您的测试平台中,您在 2 个不同的

i
循环中使用相同的变量 (
for
)。 在第二个
for
循环中,使用不同的变量名称(例如,
j
):

integer j;
initial begin
    address_in = 16'd0;
    for(j = 1;j < 500;j = j + 1) begin
    #200 address_in = j;
    end
end

现在,所有读取都具有已知值,因为它写入所有地址(偶数和奇数)。


您还可以在与写入数据相同的

for
循环内设置地址。 在这种情况下,这可能是更好的方法。

initial begin
    wr_data    =  3'd0;
    address_in = 16'd0;
    for(i = 1;i < 500;i = i + 1) begin
        #200;
        wr_data    = i;
        address_in = i;
    end
end
© www.soinside.com 2019 - 2024. All rights reserved.