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输出。它就是,在时钟的上升沿不输出,再到下个上升沿输出。