使用相同vivado block ram IP的模拟矛盾[已解决]

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

感谢@ImGroot,问题已经解决了。

当我尝试在两个不同的测试平台中测试我的定制 Vivado block ram IP 时,我得到了矛盾的结果。

内存配置

生成的RAM是一块具有本机接口的16x255 True Dual Port Ram(端口A和端口B)。原语输出寄存器和 RST 信号可用于两个端口。此外,操作模式也没有变化。图 1 和图 2 分别提供了端口配置和 IP 摘要。

图 1. 端口配置:

图2.IP摘要:

测试台A

Testbench A 是一个简单直观的测试平台,其中所有内容(控制信号、输入数据和 I/O 地址)都是手动提供的。

module tb_blk_mem_1();
    reg rst, clk, clkb;
    reg blk_mem_wen, blk_mem_ren;
    wire wrst_busy, rrst_busy;
    reg [7:0] waddr_0, raddr_0;
    reg [15:0] din_0;
    wire [15:0] dout_0;
    reg ena;
    
    always begin
        #10 clk = ~clk;
    end
    
    always begin
        #10 clkb = ~clkb;
    end 
    
    initial begin
        clk = 1; rst = 1; blk_mem_wen = 0; blk_mem_ren = 0; waddr_0 = 255; raddr_0 = 3; din_0 = 65535;clkb = 1; ena = 1;
        #40 rst = 0;
        #180 blk_mem_wen = 1; 
        #20 din_0 = 1; waddr_0 = 0;
        #20 blk_mem_wen = 1; waddr_0 = 1; din_0 = 2;
        #20 blk_mem_wen = 1; waddr_0 = 2; din_0 = 3;
        #20 blk_mem_wen = 1; waddr_0 = 3; din_0 = 4;
        #20 blk_mem_wen = 0;ena = 0;
        #200 blk_mem_ren = 1; raddr_0 = 0;
        #20 blk_mem_ren = 1; raddr_0 = 1;
        #20 blk_mem_ren = 1; raddr_0 = 2;
        #20 blk_mem_ren = 1; raddr_0 = 3;
        #20 raddr_0 = 0;
        #20 raddr_0 = 1;

    end
    
    blk_mem_gen_1 blk_mem_gen_1(
        .clka(clk),
        .wea(blk_mem_wen),
        .addra(waddr_0),
        .dina(din_0),
        .douta(),
        .ena(ena),
        .addrb(raddr_0),
        .dinb(),
        .rsta(rst),
        .doutb(dout_0),
        .rstb(rst),
        .enb(blk_mem_ren),
        .web(1'b0),
        .clkb(clkb),
        .rsta_busy(wrst_busy),
        .rstb_busy(rrst_busy)
    );



endmodule

图 3. 测试平台 A 结果:

根据图3可以看出,在提供地址时,Block ram第一次返回数据失败。而且,进一步返回的数据仅延迟 1 个时钟周期而不是 2 个时钟周期。

测试台B

Testbench B 是一个惰性测试程序,地址和数据都会自动提供给块 RAM。地址和数据以累加的方式生成。

module tb_blk_mem();
    wire [15:0] douta, doutb;
    reg clka, clkb;
    reg ena, enb;
    reg wea;
    reg rst;
    wire rsta_busy, rstb_busy;


    wire [15:0] dina;
    wire [7:0] addra, addrb;

    blk_mem_wr blk_mem_wr(
        .wr_clk(clka),
        .rst_busy(rsta_busy),
        .wr_data(dina),
        .wr_addr(addra),
        .wen(wea)
    );

    blk_mem_rd blk_mem_rd(
        .rd_clk(clkb),
        .ren(enb),
        .rst_busy(rstb_busy),
        .rd_addr(addrb)
    );


    blk_mem_gen_1 blk_mem_gen_1(
        .addra(addra),
        .addrb(addrb),
        .dina(dina),
        .dinb(),
        .clka(clka),
        .clkb(clkb),
        .ena(ena),
        .enb(enb),
        .wea(wea),
        .web(),
        .rsta(rst),
        .rstb(rst),
        .douta(),
        .doutb(doutb),
        .rsta_busy(rsta_busy),
        .rstb_busy(rstb_busy)
    );

    always begin
        #10 clka = !clka;
    end
    
    always begin
        #10 clkb = !clkb;
    end
    
    initial begin
        clka = 1; clkb = 1;rst = 1;ena = 1; enb = 0; wea = 0;
        #10 rst = 0; 
        #300 ena = 1'b1; wea = 1'b1;
        #400 wea = 1'b0;ena = 1'b0;
        #50 enb = 1;



        #400 $finish;
    end
endmodule

图 4. 测试平台 B 结果:

根据图 4,块公羊工作得非常好。由于 255 显然大于 150,因此是合法的“X”。

结论

总而言之,我有两个测试平台,A)IP ram 工作不正常,测试结果与 IP 信息不符,而 B)IP ram 工作良好。

我尝试使用不同的块内存,但问题仍然存在。另外,通过比较两个波形图(图3和图4),控制逻辑几乎相同。因此,我预计我的测试平台中存在一些我显然没有意识到的错误。

评论相关图:

  1. 测试平台 A 结果的修正图像

  2. 请求的图像:初始 raddr 被替换

verilog simulation ram vivado test-bench
1个回答
0
投票

我能够重现您的问题。该问题是由测试台提供的输入引起的,因此在时钟的上升沿您会切换所有信号,从而产生竞争条件。简而言之,由于测试平台中的输入是异步驱动的,因此正在创建竞争条件。要详细了解为什么会出现这种竞争情况,您可以查看此答案。在您的测试台上将

clk = 1;
的值更改为
clk = 0;
,将
clkb = 1;
更改为
clkb = 0;
,这样可以防止出现竞争情况。换句话说,从数据输入的转换中稍微移动时钟沿。

由于同样的原因,您的测试平台 B 正在生成正确的结果,因为在测试平台 B 中,您没有驱动来自测试平台的输入。相反,在测试平台 B 中,您从其他两个模块获取输入,并且它们同步向 Block Ram 提供输入。

© www.soinside.com 2019 - 2024. All rights reserved.