文章来源:明德扬FPGA科教
一、背景

打开VIVADO软件,点击上图中的Language Templates,将会弹出Language Templates窗口,如下图。

在Language Templates窗口中,依次点击verilog、Xilinx Parameterized Macros(XPM)、XPM、XPM_FIFO,如上图。可以看到有三种FIFO,分别是异步的XPM FIFO:xpm_fifo_async、AXI总线的FIFO:xpm_fifo_axis和同步的XMP FIFO:xpm_fifo_sync。

选择xpm_fifo_async,右边的Preview窗口,将出现xpm_fifo_async的注释以及参考代码。将此部分代码拷出来,并将注释删除,剩下的是xpm_fifo_async的例化参考。

上图是对xpm_fifo_async的参数例化部分。下面是需要重点关注并经常使用的参数。
- FIFO_WRITE_DEPTH:FIFO的写深度,其实就是在这里设置FIFO的深度,注意该值通常是2的N次方,如8、16、32、64等数。 
- PROG_EMPTY_THRESH:FIFO的快空的水线。当FIFO存储的数据量小于该水线时,FIFO的快空信号将会变高。 
- PROG_FULL_THRESH:FIFO的快满的水线。当FIFO存储的数据量大于该水线时,FIFO的快满信号将会变高,表示有效。 
- READ_DATA_WIDTH:读数据的位宽。 
- WRITE_DATA_WIDTH:将数据的位宽。 
- RD_DATA_COUNT_WIDHT:读侧数据统计值的位宽。 
- WR_DATA_COUNT_WIDTH:写侧数据统计值的位宽。 

上图是对xpm_fifo_async的接口信号部分。下面是需要重点关注并经常使用的信号。
- wr_clk:FIFO的写时钟 
- rst:FIFO的复位信号,高电平有效。要注意的是,该信号是属于写时钟域的。 
- wr_en:FIFO的写使能信号。 
- din:FIFO的写数据 
- full:写满指示信号,当FIFO写满时,该信号变高。 
- wr_data_count:FIFO存储数据量指示信号,用来指示当前FIFO已经写入但未读出的数据个数。 
- rd_clk:FIFO的读时钟。 
- rd_en:FIFO的读使能。 
- dout:FIFO读出的数据。 
- empty:FIFO的空指示信号。当其为1表示FIFO处于空状态,当其为0,表示FIFO内有数据。 
三、定义自用的FIFO模块
从第二步可以看出,xpm_fifo_async是可以参数化深度和位宽的。但xpm_fifo_async有很多参数和信号,并且其中有部分是不使用的。为了使用上的方便,可以自定义自用的FIFO模块。
例如,明德扬就定义了一个模块mdyFifoAsy,该信号的接口信号如下图。可以看出,名称更加规范,并且定义常用的信号,如读时钟rd_clk,写时钟wrclk、写使能wrreq等信号。

明德扬还在模块mdyFifoAsy定义了一些常用的参数,分别是FIFO深度参数:DEPT_W;FIFO位宽的参数:DATA_W,还有FIFO快满参数AL_FUL和快空参数AL_EMP,如下图。

接下来,就是在mdyFifoAsy中例化并使用xpm_fifo_async了。如下图,就是对xpm_fifo_async的参数例化。将DEPT_W传给FIFO_WRITE_DEPTH,DATA_W传给READ_DATA_WIDTH等。

下图是对xpm_fifo_async的信号例化。将不用的信号留空,将dout连到q,din连到data,wr_en连到wrreq等。您可以根据自己情况来定制FIFO。

四、应用
定制完自己的FIFO后,就可以直接例化使用了。

上图就是使用了一个位宽为8,深度为256的FIFO。

上图就是使用了一个位宽为18,深度为1024的FIFO。
FIFO是FPGA、芯片设计中,最常用的IP核,在存储控制、算法实现、接口设计中,都少不了FIFO,因此合理并正确使用FIFO的技术就非常有必要了,明德扬录制了FIFO的训练视频,掌握后技术能力将有大提升。
通过上面介绍可知,通过此种方式,再也不用生成FIFO IP核啦,整个工程大小基本上可以减少一大半。
上面举的例子是xpm_fifo_async,同步FIFO:xpm_fifo_sync的使用方法是类似的。