FPGA开发——IP核的FIFO调用

一、简介

FIFO 的英文全称是 First In First Out,即先进先出。 FPGA 使用的 FIFO 一般指的是对数据的存储具有先进先出特性的一个缓存器,常被用于数据的缓存或者高速异步数据的交互,也即所谓的跨时钟域信号传递。它与 FPGA 内部的 RAM 和 ROM 的区别是没有外部读写地址线,采取顺序写入数据,顺序读出数据的方式,使用起来简单方便,由此带来的缺点就是不能像 RAM 和 ROM 那样可以由地址线决定读取或写入某个指定的地址。

1、FIFO分类

FIFO 从输入时钟的角度来分,有两种类型:单时钟 FIFO(SCFIFO)和双时钟 FIFO (DCFIFO);其中,双时钟 FIFO 又可从输出数据的位宽的角度,分为普通双时钟(DCFIFO)和混合宽度双时钟 FIFO(DCFIFO_MIXED_WIDTHS)。单时钟 FIFO 具有一个独立的时钟端口 clock,因此,所有的输入输出信号都同步于 clock 信号。双时钟 FIFO结构中,写端口和读端口分别有独立的时钟,所有与写相关的信号都是同步于写时钟wrclk,所有与读相关的信号都是同步于读时钟 rdclk。

2、同步FIFO和异步FIFO 原理图

3、单时钟 FIFO 和双时钟 FIFO 的应用场景

单时钟 FIFO 常用于同步时钟的数据缓存;

双时钟 FIFO 常用于跨时钟域的数据信号的传递,例如时钟域 A 下的数据 data1 传递给异步时钟域 B,当 data1 为连续变化信号时,如果直接传递给时钟域 B 则可能会导致收非所送的情况,即在采集过程中会出现包括亚稳态(数据采样失真)问题在内的一系列问题,使用双时钟 FIFO 能够将不同时钟域中的数据同步到所需的时钟域中。

二、FIFO的配置

1、FIFO的选择

如图所示,在 IP Catalog 的搜索栏中搜索 FIFO,然后选择 FIFO。(这里和前面调用的pll一样也是需要先进行工程创建,不清楚的小伙伴可以在前面的文章看看)

2、 FIFO存放位置的选择

3、fifo存储容量和同步时钟设置

如下图所示,该界面配置的参数有:

方框①:fifo的数据存储容量

方框②:fifo读写的时钟选择,Yes选项是读写时钟同一个时钟,No是读写使用不同的时钟,这里看自己需要进行选择。在本篇文章中默认使用同一个时钟。然后点击 Next 进入下一界面。

4、控制信号的选择

如下图所示,该界面配置的参数有:

方框①:这里是满信号------full、空信号------empty、fifo剩余容量信号------usedw的选择,这里一般我们不用选,系统默认就已经选择好了,如果没有就自行勾选。

方框②:也是满信号的设置,只不过这里和上面一个的区别就是这个信号是容量接近满的状态,这样可以给fifo留有缓冲的容量,避免数据出错。不做要求一般不选

方框③:这里是空信号的设置,当fifo剩余容量少于某个值时,系统就认为是空,这里和②一样一般也是默认不选。

方框④:这里就是数据清除的选择,第一个选想是异步清除,第二个选项是同步清除。这里我们默认选择异步清除。然后点击 Next 进入下一界面。

5、fifo显示模式的选择

如下图所示,该界面配置的参数有:

方框①:这里是fifo显示模式的选择,认为普通模式和前显模式,如果需要实时读写的话就选择第一个普通模式,如果是对已经存在的数据进行一个读取或者修改的话就选择第二个前显模式。

方框②:这里是fifo构建资源的选择,一般默认就行。然后点击 Next 进入下一界面。

6、最大输出的寄存器选择

这里因为需要占用额外的资源,所以一般选择No。

7、仿真工具文件的选择

8、 生成文件的选择

如下图所示,该页面为需要配置生成的文件。勾选fifo_inst.v 即可。rfifo_bb.v 可勾可不勾选。然后点击 finish。

9、将文件添加到工程中

如下图所示,配置完成,点击"Yes"即可。

三、FIFO的调用

1、设计文件的编写

在rtl文件夹中新建ip_fifo.v文件,其中ram实例化代码可以从 fifo_inst.v 例化模板文件复制。如图:

cpp 复制代码
module ip_fifo (
    input clk,
    input rst_n,
	input [7:0] data,
	input rden,
	input wren,
	output empty,
	output full,
	output [7:0] q,
	output [7:0] usedw
);
wire rdreq;
wire wrreq;
fifo	fifo_inst (
	.aclr ( ~rst_n ),//复位
	.clock ( clk ),//时钟
	.data ( data ),//输入数据
	.rdreq ( rden ),//读有效信号
	.wrreq ( wren ),//写有效信号
	.empty ( empty ),//空标志位
	.full ( full),//满标志位
	.q 	  ( q ),
	.usedw ( usedw )//FIFO 中剩余的数据量
	);


endmodule

2、测试文件的编写

cpp 复制代码
`timescale 1ns/1ns
module fifo_tb();

reg clk     ; 
reg rst_n   ; 
reg [7:0] data    ; 
reg rden    ; 
reg wren    ; 
wire empty   ; 
wire full    ; 
wire [7:0] q      ;
wire [7:0] usedw  ;

ip_fifo ip_fifo_inst(
    /*input        */ .clk   (clk   )  ,
    /*input        */ .rst_n (rst_n )  ,
	/*input [7:0]  */ .data  (data  )  ,
	/*input        */ .rden  (rden  )  ,
	/*input        */ .wren  (wren  )  ,
	/*output        */ .empty (empty )  ,
	/*output        */ .full  (full  )  ,
	/*output [7:0] */ .q     (q     )  ,
	/*output [7:0] */ .usedw (usedw )
    );
//时钟
parameter  CLK_CLY =20 ;
initial clk=0;
always #(CLK_CLY/2) clk=~clk;

integer i;
//复位
initial begin
    rst_n =1'b0;
    data = 0;
    wren = 0;
    rden = 0;
    #(CLK_CLY*2);
    #3;
    rst_n=1'b1;
    #(10*CLK_CLY);
    //开始赋值
    for(i=0;i<512;i=i+1)begin
        data = {$random};
        wren = 1'b1;
        #(1*CLK_CLY);
        wren = 1'b0;
    end
    #(100*CLK_CLY);

     for(i=0;i<200;i=i+1)begin
        rden = 1'b1;
        #(1*CLK_CLY);
        rden = 1'b0;
    end 
end

endmodule


                                                   

3、波形仿真

通过波形图和mendata我们可以看到数据已经成功写入且成功读出。调用到此结束。

相关推荐
热爱生活的五柒3 小时前
vscode利用ofExtensions插件可以调试单进程Openfoam,但是不能调试mpi多进程案例
ide·vscode·编辑器
小陈phd3 小时前
Vscode LinuxC++环境配置
linux·c++·vscode
为什么每天的风都这么大13 小时前
Vscode/Code-server无网环境安装通义灵码
ide·vscode·阿里云·编辑器·ai编程·code-server
ahadee16 小时前
蓝桥杯每日真题 - 第19天
c语言·vscode·算法·蓝桥杯
fei_sun17 小时前
【Verilog】第一章作业
fpga开发·verilog
深圳市雷龙发展有限公司longsto17 小时前
基于FPGA(现场可编程门阵列)的SD NAND图片显示系统是一个复杂的项目,它涉及硬件设计、FPGA编程、SD卡接口、NAND闪存控制以及图像显示等多个方面
fpga开发
写点什么啦19 小时前
[debug]不同的window连接ubuntu的vscode后无法正常加载kernel
linux·vscode·ubuntu·debug
hence..19 小时前
Vscode写markdown快速插入python代码
ide·vscode·python
ahadee19 小时前
蓝桥杯每日真题 - 第18天
c语言·vscode·算法·蓝桥杯
陌上阳光21 小时前
vscode连接远程开发机报错
ide·vscode·编辑器