我正在尝试设计一个可合成的VHDL代码,它使用了一些多维数组特征 . RTL有一个64字深的数组(称为 big_array_s ,64×16位),用于存储一些初始LUT值 . 此外,还有一个4字深的数组( small_array_s ,4 x 16位),用于设计 . 需要将大数组的切片分配到小数组中 . 它在下面的代码片段中进行了说明 .
type small_array is array (0 to 3) of bit_vector(15 downto 0);
type big_array is array (0 to 64) of bit_vector(15 downto 0);
signal small_array_s : small_array;
signal big_array_s : big_array := init_array_func("test.dat");
init_array_func() 是一个VHDL函数,它使用"test.dat" ascii文件中的数据初始化big_array_s . 我遇到的部分是将big_array_s的一部分分配给small_array_s . 例如,像,
small_array_s <= big_array_s(0 to 3);
是我需要用RTL实现的 . 但是这种直接分配是不可能的,因为LHS和RHS具有不同的阵列类型 . My question is how do I achieve this kind of array slicing in VHDL?
我可以使用的另一种方法是将big_array类型声明为small_array数组 . 例如,
type small_array is array (0 to 3) of bit_vector(15 downto 0);
type big_array is array (0 to 15) of small_array;
signal small_array_s : small_array;
signal big_array_s : big_array;
在这种情况下,声明
small_array_s <= big_array_s(0);
会很顺利的 . 但考虑到综合支持,我怀疑如何初始化3D阵列 big_array_s .
2 回答
您的问题中没有声明多维(3D)数组类型 . 你的第二个big_array声明有一个索引 .
IEEE Std 1976-2008
5.3.2数组类型
5.3.2.1概述
对于第一种方法,您可以声明子类型而不是独立类型 . 结果是它们是相同的类型 .
这样做不是风险,在VHDL分配中,左手侧目标中每个元素的右 Watch 达式都需要匹配元素 . 具有不匹配元素数量的代码可以进行分析和详细说明,但会导致运行时错误报告边界不匹配(并且需要合成以遵守VHDL语义) .
创建一个工作Minimal, Complete and Verifiable example对于你的第一个片段看起来像这样:
这给了:
其中正确显示了初始化的前四个值,以便为已知的test.dat内容发出big_array_s信号 .
这些函数与早于2008年的VHDL标准版本兼容,并从其他示例中进行剪切,粘贴和编辑 .
请注意,init_array_func函数需要一个test.dat文件,其中包含至少65行big_array元素的有效值,并且这样的函数也可以通过传递big_array元素的数量(长度)来推广,返回任意子类型的值some_array .
您还可以在具有相同维度(索引数)的数组类型之间进行显式类型转换,其中元素类型密切相关:
9.3.6类型转换
请注意,作为数组类型的元素类型必须遵循相同的要求,因为它的元素(子元素,此处为类型位) .
使用没有子类型声明的原始类型声明,唯一的其他更改将是赋值:
其中类型转换操作数表达式big_array_s(0到3)与small_array_s具有相同的维度,并且元素类型密切相关(bit_vector(15 downto 0)) .
通过这些更改,上面的代码分析,详细说明并模拟了相同的结果 .
请注意类型转换还依赖于赋值语义,确保赋值目标和右侧表达式的匹配元素:
14.7.3.4信号更新
关于子类型转换的一点意味着索引范围不必匹配,表达式和目标必须具有匹配的元素 .
要进行数组切片,您可以使用一次复制一个bit_vector(15 downto 0)的generate语句 .
关于3D阵列,我使用Xilinx Vivado进行综合的经验不佳 . Vivado将其识别为3D阵列,告诉您它不受支持并实现了一堆寄存器 .