对于利用LabVIEW FPGA实现RIO目标平台上的定制硬件的工程师与开发人员,他们可以很容易地利用所推荐的组件设计构建适合其应用的、可复用且可扩展的代码模块。基于已经验证的设计进行代码模块开发,将使现有IP在未来应用中得到更好的复用,也可以使在不同开发人员和内部组织之间进行共享和交换的代码更好服用。
代码模块
任一项软件开发工作均包括函数、子例程、对象和代码模块,以及其他较大架构的基础构建模块的开发。当设计一个应用时,各个函数与操作均被识别和实现。然后,这些构建模块被组合与集成以形成更大的应用。通过长期开发不同应用的过程,一个开发小组或团队将创建表示常见操作的代码模块库,并对其进行复用以更快速地构建未来的应用。开发这样的代码库目的是通过一次构建和测试函数并多次复用它,减少开发的总工作量。模块化设计,除了促进现有代码的复用外,还提高了代码的可测试性与可维护性,从而允许开发人员和设计人员关注于应用相关的特性和代码段。
每种编程语言以及某些情况下的编程环境都有一个优选的代码模块设计模型,以便改进代码模块的实现与集成。该优选设计可以因具体的开发人员而异,但通常一个开
可复用代码——知识产权
FPGA平台上的可复用代码模块通常称为IP(知识产权)核——从传统芯片设计长时间演化来的名称。在LabVIEW FPGA中,这样的IP核由常用于LabVIEW编程和LabVIEW工具集的子VI组成。LabVIEW FPGA中的子VI支持我们一次实现不同的函数与操作,优化FPGA上的实现,然后将其运用至不同的应用。为使这样的子VI可以与不同的重叠需求和架构方便地协同使用,我们需要遵循某些基本指导方针,以确保子VI广泛可用,而不是专为一项特定应用而优化。
为进一步促进和改善LabVIEW FPGA IP的复用,代码模块应当除子VI源码以外还包括一些组件。这些组件包括文档、测试代码和使用IP的基本范例。
在LabVIEW FPGA应用中,IP代码模块典型地用于一些操作的执行,如通信协议(如SPI、I2C等)的编码与解码、数字信号处理、滤波、控制算法的实现、传感器信号(如PWM、积分信号)的编码/解码和基准标定等。
开发LabVIEW FPGA IP的最基本指导方针便是,开发不仅独立于其主应用、而且对其主应用不产生影响或不会有显著要求的代码模块。IP代码模块与其主应用间的唯一需求或依赖性应当是子VI连接面板的接口。该文档将阐述如何在LabVIEW FPGA IP中创建这样的调用独立的IP子VI,并展示一些相关范例。
I/O与资源的独立性
为使LabVIEW FPGA IP便于应用于不同的应用,它应当独立于任何输入/输出通道(I/O)或其他硬件资源,如FPGA块存储器。根据具体的应用,最终应用可以使用不同的RIO板卡或其他FPGA目标平台。因此,IP代码模块不应根据一个特定类型的I/O资源进行编程。将IP模块集成至最终应用的编程人员或开发人员将选择使用某个特定的I/O资源。来自I/O资源数据与值,应当以参数的方式传递给IP模块,或从IP模块返回。
例如对于一个PWM输出IP模块,应用开发人员将为PWM输出信号选用某条数字输出线。在此例中,该PWM IP模块应当产生并输出信号的当前状态。开发人员将把在更高层次VI中赋值给I/O资源。该I/O资源未嵌入在IP代码模块的框图中。
图1:一个调用PWM输出IP代码模块(子VI)的应用VI的框图
同样的指导方针应用于任意输入信号。例如,假设您在使用一个由数字滤波器设计工具包创建的模拟滤波器IP子VI,模拟数值应当自该滤波器子VI外部采集,然后传递给IP代码模块。
图2:使用一个模拟滤波器IP子VI(直接FIR)。模拟数值在主VI采集并传递给滤波器IP。
独立于I/O资源的IP代码模块的开发,使其使用更为方便和灵活,并支持将其多次集成到一项应用,而不必定制该IP代码模块的每个实例。
块存储
除了I/O通道外,其他可能为LabVIEW FPGA IP使用的资源便是块(用户)存储器。LabVIEW FPGA支持开发人员利用多个不同的函数访问FPGA上的块存储器,其中包括存储器读/写、FIFO、查询表及其他函数。这些函数中的大多数均在块存储中创建了一个唯一的地址空间,以避免发生IP与该应用其他IP间的存储器冲突。
然而,LabVIEW FPGA 8.0存储器读函数和存储器写函数,对于其在作为当前FPGA功能特性一部分的任一VI中使用的所有实例,均使用了一个16 kB共有地址空间,这个共有地址空间被当前FPGA功能中任一VI的函数实例所使用。使用这些函数可能会与该应用其他部分使用的存储器产生冲突,因此不应当使用这些函数。如果需要在利用LabVIEW FPGA 8.0(或者更早版本)开发的IP代码模块中支持随机存储访问,您应当使用利用LabVIEW存储器扩展应用程序创建的一个存储器模块。
在LabVIEW FPGA 8.20中,每个存储器读函数和存储器写函数引用一个特定的存储块(地址空间),典型情况下,它在LabVIEW项目中作为一项资源被创建。由于这些存储块在项目中被定义,因此,如果您将一个IP代码模块VI加载至一项新应用,它们不会自动转递给新的项目。为此,您可以在VI中定义一个存储块作为VI-Scoped存储配置,而不是LabVIEW项目。这一VI-Scoped存储块可以在IP中创建并使用;对于任一使用该IP的
新应用,它将被自动创建。
图3:使用LabVIEW FPGA 8.20 VI scoped指定存储块
相似地,使用块存储器来缓存数据的LabVIEW FPGA FIFO函数,是基于一个在LabVIEW项目中创建的FIFO资源。在LabVIEW FPGA 8.0中,如果您决定使用一个IP代码模块中的FIFO,该IP的用户需要在应用项目中手动创建相关的FIFO资源。为免除对IP代码模块用户的这一额外需求,我们建议对于LabVIEW FPGA 8.0中的任何IP代码模块避免使用FIFO。
在LabVIEW 8.20中,您可以选择创建一个VI-Scoped FIFO配置以一个VI专用FIFO存储块。这一操作与指定VI-Scoped存储块的方式相同。
图4:使用LabVIEW FPGA 8.20 VI范围指定FIFO
无论存储器如何被IP代码模块或应用的其他部分使用,都从FPGA上可用的公共块存储器上分配存储空间,存储空间的大小取决于目标平台中所使用的特定FPGA。因此,对于IP代码模块的使用者,重要的是知道IP使用了多少存储器。这一信息应当包含在文档和上下文感知的帮助文件中。使用IP模块的开发人员必须明确了解应用中不同部分所使用的块存储器的大小,以防止编译过程中可能的存储溢出。
定时独立性
为使IP模块能够自由运用于LabVIEW FPGA应用中,该代码模块不应对主应用的定时产生明显影响。例如,在处理来自一个积分编码器的一对数字输入信号时,解码位置信息的代码模块不应当显著延迟调用它的应用程序。这就意味着,该IP代码模块子VI应当快速、高效地执行其操作。在大多数情况下,这要求子VI中不应存在任何循环结构。而且,子VI也不应使用任何等待或其他延迟代码运行的定时函数。如若定时或循环功能需要作为主应用的一部分,那么应当在调用它的VI中实现这些功能。下面的框图展示了一个积分解码器的实现。该范例使用局部变量存储IP代码模块一次调用以及下一次调用(其详细描述见下段)的状态信息。
图5:一个积分解码器IP代码模块范例
使IP代码模块定时独立于调用者的指导方针,存在一个例外:如果该IP代码模块目的在于为其调用应用提供定时功能。此类IP代码模块的例子便是一个数据采集扫描时钟例程。下面的框图展示了一个简单的IP代码模块,它实现了一个具有附加功能特性的扫描时钟,附加功能就是验证调用的应用程序是否能够满足指定的定时。这一增强的扫描时钟可以快捷运用于多个不同的应用中。在此例中,IP代码模块的操作与定时依赖性应当以文档的形式详细描述,以便该IP的用
- 凡本网注明“来源:CK365测控网”的所有作品,均为北京新科时代传媒信息技术有限公司-CK365测控网合法拥有版权或有权使用的作品,未经本网授权不得转载、摘编或利用其它方式使用上述作品。已经本网授权使用作品的,应在授权范围内使用,并注明“来源:CK365测控网”。违反上述声明者,本网将追究其相关法律责任。
- 本网转载并注明自其它来源的作品,目的在于传递更多信息,并不代表本网赞同其观点或证实其内容的真实性,不承担此类作品侵权行为的直接责任及连带责任。其他媒体、网站或个人从本网转载时,必须保留本网注明的作品来源,并自负版权等法律责任。
- 如涉及作品内容、版权等问题,请在作品发表之日起一周内与本网联系,否则视为放弃相关权利。