当前位置: 首页 > news >正文

FPGA自学笔记--VIVADO FIFO IP核控制和使用

          本文主要学习在VIVADO软件中如何生成所需要的FIFO IP核,以及相关的配置定义,并搭建tb对生成的IP读写控制时序进行仿真和测试。主要学习小梅哥的笔记整理而成。

        FIFO(First In First Out,先进先出)是一种具有先进先出特性的缓冲存储结构,在 FPGA 或 ASIC 设计中常用于数据缓存和高速异步数据交互。与普通存储器相比,FIFO 没有外部读写地址线,读写操作依赖内部读写指针自动递增,简化了使用,但只能顺序写入和顺序读出,无法像普通存储器那样通过地址线随机访问指定位置。
        本文重点介绍 FIFO 的基本原理,并以双时钟 FIFO 为例,说明 FIFO IP 的生成流程及其基本使用方法。

一、FIFO结构与应用场景

        从读写时钟角度来看,FIFO 可分为两种结构:单时钟 FIFO(同步 FIFO)和双时钟 FIFO(异步 FIFO)。

  • 单时钟 FIFO:读写共用同一个时钟,所有输入信号的采样与输出信号的更新都在该时钟的上升沿完成,因此所有输入输出操作都与这一时钟保持同步。

  • 双时钟 FIFO:读端和写端各自使用独立的时钟,写相关信号仅与写时钟 wr_clk 同步,读相关信号则仅与读时钟 rd_clk 同步,实现跨时钟域的数据传输。

        单时钟 FIFO 常用于片内同步数据的传输与缓存。
        例如,FPGA 在控制外部传感器时,可以先以 2 MHz 的 SPI 速率快速读取 20 个数据,再通过 UART 以 9600 bps 的波特率依次发送。由于传感器读取速度远高于串口发送速度,需先将数据写入 FIFO 进行缓存,然后按串口速率慢速输出。读取与发送均可依赖同一时钟,因此适合采用单时钟结构的 FIFO。

        双时钟 FIFO 则用于不同步时钟域之间的数据交换。
        典型场景是高速采集系统:高速 ADC 以外部锁相环产生的 CLK1 采样,而 FPGA 内部运行在独立的 CLK2(如 125 MHz)。两者频率和相位互不关联,无法直接用 125 MHz 时钟采集 65 MHz 的数据,否则会产生速率不匹配及亚稳态等问题。借助双时钟 FIFO,可在写端同步于 CLK1、读端同步于 CLK2,实现跨时钟域的安全数据传输。

二、FIFO的常见参数和实现方式

        FIFO 的常见关键参数包括:

  • 宽度:一次读写操作的数据位数。

  • 深度:可存储的 N 位数据的数量(若宽度为 N)。

  • 满标志:当 FIFO 已满或接近满时输出,用于禁止继续写入以避免溢出。

  • 空标志:当 FIFO 已空或接近空时输出,用于禁止继续读取以防读到无效数据。

  • 读时钟:控制读操作的时钟信号,每个有效沿触发一次读取。

  • 写时钟:控制写操作的时钟信号,每个有效沿触发一次写入。

        实现 FIFO 的主要方式有三种:

  1. 自行编写逻辑:用户根据实际需求手动设计 FIFO 电路,适用于功能要求较特殊的场合。

  2. 采用第三方开源 IP 核:直接使用源码形式的开源 FIFO,实现速度快,并可在源码基础上做定制修改,以满足个性化需求。

  3. 使用 Xilinx Vivado 自带的免费 FIFO IP:Vivado 提供可视化配置界面,可轻松设置参数和结构,并针对不同系列器件做优化,功能齐全且稳定,系统设计中通常优先推荐这种方式。

三、FIFO IP配置流程

        在IP库中找到FIFO

 

        在 IP Location 设置中,可以更改生成的 IP 存放路径。此处保持默认路径,仅将 IP 名称修改为 fifo
        在 IP 配置界面中,将接口类型设为 Native。根据所用资源和读写时钟是否一致,FIFO 类型有多种可选。此示例中创建的是读写时钟独立且使用嵌入式 Block RAM 资源的 FIFO,因此选择 Independent Clocks Block RAM

        将读写数据位宽都设置为 8 bit(实际应用中读写位宽可不同),数据深度配置为 256 words。需要注意的是,虽然界面上设置为 256,但生成的 FIFO 实际有效深度只有 255。最终以工具显示的实际深度为准,这与 FIFO IP 的内部实现有关,无需深入探究,使用时留意即可。

        

Read Mode 设置中有两种可选模式:

  • Standard FIFO:只有在读使能信号有效后,数据才会输出。

  • First Word Fall Through (FWFT):当前数据会提前出现在数据线上,读使能到来时,下一个数据立即送出。本例选择 Standard FIFO 模式。

        在 Output Register 勾选并选择 Embedded Register,也可以选择 Fabric Register,或者两个寄存器都选加上,多加一个输出 寄存器,输出就会多延迟一个时钟周期出来。
        

此处可保持默认选项,勾选 复位管脚复位同步 以及 Enable Safety Circuit

  • 复位:重置数据输出和内部读写指针计数,复位后读写指针清零。

  • 复位同步:将异步复位信号分别在读时钟域和写时钟域内先做同步,再执行各自的复位操作。

  • Safety Circuit:通过额外逻辑提高复位可靠性。启用后会多出 wr_rst_busyrd_rst_busy 两个信号,分别表示写/读时钟域处于复位忙状态。

使用时需注意:

  • 只有当 wr_rst_busy 由 1 变为 0 后,且 FIFO 未满,才能开始写操作;wr_rst_busy 为 1 时禁止写入。

  • 只有当 rd_rst_busy 由 1 变为 0 后才能开始读操作;rd_rst_busy 为 1 时禁止读取。

状态输出信号可按实际需求选择。为了便于实验观察波形,此处将空、将满以及读写端握手相关信号全部勾选。勾选后,FIFO 的输出端口会增加以下常见信号:

  • wr_ack:写入响应,当数据成功写入 FIFO 时输出高电平,表示写操作已完成。

  • overflow:上溢出标志,当 FIFO 已满仍继续写入时,该信号拉高提示溢出。

  • valid:读数据有效指示,在读操作时伴随数据输出拉高,高电平表示输出数据有效,可据此触发后续处理。

  • underflow:下溢出标志,当 FIFO 已空仍继续读出时,该信号拉高提示下溢。

空满信号的触发阈值可通过 Programmable Full TypeProgrammable Empty Type 设置。默认配置为 No Programmable Full ThresholdNo Programmable Empty Threshold,对应默认阈值依次为 253、252、2、3。

其逻辑可简单理解为:

  • Full 信号:当 FIFO 内数据量 ≥ 253 时置 1;在 full 为 1 的情况下,如果数据量降至 ≤ 252,full 信号恢复为 0。

  • Empty 信号:当 FIFO 内数据量从 0 增加到 ≥ 3 时,empty 信号变为 0;在 empty 为 0 的情况下,如果数据量降至 ≤ 2,empty 信号恢复为 1。

由此可见,full 和 empty 信号并非在 FIFO 完全写满或完全读空时才改变状态,而是预留了一定余量以提高系统稳定性。

以上默认设置是可修改的,通过 Programmable Full TypeProgrammable Empty Type 可以选择不同模式进行配置。以 Programmable Full Type 为例:

  • Single Programmable Full Threshold Constant:仅可设置 Assert ValueNegate Value 保持默认不可改。

  • Multiple Programmable Full Threshold ConstantAssert ValueNegate Value 均可自定义设置。

  • Single Programmable Full Threshold Input PortAssert Value 可通过输入端口动态设置,Negate Value 保持默认不可改,此时 FIFO 会多出一个输入端口 prog_full_thresh 用于输入阈值。

FIFO 提供数据量计数信号输出:

  • Write Data Count:同步于写时钟,表示 FIFO 内当前已写入的数据数量。

  • Read Data Count:同步于读时钟,表示 FIFO 内当前可读的数据数量。

计数信号的位宽可根据实际需求设置,此处保持默认 8 位

完成上述设置后,可在 Summary 栏查看配置总结,内容包括存储器类型、数据位宽 8 bit、实际深度 255 以及已选择的状态信号等信息。

点击OK,再点击generate,生成IP ing。

四、FIFO IP 例化

        在生成的IP source中,有IP的例化模板。

fifo your_instance_name (.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 [7 : 0] din.wr_en(wr_en),                  // input wire wr_en.rd_en(rd_en),                  // input wire rd_en.dout(dout),                    // output wire [7 : 0] dout.full(full),                    // output wire full.almost_full(almost_full),      // output wire almost_full.wr_ack(wr_ack),                // output wire wr_ack.overflow(overflow),            // output wire overflow.empty(empty),                  // output wire empty.valid(valid),                  // output wire valid.underflow(underflow),          // output wire underflow.rd_data_count(rd_data_count),  // output wire [7 : 0] rd_data_count.wr_data_count(wr_data_count),  // output wire [7 : 0] wr_data_count.wr_rst_busy(wr_rst_busy),      // output wire wr_rst_busy.rd_rst_busy(rd_rst_busy)      // output wire rd_rst_busy
);

http://www.dtcms.com/a/406969.html

相关文章:

  • 张家界官方网站查询网ip138子域名
  • 【通信】无线PA 释义
  • 襄阳做公司网站的软件公司建立个人网站能赚钱吗
  • 赛迪顾问《2025中国虚拟化市场研究报告》解读丨虚拟化市场迈向“多元算力架构”,国产化与AI驱动成关键变量
  • 汕头公众号建设网站北京模板开发建站
  • 【Linux】UDP 网络编程
  • Redis 键空间 五大类型
  • seata部署与集成
  • ORM框架Java持久化层使用手册(mybatis,mybatisplus,jpa等)
  • 大型企业网站建设方案seo排名优化软件有用
  • 数据驱动下的高维数据破局术:降维处理的技术实战、选型指南与方法论沉淀
  • Java按顺序提取Word内容(文本+数学公式)
  • Python快速入门专业版(四十五):Python类的属性:实例属性、类属性与属性访问控制(封装特性)
  • 软考~系统规划与管理师考试——论文—— IT 服务监督管理专题 —— 范文
  • 深度解析社区运营中的技术实践:从数据驱动到智能优化的全面探索
  • 虚拟主机WordPress建站苏州网站建设如何选择
  • hello算法笔记 03
  • 沂水网站开发付钱做编程题目的网站
  • C++笔记(基础)string基础
  • 雨晨Win11PE_25H2_26200.6588紧急维护系统
  • 【鸿蒙心迹】摸蓝图,打地基
  • 小型教育网站的开发建设开题报告建设网咨询
  • 二级网站建设情况说明汕尾网站网站建设
  • 从零起步学习Redis || 第二章:Redis中数据类型的深层剖析讲解(下)
  • C++设计模式_创建型模式_原型模式Prototype
  • 简单直播TV1.4.3 | 一个软件观看四大平台,免去多应用切换烦恼
  • 设计模式-3D引擎中的设计模式
  • Linux安装配置Redis 7.2.3教程
  • 山西省城乡住房建设厅网站网站建设需要多少钱小江
  • 网站建设背景需要写些什么考研哪个培训机构比较好