在 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,并使实现系列迭代(而不是并行)。然而,在展开循环(这是综合工具所做的)之后,很明显综合工具将看到 sampleidx 值在迭代之间不是 re-used。