【发布时间】:2020-09-08 01:14:53
【问题描述】:
是否可以创建别名变量/信号来提高 VHDL 进程中for 循环的可读性?
例如,考虑以下模块,它包含一个带有内部 for 循环的进程(代码是为了举例,我没有测试它):
library ieee;
use ieee.std_logic_1164.all;
entity MyModule is
port (
clk : in std_logic;
inData : in std_logic_vector(7 downto 0);
outData : out std_logic_vector(7 downto 0));
end MyModule;
architecture functional of MyModule is
type sample_vector is array (natural range <>) of std_logic_vector(9 downto 0);
type data_t is record
samples : sample_vector(3 downto 0);
-- other elements...
end record data_t;
type data_vector is array (natural range <>) of data_t;
signal data : data_vector(1 downto 0);
begin -- functional
process (clk)
begin -- process
if clk'event and clk = '1' then
-- Set outData(N) to '1' if at least 1 of the last 10 values of inData(N) was '1'
for d in data'RANGE loop
for s in data(0).samples'RANGE loop
data(d).samples(s)(9 downto 1) <= data(d).samples(s)(8 downto 0);
data(d).samples(s)(0) <= inData(d * 4 + s);
outData(d * 4 + s) <= '0';
for b in data(d).samples(s)'RANGE loop
if data(d).samples(s)(b) = '1' then
outData(d * 4 + s) <= '1';
end if;
end loop;
end loop;
end loop;
end if;
end process;
end functional;
每次我需要引用该信号时都必须使用data(d).samples(s) 很麻烦,所以我宁愿使用类似别名的变量,而不是类似的东西(灵感来自generate 语法,idx 部分只是奖金):
-- Set outData(N) to '1' if at least 1 of the last 10 values of inData(N) was '1'
for d in data'RANGE loop
for s in data(0).samples'RANGE loop
alias sample : std_logic_vector(9 downto 0) is data(d).samples(s);
constant idx : integer := d * 4 + s;
begin
sample(9 downto 1) <= sample(8 downto 0);
sample(0) <= inData(idx);
outData(idx) <= '0';
for b in sample'RANGE loop
if sample(b) = '1' then
outData(idx) <= '1';
end if;
end loop;
end loop;
end loop;
当然,这是行不通的。那么,有没有办法在 VHDL 中实现类似的功能,还是我们每次都必须指定完整的信号“路径”?
我可以用一个过程替换循环体,但是必须在文件的(很远的)不同位置声明过程代码会进一步降低可读性。我也可以使用 for ... generate 构造,但这会为每次迭代创建 1 个进程,并阻止我在迭代中使用公共进程变量。
【问题讨论】:
-
表达式
id * 4 + s可以产生一个超出inData索引范围的值提供一个无错误的minimal reproducible example作为压缩的基础,从而可以演示解决方案。 For 循环语句不允许循环参数以外的声明。注意idx和sample可以是包含for 循环的声明区域中的变量,并在for 循环中使用参数s分配。 -
@user1155120 我已经修复了示例以匹配您的评论,谢谢。如果我使用流程变量来实现该别名概念,我担心综合工具可能不会将迭代实现为并行路径,因为每次迭代都将取决于变量值并且每次迭代都会更改该值。我知道该值只会在每次迭代开始时发生变化,因此迭代之间没有依赖关系,但我不确定合成工具是否足够聪明以找出...
-
通过展开循环,可以清楚地看出综合工具如何找出迭代之间未重用的过程变量值。 Vivado 至少生产相同的网络。 @user1155120 感谢您的建议。如果您想使用该解决方案发布答案,我会接受。