4.异步fifo
(1)从最简单开始,读和写分别为两个独立时钟,读写位宽比为1:2,读写频率比为2:1
module ID_fifo(wr_clk,rd_clk,din,wr_en,rd_en,dout,full,empty,valid);
input wr_clk;
input rd_clk;
input [7:0] din;
input wr_en;
input rd_en;
output [3:0] dout;
output full;
output empty;
output valid;
fifo_8_16 f0 (
.wr_clk(wr_clk), // input wire wr_clk
.rd_clk(rd_clk), // input wire rd_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 [3 : 0] dout
.full(full), // output wire full
.empty(empty),
.valid(valid) // output wire empty
);
endmodule
module tb_ID_fifo;
reg wr_clk,rd_clk;
reg [7:0] din;
reg wr_en,rd_en;
wire [3:0]dout;
wire full,empty,valid;
initial begin
wr_clk=1'b0;
rd_clk=1'b0;
wr_en=1'b1;
rd_en=1'b0;
din=8'h00;
#20//开始读取
wr_en=1'b1;
rd_en=1'b1;
end
always #10 wr_clk=~wr_clk;
always #5 rd_clk=~rd_clk;
always #20 din = din + 1'b1;
ID_fifo i0(
.wr_clk(wr_clk),
.rd_clk(rd_clk),
.din(din),
.wr_en(wr_en),
.rd_en(rd_en),
.dout(dout),
.full(full),
.empty(empty),
.valid(valid)
);
endmodule
分别设置读取的时间为20,40,60,80,行为级仿真如下所示:
注意看empty信号,对于同步fifo,在写入使能的第1个上升沿到来时,empty就置零,这一点与同步fifo有很大的不同!!异步fifo只在读时钟的某一个上升沿到来时,empty置零;也就是说,empty拉高的持续时间为读时钟周期一半的整数倍!!
(2)设置读写位宽比为1:2
读写时钟频率比为1:1
一开始empty拉高的写周期为5个,并不是前面的3个,但是读操作依然是在empty=0的下一个读上升沿到来时才能进行!!
读写时钟频率比为4:3
empty一开始拉高的持续周期数没弄明白?
读写时钟频率比为3:4
出现full=1的情况;
连续轮换进行读和写
可以看出,在后续的读过程中,在读取完最后一个数的同时empty被拉高;这个和同步fifo是一致的