如何在具有更高增量率的 VHDL 中构建 for 循环?

How to build for loops in VHDL with higher increment rates?

我想将 C for loop 转换为 VHDL 中的 for..generate 语句。

这是怪物:

for (j = J; j+d < (2 << g); j += 2*d)

到目前为止我的步数:

  1. j 重命名为 k 以避免 J
    出现问题 for (k = J; k+d < (2 << g); k += 2*d)
  2. 2 << g 替换为 1 << (g+1)
    for (k = J; k+d < (1 << (g+1)); k += 2*d)
  3. 1 << (g+1) 替换为 2**(g+1)
    for (k = J; k+d < (2**(g+1)); k += 2*d)
  4. 使上限包含在内:j+d <= (2**g)-1
    for (k = J; k+d <= (2**(g+1))-1; k += 2*d)
  5. iterationen 在 j <= (2**(g+1))-d-1
    处停止 for (k = J; k <= (2**(g+1))-d-1; k += 2*d)

到目前为止的 VHDL 代码:

-- outer loops
genK : for k in J to (2**(g+1))-d-1 generate
begin
  -- more generate loops ...
end generate;

如何转换k += 2*d

完整的奇偶合并排序算法可以在.

找到

我的下一步:

  1. 将循环范围移动到从零开始
    for (k = 0; k <= (2**(g+1))-J-d-1; k += 2*d)
  2. 增量为2*d,但生成循环有1。所以它必须通过除法归一化为1k 必须重命名为 kk:
    for (kk = 0; kk <= ((2**(g+1))-J-d-1) / (2*d); kk++)
  3. 现在k可以在循环中恢复:
    k = kk * 2*d + J

到目前为止的 VHDL 代码:

-- outer loops
genK : for kk in 0 to ((2**(g+1))-J-d-1) / (2*d) generate
  constant k  : NATURAL := (kk * 2 * d) + J;
begin
  -- more generate loops ...
end generate;

怎么样:

genK : for k in J to (2**(g+1))-d-1 generate
begin
  gen2d : if ((k - J) mod (2 * d)) = 0 generate
    -- stuff
  end generate gen2d;
end generate;

您可以使用函数生成您需要的值列表。在函数内部,您可以使用 while loop、填充列表并使用 exit 语句来中断循环。这样您就可以更好地控制循环实现。

type integer_vector is array (natural range <>) of integer;

function generate_indexes(J : integer; <some parms> ) return integer_vector is
    variable result : integer_vector( some range );
    variable index  : integer;
    variable j      : integer;
    variable d      : integer;
    variable g      : integer;
begin
    while true loop

        -- calculate the value for j, d and g

        result(index) := j;

        if <break condition> then
            exit;
        end if;
        j := j + 2*d;

    end loop;

    return result;
end function;

那就这样用吧

genK : for j in generate_indexes(<some parms>) generate
    -- code
end generate;

我想这往往更容易理解和测试代码。

没有使用 for/generate 语句,但我认为这应该涵盖了大部分算法。

while bBreak = false loop
  temp1 := j + d;           -- store j + d into variable
  temp2 := (others => '0'); -- initial set compare value to 0
  temp2(g+1) := '1';        -- set the MSB (2 << g)
  if temp1 < temp2 then     -- compare
     bBreak <= true;        -- set break variable
  else
     j <= j + 2*d;          -- set j to the new value (j += 2*d)
  end
end loop

我认为您可以在获得结果向量的 MSB 时优化比较,但不确定。