要在 FPGA VI 的不同部分之间或 FPGA 目标中的 VI 之间传输缓冲数据,可使用 FIFO。FIFO 是一种先进先出的缓冲器,第一个写入内存的数据项就是第一个从内存中读取和删除的数据项,类似于队列。
FPGA FIFO 的功能类似于一个固定长度的队列,可将多个数据项写入内存或从内存中读出。与队列不同的是,FPGA FIFO 通过对数据大小施加限制来确保行为的确定性,读写器可同时访问数据。
LabVIEW FPGA 模块包括以下类型的 FIFO:
Target-Scoped - 使用单个 FIFO 将数据传输到同一目标上多个 VI 中的代码段,或将数据传输到这些代码段。
VI Defined-在单个 VI 中的多个循环之间传输数据。
DMA - 直接访问内存,将数据传输到 RT 主机 VI 和 FPGA 目标 VI,反之亦然。
Target-Scoped FIFO
使用目标选区 FIFO 来存储必须从多个 VI 访问的数据。
名称-指定显示在项目浏览器窗口或 VI 定义的 FIFO 配置节点中的 FIFO 名称。该名称还显示在框图上的 FIFO 方法节点中,您可以在 FIFO 名称控件和常量中使用该名称来访问目标作用域的 FIFO。
类型-指定要使用的 FIFO 类型。
Target-Scoped-FIFO 可在 FPGA VI 内部以及项目资源管理器窗口中同一目标下的 FPGA VI 之间传输数据。
主机到终端 - DMA 或终端到主机 - DMA-DMA FIFO 可在主机 VI 和目标之间传输数据。
点对点写入器或点对点读取器--FIFO 可使用点对点流传输数据。
请求的元素数-指定 FIFO 所能容纳的元素数量。FIFO 可容纳的最大元素数取决于您选择的实现和 FPGA 上可用于实现的空间大小。如果 FIFO 使用内置控制逻辑,则元素的最大数量也取决于数据类型。内置 FIFO 的宽度必须小于或等于 1024。如果 FPGA 没有足够空间容纳您输入的请求元素数,则 FPGA VI 编译失败并显示错误消息。
如果在 "类型 "下拉菜单中选择 "DMA - 主机到终端 "或 "DMA - 终端到主机","要求的元素数 "将指定 DMA FIFO FPGA 部分的大小。
如果在 "实现 "控制中选择 "块存储器",则 FIFO 可容纳的元素数量将受到限制。实际元素数表示 FIFO 中的元素数,可能与请求的元素数不同。
实现-指定 FIFO 在 FPGA 上使用的存储类型。只能为目标范围和 VI 定义的 FIFO 指定实现。包含以下选项:
触发器-将数据存储在 FPGA 上可用的触发器中,性能最快。National Instruments 建议将此选项用于小型 FIFO(最多 100 字节)。您不能在多个时钟域中使用带有触发器或查找表实现的 FIFO
查找表 - 将数据存储在 FPGA 上的查找表中。Xilinx 文献将这种实现方式描述为分布式 RAM 或 LUT RAM。National Instruments 建议将此选项用于 100-300 字节的 FIFO。您不能在多个时钟域中使用带有触发器或查找表实现的 FIFO。
块存储器--使用嵌入式块存储器存储数据。Xilinx 文献将这种实现方式称为块 RAM 或 BRAM。对于大于 300 字节的 FIFO,National Instruments 建议使用该选项。如果选择 "块存储器 "选项,则可能无法读取目标作用域 FIFO 或 VI 定义 FIFO 中的数据,直到将数据写入 FIFO 后的 6 个时钟周期。使用 "读 "或 "写 "方法配置的 FIFO 方法节点的定时输出
VI-Defined FIFO
将 VI 定义的 FIFO 用于只需从单个 VI 访问的数据,或必须为可重入子 VI 的不同实例分别维护的数据,因为子 VI 的每个实例都包含一个 VI 定义的 FIFO 的新示例。
FPGA 读取/写入函数
元素 -- 要写入或读取的数据元素
超时 -- 设置方法在 FIFO 已满或为空时等待可用空间或数据的滴答数
超时? -- 如果尝试写入或读取失败,则为 True。 不覆盖或添加新元素。
如果写入超时,FIFO 传输可能会丢失
FPGA 溢出和不足
如果向 FIFO 写入数据的速度与读取数据的速度存在差异,那么 FIFO 的行为可能与预期不符。
如果写入方法的频率高于读取数据的频率,那么 FIFO 最终会填满并出现溢出情况。
当 FIFO 已满时,其他写入方法会超时,数据不会写入 FIFO,直到出现可用空间。
空间可通过从 FIFO 读取数据或重置 FIFO 来创建。任何因溢出而未写入的数据都会丢失。如果读取数据的频率高于写入数据的频率,那么 FIFO 最终会清空,出现下溢情况。当 FIFO 为空时,读取方法超时。处理溢出的方法取决于无损传输的重要性。如果在发生溢出时读写功能都必须停止,那么 FIFO 写方法的超时输出可用作终止写循环的条件,如图所示
FIFO FAQ
ASK:在从 cRIO 上的多个通道读取数据,并希望将所有这些数据发送到我的 RT 主机进行处理,但希望确保所有数据都是同步的。我怎样才能做到这一点?
答: 以相同的速率从每个 FIFO 读取数据,如果您从多于 FIFO 的通道进行采样,或者资源空间有限,并且希望在 FPGA 上使用较少的 FIFO,则可以使用交错将多个通道写入一个DMA FIFO。
ASK:使用目标到主机 DMA FIFO 将数据从 FPGA 读入 LabVIEW Real-Time VI。我可以在分布式系统管理器中看到实时目标的 CPU 使用率接近 100%,这导致我的处理器匮乏,并且我的其他循环无法运行。
答:考虑使用以下架构仅在 FIFO 中有样本时读取 FIFO,而不是使用超时:
与可配置为轮询或阻塞的实时 FIFO 不同,DMA FIFO 的行为由其运行的硬件决定。
在大多数 National Instruments 的实时控制器上,DMA FIFO 在配置超时后将轮询新样本。这可能会导致您的实时处理器承受高负载,进而导致意外的执行行为。
带有NI-STC3定时引擎的实时控制器(例如cRIO-903x系列)使用中断来执行DMA传输,因此您不会增加处理器检查数据是否准备就绪的负担。
由于这是预期行为,因此其他线程饥饿是应用程序需要更仔细考虑线程计时的症状。解决此问题的适当方法是使用初步的目标到主机 FIFO.Read 方法以编程方式检查 DMA FIFO,以在尝试读取数据之前查看所需的数据是否可用,如解决方案中所示。
ASK:在 FPGA 上使用高采样率的 DMA FIFO 时丢失数据
答:在这种情况下,主机端 DMA FIFO 由于数据吞吐量不足而溢出。有必要提高传输速度,以免 FIFO 溢出。
增加吞吐量:
- 读取剩余元素 ,然后将其用作 FIFO.Read 的元素数量 (调用方法)
- 使用最佳数据类型将数据传输至 FPGA 或从 FPGA 传输数据。例如,如果 FPGA 目标支持通过 DMA 传输无符号 32 位 (U32) 数据,请将 2 个 16 位值组合为 1 个 U32 值来传输它。有关支持的传输数据大小,请参阅 FPGA 目标文档。
- 增加主机端 FIFO 深度。为此,请使用FIFO.Configure(调用方法)。
- 增加FIFO.Read(调用方法)的元素数参数 。
- 更频繁地调用 FIFO.Read(调用方法) 。
- 将FIFO.Read(调用方法)放入其自己的 while 循环中,以允许其以最快的速率读取,而无需进行额外的处理来减慢循环速度。
- 增加 FPGA 端 FIFO 深度。
++注意:++ 增加 FPGA 端 FIFO 深度会增加 FPGA 资源利用率,并且需要重新编译 FPGA 代码。
利用板载内存:
- 许多 FPGA 设备都具有板载内存,您可以使用它来存储数据,直到数据准备好传输为止。
- 只要有可用的板载内存,这将允许用户以比从目标到主机传输样本的速度更快的速度获取数据
- 借助 FlexRIO 设备,DRAM 可用于此目的
ASK:如何将多个数据元素写入 FIFO 写入?
答:您可以配置 FIFO 以允许同时将多个元素写入 FIFO。您可以在FIFO 属性对话框中执行此操作。在**"接口"** 选项卡中,您可以将"**每次写入的元素数"**更改为不同于 1 的数字,以允许以数组的形式一次发送更多数据元素。
增加此数量后,您可以将数组连接到 包含定义数量的元素的FIFO Write 节点。
注意:您可以选择的最大元素数取决于您使用的数据类型的大小。使用例如 U8,每次写入可以写入的元素数量是使用 U16 时的两倍。
并非所有 FPGA 硬件都支持"每次写入的元素数量" 选项。请参阅您的硬件文档以获取更多信息。或者,您可以使用带有自动索引输入隧道的 For 循环将数组的每个元素单独写入 FIFO。此方法允许写入任意数量的元素,而不仅仅是 2 的幂。
ASK:配置 FIFO 中的元素数量与请求 FIFO 深度之间的区别
答:目标到主机 FIFO 的结构使得数据通过直接内存访问 (DMA) 通道在两个 FIFO(或缓冲区)之间发送。
第一个缓冲区仅存在于 FPGA 目标上,并在项目中进行配置。
第二个缓冲区仅存在于主机上。可通过主机 VI 上的调用节点请求的缓冲区深度。
FPGA 缓冲区将保留在 FPGA VI 上写入的所有数据,然后再通过 DMA 传输至主机缓冲区。通过 DMA 的数据流自动发生,无法以任何方式进行配置。
主机缓冲区接收通过DMA发送的任何数据,直到该数据从主机VI的缓冲区中读出。
如果您不指定主机缓冲区的大小,它将强制为 10,000 个元素或 FPGA 缓冲区中可容纳的最大元素数的两倍,以较大者为准。
ASK:FIFO 丢失数据
答:DMA FIFO 丢失数据通常是由于DMA 架构不当造成的。以下几点是开发人员在使用 DMA FIFO 时遇到的与丢失数据相关的几个常见问题。
- FPGA 的采集代码有一些代码段花费了不确定的时间。如果应以给定的循环速率采集数据并且 FPGA 正在主机上等待值更改或中断,则 FPGA 将停止采集并且数据将丢失。
- 正在从 FIFO 中乱序读取数据。当将数据交错写入 FIFO 并且您未指定读取通道数的整数倍时,可能会发生这种情况。
- DMA FIFO 溢出。知识库文章在 FPGA 上使用高采样率的 DMA FIFO 时丢失数据 更详细地介绍了这个主题。然而,下面给出了几种避免溢出的方法。
- 监视写入(FIFO 方法)是否 超时。如果写入函数超时为真,则表明缓冲区设置不正确。
- 在主机上大量读取数据。这有助于限制主机数据通信的计算开销。
- 使用标准架构从 FIFO 读取数据。请遵循设计主机 VI 以读取 DMA 应用程序中的数据的指南。
ASK:中止、运行、启动、复位或写入已满 FIFO 后的 FPGA FIFO 状态
答:
- 启动时,FIFO 应该是空的,里面什么也没有。里面不应该有剩余的数据。
- 中止调用方法将停止FPGA目标上打开并运行的FPGA VI。它不会重置FPGA VI中的默认值。I/O 在中止时保持其先前的状态。
- 运行调用方法将在FPGA终端上运行FPGA VI。
- 启动调用方法开始 FPGA 目标和主机之间的 DMA 数据传输**。** 配置有读 或写方法的 FIFO 方法节点会自动启动 DMA 数据传输。
- 重置会将FPGA终端上的FPGA VI重置为VI的默认状态。该方法将清除所有 FIFO。
- 如果您尝试写入已满的 FIFO,数据将会丢失。