在 for 循环中使用类似别名的变量
Use alias-like variable in for loops
是否可以创建别名 variable/signal 以提高 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 个进程,并阻止我在迭代中使用公共进程变量。
如问题评论中所述,这可以使用过程变量来实现:
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
值在迭代之间不是 re-used。
是否可以创建别名 variable/signal 以提高 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 个进程,并阻止我在迭代中使用公共进程变量。
如问题评论中所述,这可以使用过程变量来实现:
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
值在迭代之间不是 re-used。