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

D1 测试代码

`timescale 1ns / 1ps
module test_fifo(

    );
reg sys_clk, sys_rst_n;
initial sys_clk=0;
always #10 sys_clk=~sys_clk;

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

reg [7:0] din;
reg wr_en, rd_en;    
wire [7:0] dout;

initial begin
    din=8'h00;
    wr_en=0;
    rd_en=0;

wait(sys_rst_n==1);
# 1000;

while(full==0) 
    @(posedge sys_clk) begin
        #1;
        wr_en=1;
        din=din+1;
    end
    
//@(posedge sys_clk) begin
//    #1;
//    wr_en=1;
//    din=din+1;
//end    

wr_en=0;

# 1000;

while(empty==0) 
    @(posedge sys_clk) begin
        #1;
        rd_en=1;
    end
    
//@(posedge sys_clk) begin
//    #1;
//    rd_en=1;
//end    
    
rd_en=0;    

end
    
fifo_generator_0 your_instance_name (
  .clk(sys_clk),              // input wire clk
  .rst(~sys_rst_n),              // input wire rst
  .din(din),              // input wire [7 : 0] din
  .wr_en(wr_en),          // input wire wr_en
  .rd_en(rd_en),          // input wire rd_en
  .dout(dout),            // output wire [7 : 0] dout
  .full(full),            // output wire full
  .overflow(overflow),    // output wire overflow
  .empty(empty),          // output wire empty
  .valid(valid),          // output wire valid
  .underflow(underflow)  // output wire underflow
);    
endmodule

D2 正常读写波形,看full/empty信号行为

写开始部分

写结束部分

读开始部分

读结束部分

因此:

  1. 写入是值是1,2,3....255,0
  2. 第一个写时钟拉高,过一个周期后empty信号拉高
  3. 最后一个写时钟拉高,full信号立即拉高,没有延时。
  4. 读出的值是1,2,3...255,0
  5. 第一个读时钟拉高后,dout立即产生,full立即拉低,valid信号立即拉高
  6. 最后一个读时钟拉高后,empty信号立即拉高。valid信号要过一个周期后变低
  7. 注意full/empty这2个关键信号:在初始和结束,都是立即拉高的。
  8. din/dout也是随时钟上升沿立即产生的

D3 多写一个周期,多读一个周期,看overflow/underflow信号行为

写结束部分

读结束部分

可以看到:

  1. 多写一个周期,overflow是立即拉高的
  2. 多读一个周期,underflow是立即拉高的

D4 关于First Word Fall Through

可以看到,这种模式,第一个数据不读也是呈现在输出端。当发第一个读时钟,实际上读到的是第2个数据。