LabVIEW FPGA代码设计(IP核)

概览

本文档可帮助工程师和开发人员使用NI LabVIEW FPGA模块构建可复用、可扩展且可维护的代码模块,该模块也称为知识产权(Intellectual Property, IP)核、IP块或现场可编程门阵列(Field-Programmable Gate Array, FPGA)功能。了解符合应用和优化需求的推荐组件设计技巧,有助于在应用程序和开发人员之间更高效而有效地复用IP。

内容

IPNet FPGA指南概览

扩展IP

可扩展IP应支持同时使用多个块,以访问越来越多的I/O或所需存储器 








 

内部数据存储
反馈节点可从先前的迭代和流水线中访问数据点

VI范围双端口存储器和FIFO支持在不使用LabVIEW项目的情况下访问FPGA存储器

 

 

独立性

避免使用循环结构。 使用IP块外部的循环

 

 

 

 

 

请勿用定时函数延迟IP块

 

 

项目独立性

无需在项目中配置IP













避免使用FPGA向导




 

I/O独立性
从调用VI访问I/O节点





或使用FPGA I/O常量对模块和通道寻址。 

 

 



 

性能
流水线是指通过使用反馈节点或移位寄存器,并行执行正常串行执行的项
单周期定时循环是LabVIEW FPGA中使用的LabVIEW定时循环结构。  SCTL支持在FPGA时钟的一个滴答内执行循环中的所有代码。






 

FPGA IP代码模块

所有软件开发工作都包括函数、子例程、对象、代码模块,或其他具有大型架构的基本构建块的开发。在设计应用时,需确定并实现所有函数和操作。设计完成后可组合并集成这些构建块,以实现更大的应用程序。在长期开发不同应用程序的过程中,开发小组或团队会创建代表常见操作的代码模块库,并通过对其进行复用从而更快地构建后续应用程序。开发此类代码库的目的是一次完成函数的构建和测试,并多次复用相应函数,以减少整体开发工作量。模块化设计除促进现有代码的复用外,还提高了代码的可测试性和可维护性,从而使开发人员和设计人员能专注在特定于应用的特性和代码段。 

LabVIEW语言提供了一套易于理解的指南,可应用于不同应用并由不同开发人员维护,供世界各地的编程人员开发子VI。使用NI LabVIEW FPGA开发用于FPGA部署的应用程序时,需遵循一些其他指南来构建利用FPGA特定行为的代码模块(子VI)。这有助于在各种基于FPGA的应用程序中有效应用子VI。 

在FPGA平台上,可复用代码模块通常称为IP(知识产权)核;该名称随着传统芯片设计的发展逐渐演变而来。在LabVIEW FPGA中,这些IP核由子VI组成,通常用于LabVIEW编程和LabVIEW工具包。用户可借助LabVIEW FPGA中的子VI一次性实现不同的函数和操作、优化FPGA平台中的实现,并将其应用于不同的应用程序。除子VI源代码之外,代码模块还应包含一些组件,以进一步促进和提高LabVIEW FPGA IP的复用性。其中包括文档、测试代码和基本IP使用范例。 

在LabVIEW FPGA应用中,IP代码模块可执行各种操作,包括使用通信协议(SPI和I2C等)对数据进行编码和解码、数字信号处理(滤波和FFT等)、实现控制算法(PID等)、传感器编码/解码(PWM和正交信号等),以及触发和基准测试。 

扩展IP

应编写可调节输出或输入信号或访问VI范围存储器的IP块,以便其能访问任何应用所需的任意数量I/O。  由于不包含用于附加输入、输出或存储空间的额外代码,因此可减少每个IP的FPGA占用空间。 

某些应用程序可能会使用IP代码模块的多个副本,因此代码模块应无缝支持此类操作。如果代码模块子VI使用局部变量存储状态信息,可将子VI设为重入。在编译过程中,这会在FPGA中创建子VI的多个实例,每个实例都有用于存储状态信息的专属存储空间。

IO扩展性

如果需要额外的IO,用户应能为每个IO点下拉一个附加IP块。  为使程序框图条理清晰,可将多个IP置于一个子VI中。  如果IP块同时包含应用特定代码或更具通用性的代码,请考虑将这些代码分别设为不同的IP。  该操作可提高每个IP的模块化程度和可扩展性。

存储扩展性

与IO可扩展性相同,任何单个IP都应只能访问FIFO存储器中的单个空间。  IP本身不应包含FIFO和存储空间,而是应通过调用VI进行访问。 

某些应用程序可能会使用IP代码模块的多个副本,因此代码模块应无缝支持此类操作。如果代码模块子VI使用局部变量存储状态信息,可将子VI设为重入。在编译过程中,这会在FPGA中创建子VI的多个实例,每个实例都有用于存储状态信息的专属存储空间。

内部数据存储 

根据IP的功能,可能需要子VI内部某种类型的数据存储元素。IP内部的数据存储主要有两种机制:反馈节点和VI范围存储器。反馈节点可在迭代之间存储一个数据点,从而有效保持最新值并实现流水线以提高算法吞吐量。VI范围存储器支持双端口存储器或VI范围先进先出存储器缓冲区(FIFO)的专用模块。重点是应尽可能避免在LabVIEW项目中创建FIFO。因为会依赖于LabVIEW项目配置,使用LabVIEW项目FIFO不利于IP的模块化。仅当IP需要自定义缓冲输入和输出时,才可使用全局存储器。  

反馈节点 

自LabVIEW FPGA模块8.5起,反馈节点可放置在程序框图的任意位置。反馈节点执行与移位寄存器相同的功能:保持上次迭代的值。 

输出i=输入i-1

使用反馈节点存储迭代算法迭代之间的状态信息。以一个简单的计数器为例。图1所示为如何使用反馈节点访问边沿的上一个计数和增量。

图1.使用反馈节点访问简单计数器边沿的上一个计数和增量

在LabVIEW FPGA模块8.5中推出反馈节点优化之前,还有其他选项可在子VI中存储状态信息。最常见的是LabVIEW功能全局变量,它将子VI代码封装在一个单次迭代的While循环中,并使用一个未初始化的移位寄存器来存储状态数据。由于该方法与单周期定时循环不兼容,因此不推荐在LabVIEW FPGA中使用。

在LabVIEW FPGA模块8.5发布前,也可选择使用前面板显示控件和输入控件存储数据。该方法支持通过局部变量读取和写入相应前面板对象,前面板对象的作用与存储寄存器类似。不同于LabVIEW (Windows),由于LabVIEW FPGA读写该存储元素时不会产生额外开销,因此无需使用局部变量。此外,只要控件位于子VI中,便无需像在顶层VI中那样为主机通信提供额外的逻辑。因为无需通过循环实现状态存储,单周期定时循环中可兼容该方法。

注:LabVIEW FPGA中的反馈节点变为硬件触发器。放置在函数之间时,反馈节点可充当流水线层级。

在LabVIEW FPGA模块8.5中,反馈节点是一种在IP块迭代中存储单个数据值的简便方法。推荐使用该方法,而不是使用功能全局和局部变量方法。此外,建议使用反馈节点来存储流水线层级之间传递的数据。 

存储器

除反馈节点外,LabVIEW FPGA IP可以使用的存储资源还有块(用户)存储器或FPGA自有的用户可访问存储器块。

FPGA部分

NI产品

块RAM

1百万门Virtex-II

R系列多功能RIO-NI 7811R、
NI 7830R、NI 7831R (PXI/PCI)

CompactRIO背板-cRIO-9101、cRIO-9102

720 Kb
3百万门Virtex-II

R系列多功能RIO-
NI 7813R、NI 7833R (PXI/PCI)

CompactRIO背板-cRIO-9103、cRIO-9104

1728 Kb
1百万门Spartan-3

CompactRIO集成系统-
cRIO-9072

单板RIO―sbRIO-9601、sbRIO-9611、sb-RIO 9631、sbRIO-9641

432 Kb
2百万门Spartan-3

CompactRIO集成系统-
cRIO-9073、cRIO-9074

单板RIO-sbRIO-9602、sbRIO-9612、sbRIO-9632、sbRIO-9642

EtherCAT-NI 9144

以太网-NI 9148

720 Kb
Virtex-5 LX30

R系列多功能RIO-NI 7851R、NI 7841R

CompactRIO背板-cRIO-9111、cRIO-9112

FlexRIO-PXI-7951R

1152 Kb
Virtex-5 LX50

R系列多功能RIO-NI 7852R、NI 7842R

CompactRIO背板-cRIO-9113、cRIO-9114

MXI-Express-NI 9154

1728 Kb 
Virtex-5 LX85

R系列多功能RIO-NI 7853R 

CompactRIO背板-cRIO-9116

FlexRIO-PXI-7953R

MXI-Express-NI 9155、NI 9157

3456 Kb
Virtex-5 LX110

R系列多功能RIO-NI 7854R

CompactRIO背板-cRIO-9118

FlexRIO-PXI-7954R

MXI-Express-NI 9159

4608 Kb
Virtex-5 SX50T

FlexRIO-PXIe-7961R、PXIe-7962R

 

4752 Kb
Virtex-5 SX95T

FlexRIO-PXIe-7965R、PXIe-7966R

 

8784 Kb
Spartan 6 LX25

CompactRIO集成系统-cRIO-9075

单板RIO-sbRIO-9605、sbRIO-9623、sbRIO-9633

936 Kb
Spartan-6 LX45

CompactRIO集成系统-cRIO-9076

单板RIO-sbRIO-9606、sbRIO-9626、sbRIO-9636

以太网-NI 9146

2088 Kb
Spartan-6 LX75

CompactRIO集成系统-cRIO-9081

 

3096 Kb
Spartan-6 LX150

CompactRIO集成系统-cRIO-9082

 

4824 Kb
Artix-7 Zync 7020

CompactRIO集成系统-cRIO-9068

 

560 Kb
Kintex-7 70T

R系列多功能RIO-NI USB-7855R、NI USB-7855R OEM

 

4860 Kb
Kintex-7 160T

R系列多功能RIO-NI USB-7856R、NI USB-7856R OEM

 

11700 Kb
Kintex-7 410T

FlexRIO-PXIe-7975R

 

28620 Kb


表1.另一个LabVIEW FPGA存储资源是FPGA自有的用户可访问存储器块。


此类存储可在IP需要多个数据点或需要内部FIFO时使用。使用LabVIEW FPGA可通过多种不同的方式访问FPGA上的块存储器,包括存储器读取/写入、FIFO和查找表。为IP创建一个仅供函数本身使用的唯一内存空间很重要。这可以通过VI范围存储器和FIFO实现。不建议对IP使用全局存储器和FIFO,以免IP不必要地依赖LabVIEW项目配置。

但是,对于其在作为当前FPGA功能特性一部分的任一VI中使用的所有实例,LabVIEW FPGA模块8.0的存储器读取和存储器写入函数均使用了一个16 KB共有地址空间。请勿使用上述可能会与应用中其他位置所用存储器发生冲突的函数。如果LabVIEW FPGA 8.0(或更早版本)中开发的IP代码模块需要随机存储器访问,应使用通过LabVIEW存储器扩展实用程序创建的存储器块。

LabVIEW 8.2及更高版本中,每个存储器读取和存储器写入函数都会引用一个特定的存储器块(地址空间),该存储器块通常在LabVIEW项目中作为资源创建。由于这些存储块是在项目中定义的,因此如果在新应用程序中加载IP代码模块VI时,则这些存储块不会自动传输至新项目。为此,可将VI中的存储器块定义为VI范围存储器配置,而不是LabVIEW项目存储器块。可在IP中创建和使用VI范围存储器块,并在使用该IP的任何新应用程序中自动创建存储器块

使用块存储器缓冲数据的FPGA IP FIFO函数同样基于LabVIEW项目中创建的FIFO资源。如果决定在LabVIEW FPGA 8.0的IP代码模块中使用FIFO,IP用户需在应用程序项目中手动创建关联的FIFO资源。如需消除该额外要求,请避免在LabVIEW FPGA 8.0中将FIFO用于任何IP代码模块。

在LabVIEW 8.2及更高版本中,用户可选择开发VI范围FIFO配置,以创建VI特定的FIFO存储器块。其操作与用于VI范围存储器块的步骤相同。

无论IP代码模块或应用程序的其余部分如何使用存储器,所用到存储器均可从FPGA上可用的公共块存储器中分配存储空间,其大小取决于终端中使用的特定FPGA。因此,IP代码模块的用户必须了解IP使用了多少存储器(如有)。该信息应包含在文档和上下文相关帮助中。使用IP模块的开发人员必须跟踪其应用程序不同部分的块存储器使用量,以防编译期间存储器分配过多。

独立性

为能在LabVIEW FPGA应用中自由使用IP模块,代码模块不应明显影响主应用定时。例如,在处理来自正交编码器的两个数字输入信号时,解码位置信息的代码模块不应明显延迟调用应用程序。这要求IP代码模块子VI应快速高效地执行操作。因此在大多数情况下,子VI中不应存在任何循环结构。此外,子VI不应使用任何会延迟代码的定时函数。如果主应用需要定时或循环,应在调用VI中实现。

对于使IP代码模块的定时应独立于调用方这一准则,存在一个例外情况:IP代码模块为调用应用程序提供定时函数。数据采集扫描时钟实用程序是此类IP代码模块的一个示例。图4所示为一个简单的IP代码模块,可实现具有附加功能的扫描时钟,该功能用于验证调用应用程序是否能够满足指定定时。可在多个不同应用程序中快速使用该增强型扫描时钟。这种情况下,应详细记录IP代码模块的操作和定时依赖关系,以便IP用户了解其应用程序的定时行为会如何受到影响。

图4.实现扫描时钟并验证调用应用程序是否满足指定定时的IP代码模块程序框图

 

项目独立性

高质量IP应该高度独立且功能自足。  创建IP时,应确保IP独立于创建它的LabVIEW项目。 这对IP代码模块中的代码施加了一些限制。这些限制与内部数据存储部分中介绍的指南类似。 

  • 避免使用项目范围的FIFO和存储器块
  • 避免使用FPGA向导

自LabVIEW 8.2及更高版本起,可使用VI范围FIFO和存储器块。  它们可提供与项目范围FIFO和存储器相同的功能。 

应避免使用LabVIEW FGPA向导,因为该向导始终生成依赖于LabVIEW项目的代码。 

 

I/O独立性

为使LabVIEW FPGA IP可在不同应用中灵活使用,请确保其独立于所有I/O通道或其他硬件资源,如FPGA块存储器。根据具体应用,用户可在最终应用中集成不同的可重配置I/O设备或其他FPGA终端。因此,不应将IP代码模块编程为特定类型的I/O资源。在最终应用中集成IP模块的编程人员或开发人员可选择要使用的特定I/O资源。与I/O资源相关的数据和值应作为参数传递至IP模块或从IP模块返回。

例如,对于脉冲宽度调制(Pulse-Width Modulation, PWM)输出IP模块,应用程序开发人员可选择用于PWM输出信号的数字输出线。在这种情况下,PWM IP模块应生成并输出信号的当前状态。 开发人员将该值分配给更高层级VI的I/O资源。I/O资源未嵌入IP代码模块的程序框图中。

图2.调用PWM输出IP代码模块(子VI)的应用程序VI程序框图

相同的准则适用于所有输入信号。例如,如果使用NI数字滤波器设计工具包创建的模拟滤波器IP子VI,应在滤波器子VI之外获取模拟值,并将其传递至IP代码模块。

图3.对于NI数字滤波器工具包创建的模拟滤波器IP子VI,可在滤波器子VI之外获取模拟值并将其传递至IP代码模块。

独立于I/O资源开发IP代码模块可使其更易用灵活,并且可在应用中多次集成,而无需自定义IP代码模块的每个实例。

性能

可通过实施以下方法之一或将两者结合来进一步改进高效的FPGA算法。

流水线支持通常在多个时钟周期内串行执行的代码在更短的时钟周期内并行执行。  该方法通过将子程序框图分解为离散步骤实现,每个步骤都成为流水线的一个独立阶段。  每次调用代码时,流水线的每一阶段处理的数据点均为子程序框图最后一次调用中前一阶段处理的数据点。  可使用移位寄存器或反馈节点来实现流水线。  关于流水线的详细信息,请参见LabVIEW帮助中的使用流水线优化FPGA VI(FPGA模块)。  

单周期定时循环(Single Cycle Timed Loop, SCTL)是定时循环结构的一种特殊用法。  SCTL在40 MHz FPGA时钟或另一个衍生时钟的一个滴答中执行结构中的所有代码。  如果SCTL包含过多代码而无法在一个时钟滴答内执行,或包含不支持的函数或结构,用户将收到编译错误。  关于无法在SCTL中使用的函数详细列表,请参阅LabVIEW帮助的定时循环主题,以了解不受支持的函数和结构完整列表。 

带有连线至条件接线端的True布尔常量的SCTL可用于优化非迭代代码的大小和速度性能

档、测试范例

开发IP代码模块时,创建文档、实施测试和构建范例是开发过程的必要部分。其他不熟悉代码模块的开发人员需了解如何正确使用IP,以在其自有应用中实现该IP。 

作为实现的一部分,每个子VI都应包含LabVIEW即时帮助,以供其他开发人员使用。打开帮助窗口且鼠标悬停在子VI上时,即时帮助将显示在LabVIEW中。本文档应包含VI操作/函数以及每个输入和输出参数的基本说明。还应注意其他与子VI相关的编程限制或其他限制,例如在单周期定时循环中使用或块存储器的用法。关于VI及其参数的详细说明,请参见单独的用户手册或参考手册。

图5.每个子VI都包含LabVIEW即时帮助,供其他开发人员使用。

完成IP代码模块的基本实现后,后续逻辑开发步骤就是进行测试和构建范例。测试可确保IP代码模块在所有预期范围内按预期运行。使用一系列不同的输入值并在不限于最初考虑的不同编程场景中测试IP代码模块。还应测试IP的多个实例,以及在不同编程结构中的多种用途。

最终的IP代码模块应包含一些基本以及可能更高级的范例,以说明如何在应用中使用代码模块。通常,开发以特定IP为中心的应用程序都会从这些范例开始。

 

图6.模块中应包含范例,以说明应如何在应用中使用代码模块。

 

总结

LabVIEW FPGA IP代码模块灵活易用,可为应用开发带来显著的优势并节省成本。本文档中提供的指南可助用户创建可轻松复用的IP且无需针对单个应用进行定制。

以下是开发LabVIEW FPGA IP的指南总结:

  • 请勿在IP代码模块的程序框图中嵌入I/O资源。
  • 请勿在IP中使用项目引用的存储器读取和存储器写入或FIFO读取和写入函数。尽量使用VI范围存储器块或FIFO(LabVIEW 8.2及更高版本)。
  • 记录IP中存储器的所有使用情况(存储器扩展实用程序存储器块、FIFO、查找表等)。IP分步包中包含所有存储器扩展实用程序存储器块VI。
  • 请勿在IP中包含任何循环结构或等待/循环定时器函数,除非这是IP的主要用途。
  • 在IP中使用局部变量存储状态信息。 
  • 记录IP所有异常定时行为。

 

Was this information helpful?

Yes

No