fifo学习(3)

3.fifo IP核的使用

(1)最简单的ip核,不设置复位信号,采用公共时钟;公共时钟FIFO写入读取的位宽比只能是1:1;可以同时读写!

module fifo_ip(clk,din,wr_en,rd_en,dout,full,empty);
 input clk;
 input [7:0] din;//位宽为8位,深度为16
 input wr_en;
 input rd_en;
 output [7:0] dout;
 output full;
 output empty;
 
 fifo_8_16 f0 (
  .clk(clk),      // input wire clk
  .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
  .empty(empty)  // output wire empty
);
endmodule

//tb
module tb_fifo_ip;
 reg clk;
 reg [7:0] din;
 reg wr_en,rd_en;
 wire [7:0] dout;
 wire full,empty;
 
 initial begin
              clk=1'b0;
              din=8'h01;
              wr_en=1'b1;
              rd_en=1'b0;
              #400
              wr_en=1'b0;
              rd_en=1'b1;
              #300
              wr_en=1'b1;
              rd_en=1'b0;
              #200 
              wr_en=1'b0;
              rd_en=1'b1;
         end
         
 always #10 clk = ~clk;
 always #20 din = din + 1'b1;
 fifo_ip t1(.clk(clk),
            .din(din),
            .wr_en(wr_en),
            .rd_en(rd_en),
            .dout(dout),
            .full(full),
            .empty(empty));
endmodule

 

在第16个周期,fifo处于满状态,full置1;

但是,第一次读取只读取到了15,此时又开始写入数据,写入的第一个数据为36,故下一次读取从16开始,第二个读取的数据为36;可以说明在full或者empty拉高时,无论是写入还是读取使能都不会影响fifo中保存的数据!

(2)设置同步复位信号,采用公共时钟

module fifo_ip0(clk,srst,din,wr_en,rd_en,dout,full,empty);
 input clk;
 input srst;
 input [7:0] din;
 input wr_en;
 input rd_en;
 output [7:0] dout;
 output full;
 output empty;
 
 reg [7:0] din1;
 always @(posedge clk)
    begin
         if(srst)
            din1 <= 8'd0;
         else
            din1 <= din;
    end
 
 fifo_8_16_srst f1 (
  .clk(clk),      // input wire clk
  .srst(srst),    // input wire srst复位信号为高电平有效
  .din(din1),      // 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
  .empty(empty)  // output wire empty
);

module tb_fifo_ip0;
 reg clk,srst;
 reg [7:0] din;
 reg wr_en,rd_en;
 wire [7:0] dout;
 wire full,empty;
 
 initial begin
               clk=1'b0;
               srst=1'b1;
               din=8'h01;
               wr_en=1'b1;//写
               rd_en=1'b0;
               #40
               srst=1'b0;
               #400
               wr_en=1'b0;//读
               rd_en=1'b1;
               #300
               srst=1'b1;
               wr_en=1'b1;//写
               rd_en=1'b0;
               #500
               srst=1'b0; 
               wr_en=1'b0;//读
               rd_en=1'b1;
               #200
               wr_en=1'b1;//写
               rd_en=1'b0;
          end
          
  always #10 clk = ~clk;
  always #20 din = din + 1'b1;
  fifo_ip0 t2(.clk(clk),
             .srst(srst),
             .din(din),
             .wr_en(wr_en),
             .rd_en(rd_en),
             .dout(dout),
             .full(full),
             .empty(empty));
endmodule

srst信号有效时,在下一个上升沿来临时empty拉高,上图中在srst信号无效时开始写入,写入的数据为0,3,4....17;

srst有效期间,不管是写入还是读取状态,fifo的输入输出都是0;上图可见在din1为63时进行读取操作,所读出的数为0,且empty为1;

继续写入,写到87时,full拉高;

(3)带输出标志位valid和almost full、almost empty

almost_full总是比full提前一个周期拉高,它拉高表明还可以进行一次写入操作;同时在srst有效的情况下,almost_empty和empty同时拉高;

almost_empty和empty在fifo为空时是同时为1的;valid信号在读使能有效的第1个上升沿拉高,在写入的第1个上升沿到来时置零;

(4)FWFT首字预现fifo

在srst有效时,valid置零;在写使能有效的第3个上升沿到来时拉高,在读使能有效之前且empty不为零就已经处于拉高状态;

写使能只存在2个周期,写入了0和3;valid在90ns拉高,在empty拉高的同时,valid置零;可以说明,在FWFT fifo中valid不能作为数据的输出标志位!!

(5)加入输出缓存寄存器,增加一级延时

在读信号的时钟第2个上升沿到来时才开始读出数据,同时valid拉高;

(6)FWFT+输出缓存寄存器

对FWFT模式的FIFO,加入寄存器对输出并没有增加1个周期的延时,但是对full和almost_full信号有延时,实际上是FWFT模式相对于标准模式分别增加了两个读深度和写深度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值