可以使用内存项将数据存储在FPGA块内存中。内存项以2kb为倍数引用FPGA目标上的块内存。每个内存项引用一个单独的地址或地址块,您可以使用内存项访问FPGA上的所有可用内存。如果需要随机访问存储的数据,请使用内存项。
内存项不消耗FPGA上的逻辑资源,因为它们不包括确保跨时钟域数据完整性所需的额外逻辑。
内存项中的每个内存地址只存储最新的值。如果在从内存地址读取之前对该地址进行N次写入,则在最近的值之前的N - 1个值将丢失。
如果您不使用获取的每个数据值,那么内存项是一个不错的选择,因为您不需要编写额外的代码来丢弃不必要的值。如果需要保存所有值,则应该使用FIFO。
1.FPGA 创建 Memory Items 的两种方式
1.1 Target-Scoped Memory Items
可以由FPGA终端上的多个VI访问,并且存储多个VI访问的数据。
名称:显示在“项目资源管理器”窗口或“vi定义的内存配置”节点中的内存项的名称。该名称也出现在框图上的内存方法节点中。
请求的元素数量: 指定你想在内存项中保存的元素数量。实际的内存使用量(以字节为单位)取决于您指定的元素数量和数据类型。
实现:指定FPGA如何存储该内存项。包含以下选项:
存储器块—数据通过内嵌的内存块存储。赛灵思的文献将这种实现描述为块RAM或BRAM。使用嵌入式块内存的内存项需要一个时钟周期来执行。在以下情况下使用块内存:•在单周期定时循环中,当您不需要在给定地址的同一周期内访问该内存时。
•当您需要的内存量很大时。
•当您在FPGA上没有足够的空闲逻辑资源可用时。
该选项包含以下组件:—实际元素数—返回配置的元素数。
有时所请求的元素数量与内存配置不兼容。在这种情况下,实际元素数被强制为一个兼容的数字。
查找表-将内存项存储在FPGA上可用的查找表中。这种存储消耗FPGA用于其他逻辑运算的逻辑资源,例如加法和减法。赛灵思的文献将这种实现描述为分布式RAM或LUT RAM。在以下情况下使用查找表:•您正在以单周期定时循环访问该内存,并且需要在您给出地址的同一周期内从内存项读取数据。
•需要的内存量小于FPGA上的最小嵌入式块内存量。
•在FPGA上没有足够的空闲嵌入式块内存。
该选项包含以下组件:—实际元素数—返回配置的元素数。
有时所请求的元素数量与内存配置不兼容。在这种情况下,实际元素数被强制为一个兼容的数字。
DRAM -将内存项存储在FPGA上可用的DRAM中。并非所有硬件都支持使用DRAM作为内存。该选项包含以下组件:•实际元素数量-返回配置的元素数量。有时所请求的元素数量与内存配置不兼容。在这种情况下,实际元素数被强制为一个兼容的数字。
•最大未处理请求数-指定应用程序允许未处理的最大数据请求数。
•DRAM bank -指定使用哪个DRAM bank。
此处已分配:表示该内存项已分配的内存量。
其他分配:显示在其他项中分配了多少内存。
空闲的:指示存储库中还有多少内存可用。
总物理大小:BANK的总大小。
数据类型-:FIFO或内存中数据的数据类型。您可以选择定点(FXP)数据类型;布尔数据类型;8位、16位、32位或64位有符号或无符号整数数据类型;或单精度浮点(SGL)数据类型。还可以选择自定义控件作为数据类型。如果选择FXP,则必须在“定点配置”部分配置数据类型。
定点配置:设置定点数据的配置信息。选择“数据类型”为“FXP”,启用定点设置。您可以配置Encoding设置,然后LabVIEW自动确定Range设置。
编码器 -设置定点值的二进制编码设置。
signed -设置定点值是否有符号。
unsigned -设置定点值是否为无符号值。
字长-设置LabVIEW用来表示所有可能的定点值的位数。
整型字长—对于所有可能的定点值,设置整位数,或者将二进制点移动到最高位的位数。整型字长可以是正数或负数。
最小值-定点数据范围的最小值。
最大值-定点数据范围的最大值。
delta -在定点数据范围内任意两个序号之间的最大距离。
选择控件—打开一个对话框,您可以在其中导航到要使用的自定义控件。只有在“数据类型”下拉菜单中选择“自定义控件”时,才会显示此按钮。
DRAM最大数据宽度-内存的物理端口宽度。选择的数据类型不能大于数据宽度。
确保自定义控件中所有项的数据宽度之和不大于DRAM的最大数据宽度
通过此页面可以配置仲裁选项,并为内存项指定读/写端口。
本界面包括以下几个部分:
接口A:指定从接口A读取仲裁的类型。
方法-接口访问内存的方式。接口A始终是只读的。
仲裁:设置内存接口的仲裁类型。如果在单周期定时环路中使用为接口A配置的内存方法节点,请选择“仅多个请求者仲裁”或“从不仲裁
接口B:指定接口B仲裁的方式和类型。
方法-指定接口访问内存的方式。接口B默认具有写访问权限。接口B的read方法与自定义数据类型不兼容。如果在“数据类型”页面中选择“自定义控件”作为数据类型,则接口B的“方法”为dim。
仲裁:设置内存接口的仲裁类型。如果在单周期定时环路中使用为接口B配置的内存方法节点,请选择“只有多个请求者时仲裁”或“不仲裁”。
内存原理图-反映内存块的配置。
该界面包括以下几个部分:
初始化方法—初始化内存项的方法。选择“标准函数”以使用常量、直线、正弦波或余弦波填充内存项。选择Initialization VI以初始化VI创建的数组填充内存项。
标准函数-包含以下选项:
模式-指定LabVIEW填充所选地址间隔的内容。您可以从以下值中选择:
常数:使用在“值”中指定的常数填充。
线性-使用从您在起始值和斜率中指定的值计算的线性段进行填充。
正弦-使用您在周期数中指定的全尺寸正弦波填充。此选项仅适用于有符号整数和有符号定点数。
余弦-使用您在周期数中指定的全尺寸余弦波填充。此选项仅适用于有符号整数和有符号定点数。
起始地址-指定要填充的内存项间隔的下限。
结束地址-指定要填充的内存项间隔的上限。
起始值-如果从模式下拉菜单中选择线性,则指定LabVIEW在内存项中输入的第一个值。
斜率-如果从模式下拉菜单中选择线性,则指定LabVIEW在内存项中输入的直线的斜率。
周期数-如果从模式下拉菜单中选择正弦或余弦,则指定LabVIEW在内存项中进入的周期数。
应用-显示图形预览和数据值选项卡中的初始值。单击Apply按钮不会保存初始化数据。必须单击OK按钮保存初始化数据。
初始化VI -包含以下选项:
VI路径-初始化VI的路径。
从模板新建VI—创建模板VI的实例,保存到在“命名新初始化VI”对话框中指定的位置,然后打开该VI。必须关闭“内存属性”对话框才能编辑该VI。
打开 VI-打开在 VI 路径字段中指定的 VI。要编辑 VI,必须关闭 "内存属性 "对话框。
- 运行 VI-运行在 VI 路径字段中指定的 VI。然后,LabVIEW 将输出阵列导入内存项,并在 "图形预览 "和 "数据值 "选项卡中显示相应的值。
- 图形预览-在波形图中显示内存项的当前内容。
- 数据值-显示存储项的当前内容。
- 重置为默认值-将存储项的内容重置为默认值。对于布尔数据类型,默认值为 0(FALSE)。对于整数数据类型,默认值为 0。 对于定点数据类型,如果在 "内存属性 "对话框的 "数据类型 "页面上,"最大值 "大于或等于 0,且 "最小值 "小于或等于 0,则默认值为 0。如果最大值小于 0,默认值等于最大值。如果 "最小值 "大于 0,默认值等于 "最小值"。
1.2 VI-Defined Memory Item
如果在可重入的 FPGA VI 中使用 VI 定义的内存项,LabVIEW 会为 VI 的每个实例创建内存项的单独副本,这样就可以创建可重用的子 VI,同时避免资源冲突。如果将带有 VI 定义的内存项的 FPGA VI 发送给其他用户,则无需发送 LabVIEW 项目,因为 VI 定义的内存项在 Project Explorer 窗口中不包括相应的项目。
有关此处详细信息查看NI在线文档:
https://www.ni.com/docs/zh-CN/bundle/lvfpga-api-ref/page/vi-lib/rvi/memory/memory-common/write-memory-method.htmlhttps://www.ni.com/docs/zh-CN/bundle/lvfpga-api-ref/page/vi-lib/rvi/memory/memory-common/write-memory-method.html
2 示例-并行
该程序有两个 While 循环--一个从 FPGA I/O 节点获取数据并将数据写入内存项,另一个从内存项读取数据并显示数据。
3.示例-过采样
如果读取和显示循环的运行速度较快,则读取和显示的数据会多于实际获取的数据。循环会多次读取和显示某些数据点。这种情况称为过采样。从速度较慢的硬件(模拟输入信号、热电偶)获取数据,然后在速度较快的硬件(FPGA)上进行处理时,就会出现过采样。在试图捕捉快速边缘、瞬态和一次性事件时,通常需要过采样。
4.示例-欠采样
如果读取和显示循环运行速度较慢,读取和显示的数据点就会少于实际获取的数据点。一些数据点在被读取和显示之前就被写入并丢失了。这种情况称为采样不足。欠采样是指对感兴趣的特定信号采样太慢。