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模式相对于标准模式分别增加了两个读深度和写深度;