arrays - 不使用访问类型的 VHDL 可变长度数组
问题描述
在可综合的 VHDL 设计中,我经常需要做一些“软件”计算来将高级参数 ( generic
s) 转换为低级配置。要进行这些计算,有可用的基本软件工具很有用,例如动态内存分配。
澄清一下,这种参数转换通常采用function
为 some 赋值的调用形式constant
,例如:
constant internal_config_c : config_t := calc_low_level_config(params_g);
因此,请注意这个问题纯粹是关于 VHDL“软件”编程(里面的东西calc_low_level_config
)。我的问题不是关于综合(随后使用的东西internal_config_c
),我只提到综合是因为 Xilinx Vivado 综合不支持access
类型,这对我来说是在 VHDL 中创建动态数组的最自然的方式。
因此,我的问题是:VHDL(除了类型)中有哪些编程结构可access
用于使用(或模仿)可变大小的数组?
我能想出的唯一可能的解决方案是递归。我不喜欢这样,因为我发现递归函数往往非常难以阅读,所以我很想了解任何替代方法。
access
为了说明,这是一个使用类型的简化但完整的玩具示例:
entity top is
generic (
params_g : integer_vector := (7, 11, 6)
);
end;
architecture rtl of top is
function internal_calculations(x : natural) return bit_vector is
begin
-- Toy example...
if x mod 3 = 2 then
return "1101";
elsif 7*x mod 5 < 3 then
return (x-1 downto 0 => '1');
else
return (3*(x/2)-1 downto 0 => '0');
end if;
end function;
function calc_low_level_config(params : integer_vector) return bit_vector is
type ptr_t is access bit_vector;
variable data : ptr_t := new bit_vector'(0 to -1 => '0');
begin
-- Collect variable-length data
for i in params'range loop
data := new bit_vector'(data.all & internal_calculations(params(i)));
end loop;
-- Print
report to_string(data.all);
return data.all;
end function;
constant internal_config_c : bit_vector := calc_low_level_config(params_g);
begin
end;
在 Modelsim 中进行模拟会打印出预期的结果:
vlib work
vcom -2008 top.vhd
vsim work.top
# ** 注:0000000001101111111
但是,上述实现无法由 Xilinx Vivado 综合。因此,我能想到的唯一可用选项是递归,如下所示:
function calc_low_level_config(params : integer_vector; idx : integer) return bit_vector is
begin
if idx = params'high then
-- Exit condition
return internal_calculations(params(idx));
else
-- Recurse
return internal_calculations(params(idx)) & calc_low_level_config(params, idx+1);
end if;
end function;
constant internal_config_c : bit_vector := calc_low_level_config(params_g, params_g'low);
有没有更好的办法?
编辑:针对以下最初的评论:
- 上面的示例代码不适用于实际项目中的综合。我专门写了它来说明我想要做的数组大小调整的类型。这是我对最小但完整(可编译)示例的尝试。
- 在这个极其简化的示例中,我不是在问是否需要调整数组大小。我关于 VHDL 语言的问题是主要的,而示例则非常次要。如果它会分散注意力,请忽略该示例。
- 我的真实例子很复杂(在同一个循环中涉及多个可变长度数组,其长度变化是相互依赖的,并且依赖于深度嵌套的函数调用)。我用 C++ 和 MATLAB 编写的验证模型使用可变大小的数组,所以我很确定如果可能的话我也想在 VHDL 中使用可变大小的数组。
解决方案
我认为 Tricky 在上面的评论中提供了这个问题的最佳答案:
唯一的另一种方法是提前知道整个向量的长度,并通过计算切片范围来填充位。这里的递归形式可能是最省力的。VHDL 没有“动态调整大小”对象。即使对于访问类型,您也需要在创建对象时知道长度。
推荐阅读
- python - 过滤数据源后散景 vbar_stack 条不重新排序
- amazon-web-services - 使用 Python 为 AWS API Gateway 发出签名的 IAM_AUTH 请求
- oracle - 显示 PLSQL 中的所有对象值
- lodash - 从数组中删除具有特定“键:值”的对象
- javascript - React HOC 与 Helper 类?
- javascript - 尝试在调整大小后将 jquery 设置为触发一次
- android - 文本没有出现在 ios / android 设备上,但在模拟器上工作正常
- protocol-buffers - 反序列化缓冲区协议缓冲区
- netlogo - 修改以修复从补丁到观察者 netlogo 的上下文
- python - 为什么我得到错误的输出?