bram读写测试时序分析 - minichao9901/TangNano-20k-Zynq-7020 GitHub Wiki

D1 代码

`timescale 1ns / 1ps
module test_bram(

    );
reg clka, clkb, rstn;
initial clka=0;
always #10 clka=~clka;
initial clkb=0;
always #20 clkb=~clkb;

initial begin
    rstn=0;
    #1000;
    rstn=1;
end 

reg [15:0] dina;
reg [7:0] addra;
reg wea;
wire [15:0] douta;

reg [15:0] dinb;
reg [7:0] addrb;
reg web;
wire [15:0] doutb;

initial begin
    dina=16'h0000;
    addra=8'h00;
    wea=0;  

wait(rstn==1);
# 1000;

repeat(256)
    @(posedge clka) begin
        #1;
        wea=1;
        addra=addra+1;
        dina=dina+1;
    end
    
wea=0;

end


initial begin
    dinb=16'h0000;
    addrb=8'hff;
    web=0;    

wait(addra>=128);

repeat(256)
    @(posedge clkb) begin
        #1;
        addrb=addrb+1;
    end
    
wea=0;

end
    
blk_mem_gen_0 your_instance_name (
  .clka(clka),    // input wire clka
  .wea(wea),      // input wire [0 : 0] wea
  .addra(addra),  // input wire [7 : 0] addra
  .dina(dina),    // input wire [15 : 0] dina
  .douta(douta),  // output wire [15 : 0] douta
  .clkb(clkb),    // input wire clkb
  .web(web),      // input wire [0 : 0] web
  .addrb(addrb),  // input wire [7 : 0] addrb
  .dinb(dinb),    // input wire [15 : 0] dinb
  .doutb(doutb)  // output wire [15 : 0] doutb
); 
endmodule

这里Operating Mode有3种:write first, read first, no change。 如果write first/read first模式,在写的时候,dout也会有输出。只要addr变化,dout就会变化。 如果no change,则写的时候,dout不会变化。这个是符合期望的。

如果2项都勾选,延迟3拍。如果只勾选1项,延迟2拍。如果都不勾选,延迟1拍。

D2 仿真波形(勾选Primitive Output Register,读延迟2拍)

写开始。可以看到,写的第1个地址是 0x01地址,写入的数据是0x0001。 也就是,0x00地址其实是没有写入的,是默认值。

写结束。写入的最后一个数据,地址是0xff,写入的数据是0x00ff。

读开始。由于读延迟2个cycle。可以看到读出的第一个数据是,地址是0x00,值是0x0000。这个地址内容不是写入的,是默认值。 读入的第二个数据,地址是0x01,值是0x0001。这个地址内容是写入的。

读结束。由于读延迟2个cycle。可以看到读的最后一个数据,地址是0xff,值是0x00ff。

D3 (都不勾选,读延迟1拍)

读开始

读结束

可以看到,结果确实是延一拍输出。

D4 总结

  • 在数字电路中,所谓的延迟一拍输出,其实就是DFF输出。它就是:在时钟的上升沿,立即输出。
  • 延迟2拍输出,就是DFF+DFF输出。它就是,在时钟的上升沿不输出,再到下个上升沿输出。