此篇是我在学习中做的归纳与总结,其中如果存在版权或知识错误请直接联系我,欢迎留言。
PS:本着知识共享的原则,此篇博客可以转载,但请标明出处!
目录
Standard FIFO与First-word-Fall-Through(FWFT)区别:
引言:
下面介绍一个 XPM_FIFO 实例的基本读写操作。
• 所有同步信号都对wr_clk 的上升沿敏感,它被假定为根据目标设备和FIFO/存储器原语要求运行的缓冲和切换时钟信号。
• 当FIFO 未满且wr_en 在每个wr_clk 周期置位时执行写操作。
• 当FIFO 不为空且rd_en 在每个wr_clk 周期被置位时,执行读操作。
• XPM FIFO 对 Dout、满和空变化做出反应所需的时钟周期数取决于 CLOCK_DOMAIN、READ_MODE 和 FIFO_READ_LATENCY 设置。
– 写操作(wr_en = 1),可能需要一个以上的 wr_clk 周期才能将空置为无效。
– rd_en 置位时,可能需要一个以上的 wr_clk 周期才能在 Dout 端口上呈现读取数据。
– 读操作 (rd_en = 1),可能需要 1 个以上的 wr_clk 周期才能解除完全置位。
• 所有写操作都由 wr_en 的值进行门控,并且在启动 wr_clk 周期时为 full。
• 所有读取操作都由 rd_en 的值进行门控,并且在启动 wr_clk 周期时为空。
关键参数说明:
详情可参照Xilinx UG974文档
参数名称 | 默认值 | 说明 |
DOUT_RESET_VALUE | 0 | 读取数据路径复位值 |
ECC_MODE | no_ecc | |
FIFO_MEMORY_TYPE | auto | |
FIFO_READ_LATENCY | 1 | 读取数据路径中的输出寄存器级数 如果 read _ mode = “ fwft”,那么唯一适用的值是0 |
WAKEUP_TIME | 0 | • 0 - Disable sleep • 2 - Use Sleep Pin |
READ_MODE | "std" | "std" "fwft", |
使用说明:
Standard FIFO与First-word-Fall-Through(FWFT)区别:
在vivado中例化fifo的IP核的时候,在native ports部分有两种模式可以选择,对于XPM_FIFO也同样适用,如下图所示:
当选择Standard模式、FIFO_READ_LATENCY = 1时,在读使能信号有效的下一个周期才能读出第一个有效的数据;
当选择FWFT模式的时候,在读使能信号有效的第一个周期就能能读出第一个有效的数据; 这是因为在这种模式下,FIFO提前把数据已经准备到了数据输出总线上,等待都使能有效就输出到数据输出端口(组合逻辑),但在这种模式下,valid信号将会在复位后就保持有效,这一点要特别注意;
(FIFO_READ_LATENCY:读取数据路径中的输出寄存器级数,如果 READ_MODE = "fwft",则唯一适用的值为 0 )
下图中:READ_MODE = “std” ; FIFO_READ_LATENCY = 2
(OutPreDe为读FIFO使能信号,RdFIFOData为FIFO读出信号)
ILA抓取实际波形为 延时2Clk输出
下图中:READ_MODE = “std” ; FIFO_READ_LATENCY = 1
ILA抓取实际波形为 延时1Clk输出
Memory Type :
常用的有Block Ram 和 Distrubtion RAM ,前者使用片上ROM作为缓存,后者使用LUT逻辑资源搭建RAM缓存,如果使用FIFO不大,或者资源充足的情况下,使用Block RAM。
参考代码段:
xpm_fifo_sync #(
.DOUT_RESET_VALUE ("1" ), // String
.ECC_MODE ("no_ecc" ), // String
.FIFO_MEMORY_TYPE ("auto" ), // String
.FIFO_READ_LATENCY (1 ), // DECIMAL
.FIFO_WRITE_DEPTH (FIFO_DEPTH ), // DECIMAL
.FULL_RESET_VALUE (0 ), // DECIMAL
.PROG_EMPTY_THRESH (10 ), // DECIMAL
.PROG_FULL_THRESH ((FIFO_DEPTH>>1) ), // DECIMAL
.RD_DATA_COUNT_WIDTH (FIFO_RDWR_CNT_WIDTH ), // DECIMAL
.READ_DATA_WIDTH (24 ), // DECIMAL
.READ_MODE ("std" ), // String
.USE_ADV_FEATURES ("0707" ), // String
.WAKEUP_TIME (0 ), // DECIMAL
.WRITE_DATA_WIDTH (24 ), // DECIMAL
.WR_DATA_COUNT_WIDTH (FIFO_RDWR_CNT_WIDTH ) // DECIMAL
)
xpm_fifo_sync_24x128 (
.almost_empty ( ) ,
.almost_full ( ) ,
.data_valid ( ) ,
.dbiterr ( ) ,
.dout ( RdFiFoData ) ,
.empty ( ) ,
.full ( ) ,
.overflow ( ) ,
.prog_empty ( ) ,
.prog_full ( FIFOProgFull ) ,
.rd_data_count ( ) ,
.rd_rst_busy ( ) ,
.sbiterr ( ) ,
.underflow ( ) ,
.wr_ack ( ) ,
.wr_data_count ( ) ,
.wr_rst_busy ( ) ,
.din ( WrFiFoData ) ,
.injectdbiterr ( 1'b0 ) ,
.injectsbiterr ( 1'b0 ) ,
.rd_en ( RdFiFoEn ) ,
.rst ( SysRst ) ,
.sleep ( 1'b0 ) ,
.wr_clk ( OutPclk ) ,
.wr_en ( WrFiFoEn )
);