问题描述
是否可以创建别名变量/信号来提高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
语法启发,{{ 1}}部分只是个奖励):
idx
当然,这不起作用。那么,有什么方法可以在VHDL中实现类似的效果,还是每次都必须始终指定完整的信号“路径”?
我可以用过程代替循环体,但是必须在文件的(远处)不同位置声明过程代码,从而进一步降低了可读性。我也可以使用 -- 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;
构造,但这将为每个迭代创建1个过程,并阻止我在迭代内部使用公共过程变量。
解决方法
如问题注释中所述,可以使用过程变量来实现:
process (clk)
variable sample : std_logic_vector(9 downto 0);
variable idx : integer;
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
-- Helpers
sample := data(d).samples(s);
idx := d * 4 + s;
outData(idx) <= '0';
for b in sample'RANGE loop
if sample(b) = '1' then
outData(idx) <= '1';
end if;
end loop;
sample(9 downto 1) <= sample(8 downto 0);
sample(0) <= inData(idx);
-- Do not forget to apply changes
data(d).samples(s) <= sample;
end loop;
end loop;
end if;
end process;
当然,使用过程变量意味着更改操作顺序以获得相同的行为。
由于过程变量是在循环中读取和写入的,因此我担心综合工具会认为迭代N
的结果取决于迭代N-1
的结果,并在其中实现迭代系列(而不是并行)。但是,展开循环后(综合工具将执行此操作),可以清楚地看到综合工具将看到sample
和idx
的值在两次迭代之间不会被重新使用。