FIFO广泛应用于不同时钟域之间的数据传输或不同数据宽度之间的数据匹配。在实际工程应用中,可以根据需要编写自己的FIFO。不考虑资源,也可
FIFO广泛应用于不同时钟域之间的数据传输或不同数据宽度之间的数据匹配。在实际工程应用中,可以根据需要编写自己的FIFO。不考虑资源,也可以使用Xilinx提供的IP核。
接口类型为原生,也可以根据需要在SOC芯片上选择AXI接口。
选择存储器类型:FIFO可以用块RAM、分布式RAM、移位寄存器、嵌入式FIFO来实现。这主要是块RAM和分布式RAM的区别。简而言之,块ram是FPGA中定制的RAM资源,而分布式RAM是由LUT组成的RAM资源。这种差异表明,当FIFO较大时,应选择块RAM;当FIFO较小时,应选择分布RAM。另外很重要的一点是,block RAM支持不同宽度的读写,distribute不支持。这里为了对FIFO有更全面的了解,选择了块RAM具有非对称方向速度的特点,内置FIFO只存在于5片以上的FPGA芯片中。
时钟:读写操作是否在同一个时钟域内完成。如果是,可以选择普通时钟;否则,您可以选择独立的clcoks。
阅读模式有两种选择,一般选择标准模式。首字Fall-FH through模式是前缀预览,FWFT是指在不影响FIFO读操作的情况下,提前查看下一个数据的能力。也就是说,FIFO不为空,当有可用数据时,FIFO中的第一个数据自动出现在输出总线DOUT上。
同步阶段:通过跨时钟域的同步状态(寄存器)数;默认就够了。
在数据端口参数处,有实际写入深度和实际读取深度,这两个深度都比我们设置的要小。在实际工程应用中,FIFO的深度确实比预置的要小,也就是在写Width-1数据时,FIFO的满信号会被拉高。此时,如果要写入数据,写入的数据将会丢失。同样,读取-1数据后,FIFO的空信号会被拉高,此时读取信号无效。如下所示:
FIFO的数据深度为16,从aabb0002至aabb0011写入16个数据。当写入第15个数据时,FULL信号被拉高,数据无法有效写入,从读取状态可以看出。当读取和写入数据位宽不匹配,且写入的位宽大于读取数据的位宽时,首先从高位开始读取;当写入数据的位宽小于读取数据的位宽时,首先写入的数据位于读取数据的高位,如下所示:
关于FIFO复位,Xilinx FIFO默认为高电平复位。初始化时,满、几乎满、prog满等信号的复位值可设置为0或1。可设置读写同步复位或异步复位。复位fifo需要一些时间,在此期间,wr_rst_busy和rd_rst_busy信号处于高电平。此时禁止读写FIFO,否则数据会丢失。
至于读和写计数,读计数与读时钟同步,写计数与写时钟同步。读取计数是基于读取数据宽度的fifo中的数据数量;写计数是基于写数据宽度的fifo中的数据数量。这两个值的结果简单理解为fifo内部控制器的读写地址之差。由于fifo的读写时钟可能是异步的,读写时钟的频率不同,所以在计算读写计数值时存在延迟,与读写操作不完全同步。
读写计数的模拟结果如下:
关于读写使能,当写使能wr_en为高电平时,数据将立即写入fifo,当读使能为高电平时,有效数据将在下一个时钟周期出现在数据总线dout上。
一个简单的模拟如下:
`时间刻度1纳秒/1秒
模块tb_fifo_16x256(
);
reg rst
寄存器wr _ clk
reg rd _ clk
reg[31:0]din;
reg wr _ en
reg rd _ en
wire[15:0]dout;
电线满了;
线空;
电线有效;
电线快满了;
线材几乎_空;
wire[4:0]rd _ data _ count;
wire[3:0]wr _ data _ count;
wire wr _ rst _ busy
电线rd _ rst _ busy
总是# 10 wr _ clk=~ wr _ clk
always # 5 rd _ clk=~ rd _ clk
初始开始
rst=1;
wr _ clk=0;
rd _ clk=1;
din=32 ' haabb0001
wr _ en=0;
rd _ en=0;
#20;
rst=0;
#300;
//===========================空
repeat(16) @(posedge wr_clk)
开始
din=din 1;
wr _ en=1;
结束
重复(1)@(pos edge wr _ clk)wr _ en=0;
repeat(32) @(posedge rd_clk)
开始
rd _ en=1;
结束
重复(1)@(pos edge rd _ clk)rd _ en=0;
//==============================满
repeat(16) @(posedge wr_clk)
开始
din=din 1;
wr _ en=1;
结束
重复(1)@(pos edge wr _ clk)wr _ en=0;
结束
初始开始
#900;
repeat(32) @(posedge rd_clk)
开始
rd _ en=1;
结束
重复(1)@(pos edge rd _ clk)rd _ en=0;
结束
fifo_16x256 fifo_16x256_inst(。rst(rst),//输入线英特尔的快速储存技术。wr_clk(wr_clk),//输入线工作时钟。rd_clk(rd_clk),//输入线rd_clk。din(德国工业标准),//输入线[31 : 0]晚餐。wr_en(wr_en),//输入线工作时间。rd_en(rd_en),//输入线rd_en。dout(dout),//输出线[15 : 0] dout。完整(满),//输出线满。几乎_满(几乎_满),//输出线几乎_满。空(空),//输出线空。几乎_空(几乎_空),//输出线几乎_空。有效(有效),//输出线有效。rd_data_count(rd_data_count),//输出线[8:0]rd _数据_计数。wr_data_count(wr_data_count),//输出线[7 : 0]工作数据计数。wr_rst_busy(wr_rst_busy),//输出线工作繁忙。rd_rst_busy(rd_rst_busy) //输出线rd _ rst _忙碌
);
末端模块
审核彭静
声明本站所有作品图文均由用户自行上传分享,仅供网友学习交流。若您的权利被侵害,请联系我们