0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

FIFO IP核的使用教程

FPGA设计论坛 来源:CSDN威廉希尔官方网站 社区LuBake 2025-01-03 09:36 次阅读

引言

在数字设计中,利用FIFO进行数据处理是非常普遍的应用,例如,实现时钟域交叉、低延时存储器缓存、总线位宽调整等。下图给出了FIFO生成器支持的一种可能配置。

b6ad08ce-c8ce-11ef-9310-92fbcf53809c.png

设计中有两个独立的时钟域并且读数据总线的位宽是写数据总线位宽的2倍。使用FIFO生成器可以快速实现这种配置,从而在Xilinx FPGA芯片上实现特定的设计要求。

实际应用案例:本案例背景是将信号处理系统中ADC采集到的数据写入FPGA芯片外挂的DDR3,完成采样数据的存储。ADC采样率设定为96Mhz,两个采样点(两个16bit数据拼接成一个32bit)为单位,DDR读写时钟速率为150Mhz,总线数据位宽64bit,二者时钟域、位宽均不同,故需在中间加入一级FIFO,从而实现时钟域的交叉以及总线位宽的调整。

下面将从FIFO IP核的创建,模块程序编写,功能仿真验证等三个方面完成本案例的介绍:

1)FIFO IP核的创建:打开Vivado软件(本例程基于Vivado 2018.3版本)IP catalog一栏,输入FIFO,双击进入如下界面,第一个Basic选项卡主要是设置FIFO接口类型,可设置为正常的Native模式或AXI总线接口,一般我们选择Native即可。然后选择FIFO实现的类型:读写使用独立时钟还是同一时钟,实现时使用分布式RAM、Block RAM还是专用的FIFO等等,这里我们选择Independent Clocks Block RAM,即独立时钟块RAM的FIFO。

b6b44080-c8ce-11ef-9310-92fbcf53809c.png

切换至第二个Native Ports选项卡,这个界面主要是设置读写数据位宽、深度以及一些端口的使能、端口复位值等的设置。结合本案例的应用,设置写位宽为32bit,深度设置为1024,读位宽设置为64bit。使能复位管脚,设置满信号(Full Flags)的复位值为0,读数据(Dout)复位值为0。

b6cd359a-c8ce-11ef-9310-92fbcf53809c.png

然后切换至第三个Status Flags选项卡,本选项卡是设置其余一些可选的标志信号,本案例需使用本界面下的Programmable Flags,即可编程的标志信号,设置满标志门限置位值(Full Threshold Assert Value),可使FIFO写入的数据总数大于等于该值后将prog_full(可编程满标志信号)拉高,相比full信号使用起来更灵活。DDR读写采用Burst方式(突发传输),一次连续写入256个数,这里设置Full Threshold Assert Value为512(256*2,2是FIFO读写位宽的比值),当FIFO写入512个数后,prog_full拉高,进行FIFO读操作,一次连续读256个64bit的数(对应写的512个32bit数)存入DDR。

b6e399f2-c8ce-11ef-9310-92fbcf53809c.png

切换至第四个Data Counts选项卡,本选项卡主要是选择是否使用读写数据计数,本案例不使用计数,此页面保持默认设置。

b6f7db1a-c8ce-11ef-9310-92fbcf53809c.png

最后Summary选项卡是FIFO设置后的各项信息,可核对FIFO设置是否正确及设计是否满足要求。

b714d850-c8ce-11ef-9310-92fbcf53809c.png

2)模块程序的编写

顶层模块:FIFO_test.v

module FIFO_test(

input rst,

input wr_clk,

input rd_clk,

input [31:0] din,

input wr_en,

input rd_en,

output [63:0] dout,

output full,

output empty,

output prog_full,

output wr_rst_busy,

output rd_rst_busy

);

fifo_generator_0 U_fifo (

.rst(rst), // input wire rst

.wr_clk(wr_clk), // input wire wr_clk

.rd_clk(rd_clk), // input wire rd_clk

.din(din), // input wire [31 : 0] din

.wr_en(wr_en), // input wire wr_en

.rd_en(rd_en), // input wire rd_en

.dout(dout), // output wire [63 : 0] dout

.full(full), // output wire full

.empty(empty), // output wire empty

.prog_full(prog_full), // output wire prog_full

.wr_rst_busy(wr_rst_busy), // output wire wr_rst_busy

.rd_rst_busy(rd_rst_busy) // output wire rd_rst_busy

);

endmodule

TestBench模块:FIFO_sim

module FIFO_sim;

reg rst;

reg wr_clk;

reg rd_clk;

reg [31:0] din;

reg wr_en;

reg rd_en;

wire [63:0] dout;

wire full;

wire empty;

wire prog_full;

wire wr_rst_busy;

wire rd_rst_busy;

initial begin

rst = 1;

wr_clk = 0;

wr_en = 0;

rd_clk = 0;

rd_en = 0;

din = 0;

#1000

rst = 0;

end

always #10.4167 wr_clk = ~wr_clk;

always #3.3333 rd_clk = ~rd_clk;

always @(posedge wr_clk) begin

if(!wr_rst_busy && !rst) begin

wr_en <= 1'b1;

din <= din + 1'b1;

end

end

reg [1:0] RD_state = 2'b01;

reg [15:0] rd_count = 'd0;

always @(posedge rd_clk) begin

case(RD_state)

2'b01: begin

if(!rd_rst_busy && prog_full) RD_state <= 2'b10;

end

2'b10: begin

if(rd_count >= 'd256) begin

RD_state <= 2'b01;

rd_count <= 'd0;

rd_en <= 1'b0;

end

else begin

rd_count <= rd_count + 1'b1;

rd_en <= 1'b1;  

end

end

default: begin

RD_state <= 2'b01;

end

endcase

end

FIFO_test U_FIFO_test(

.rst(rst),

.wr_clk(wr_clk),

.rd_clk(rd_clk),

.din(din),

.wr_en(wr_en),

.rd_en(rd_en),

.dout(dout),

.full(full),

.empty(empty),

.prog_full(prog_full),

.wr_rst_busy(wr_rst_busy),

.rd_rst_busy(rd_rst_busy)

);

endmodule

编写TestBench时,写时钟为48Mhz,读时钟为150MHz。写是连续的,使能一直打开,表示AD是一直连续工作的,写入够512个数后,prog_full拉高,进行一次FIFO读操作,连续读出256个数,然后等待下一次prog_full为高的到来,如此周而复始。

3)波形功能仿真

点击Run simulation,启动功能仿真,可以看到FIFO一开始复位结束后,进行写操作,每写够512个数后,prog_full拉高,进行一次读操作,连续读出256个数后,停止读操作,等待下一次prog_full拉高时刻的到来。将读出的数据和写入的数据对比,完全一致,不存在丢数的情况,因此验证了功能的正确性。

b72f02a2-c8ce-11ef-9310-92fbcf53809c.png

总结:通过本案例代码程序的编写以及波形功能仿真,可以熟悉并掌握FIFO的基本功能和常用用法:数据跨时钟域及总线位宽调整。本例程是我自己在一个项目中用到的,结合自己的需求进行编写的,并不具有普适性,写此博客的初衷也是让一些不熟悉FIFO用法的读者能快速入门,可能并不能直接帮助到所有的读者。希望大家可以在此基础上,结合自己的工程应用实例,完成自己相应的设计。

原文链接:https://blog.csdn.net/qq_43622265/article/details/113497121

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1629

    文章

    21748

    浏览量

    604030
  • fifo
    +关注

    关注

    3

    文章

    389

    浏览量

    43712
  • IP核
    +关注

    关注

    4

    文章

    329

    浏览量

    49527
  • 生成器
    +关注

    关注

    7

    文章

    316

    浏览量

    21044

原文标题:FIFO IP核的使用

文章出处:【微信号:gh_9d70b445f494,微信公众号:FPGA设计论坛】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    #FPGA点拨 生成FIFOIP

    fpgaIP
    电子威廉希尔官方网站 那些事儿
    发布于 :2022年10月12日 21:52:56

    #硬声创作季 #FPGA FPGA-27-04 Quartus中fifo IP介绍与仿真测试-1

    fpgafifoIP
    水管工
    发布于 :2022年10月29日 02:28:30

    #硬声创作季 #FPGA FPGA-27-04 Quartus中fifo IP介绍与仿真测试-2

    fpgafifoIP
    水管工
    发布于 :2022年10月29日 02:28:50

    #硬声创作季 #FPGA FPGA-27-04 Quartus中fifo IP介绍与仿真测试-3

    fpgafifoIP
    水管工
    发布于 :2022年10月29日 02:29:13

    #硬声创作季 #FPGA FPGA-27-04 Quartus中fifo IP介绍与仿真测试-4

    fpgafifoIP
    水管工
    发布于 :2022年10月29日 02:29:34

    求助:用fifo ip作延时输出数据

    同上,如何用fifo ip作延时输出数据,想输入一组数据,大概300个,clk上升沿输出一个,想延迟128个数据输出的时间后,将这一组数据通过fifo输出,求大神指点代码该怎么写,大
    发表于 04-26 11:37

    求助 FPGA 异步FIFO IP

    各位大神: 异步FIFO的空 满信号为什么都是高?描述如下:always @(posedge DFIFO_clk or negedge rst_n )beginif(!rst_n)beginWRITE_req
    发表于 07-01 01:51

    ISE中,调用FIFO IP遇到的问题?

    fifo IP fifo_uart fifo_uut(.clk(clk), // input clk.rst(rst_n), // inp
    发表于 09-14 11:36

    XILINX FIFO IP调用问题

    工程利用ISE自带的FIFO将32位的并行数据经过缓存以单bit输出,读写时钟相同,首先将32位数据经过FIFO1变成8位输出,再将8位数据经过FIFO2变成1位输出,对程序仿真结果
    发表于 12-23 12:53

    FIFO IP的使用

    一、原理介绍FIFO即First in, First out。代表着先进的数据先出,后进的数据后出。FIFO实在RAM的基础上增加了许多功能,主要分为读和写两部分。与RAM最大的不同时,FIFO没有
    发表于 04-12 22:44

    FIFO是什么?有什么用?FIFO IP应该如何使用?

    FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。
    发表于 07-20 08:00 22次下载
    <b class='flag-5'>FIFO</b>是什么?有什么用?<b class='flag-5'>FIFO</b> <b class='flag-5'>IP</b><b class='flag-5'>核</b>应该如何使用?

    锆石FPGA A4_Nano开发板视频:FIFO IP的使用讲解

    FIFO是队列机制中最简单的,每个接口上都存在FIFO队列,表面上看FIFO队列并没有提供什么QoS(Quality of Service,服务质量)保证,甚至很多人认为FIFO严格意
    的头像 发表于 09-27 07:07 2080次阅读
    锆石FPGA A4_Nano开发板视频:<b class='flag-5'>FIFO</b> <b class='flag-5'>IP</b><b class='flag-5'>核</b>的使用讲解

    讲解几点关于FIFO IP使用时的注意事项

    FIFO?还是FIFO IP?这也需要写总结吗?太容易了吧。如果我是一个正在处于面试找工作中的年轻人,肯定关注的是如何手撕FIFO,这也是
    发表于 06-21 14:22 1586次阅读
    讲解几点关于<b class='flag-5'>FIFO</b> <b class='flag-5'>IP</b><b class='flag-5'>核</b>使用时的注意事项

    如何在Vivado中配置FIFO IP

    Vivado IP提供了强大的FIFO生成器,可以通过图形化配置快速生成FIFO IP
    的头像 发表于 08-07 15:36 4406次阅读
    如何在Vivado中配置<b class='flag-5'>FIFO</b> <b class='flag-5'>IP</b><b class='flag-5'>核</b>

    FPGA学习笔记:FIFO IP的使用方法

    FIFO(First In First Out, 先入先出 ),是一种数据缓冲器,用来实现数据先入先出的读写方式。数据按顺序写入 FIFO,先被写入的数据同样在读取的时候先被读出,所以 FIFO存储器没有地址线,有一个写端口和一
    的头像 发表于 09-07 18:30 3662次阅读
    FPGA学习笔记:<b class='flag-5'>FIFO</b> <b class='flag-5'>IP</b><b class='flag-5'>核</b>的使用方法