如何在具有更高增量率的 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)
到目前为止我的步数:
- 将
j
重命名为 k
以避免 J
出现问题
for (k = J; k+d < (2 << g); k += 2*d)
2 << g
替换为 1 << (g+1)
for (k = J; k+d < (1 << (g+1)); k += 2*d)
1 << (g+1)
替换为 2**(g+1)
for (k = J; k+d < (2**(g+1)); k += 2*d)
- 使上限包含在内:
j+d <= (2**g)-1
for (k = J; k+d <= (2**(g+1))-1; k += 2*d)
- 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
?
完整的奇偶合并排序算法可以在.
找到
我的下一步:
- 将循环范围移动到从零开始
for (k = 0; k <= (2**(g+1))-J-d-1; k += 2*d)
- 增量为
2*d
,但生成循环有1
。所以它必须通过除法归一化为1
。 k
必须重命名为 kk
:
for (kk = 0; kk <= ((2**(g+1))-J-d-1) / (2*d); kk++)
- 现在
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 时优化比较,但不确定。
我想将 C for loop
转换为 VHDL 中的 for..generate 语句。
这是怪物:
for (j = J; j+d < (2 << g); j += 2*d)
到目前为止我的步数:
- 将
j
重命名为k
以避免J
出现问题for (k = J; k+d < (2 << g); k += 2*d)
2 << g
替换为1 << (g+1)
for (k = J; k+d < (1 << (g+1)); k += 2*d)
1 << (g+1)
替换为2**(g+1)
for (k = J; k+d < (2**(g+1)); k += 2*d)
- 使上限包含在内:
j+d <= (2**g)-1
for (k = J; k+d <= (2**(g+1))-1; k += 2*d)
- 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
?
完整的奇偶合并排序算法可以在
我的下一步:
- 将循环范围移动到从零开始
for (k = 0; k <= (2**(g+1))-J-d-1; k += 2*d)
- 增量为
2*d
,但生成循环有1
。所以它必须通过除法归一化为1
。k
必须重命名为kk
:
for (kk = 0; kk <= ((2**(g+1))-J-d-1) / (2*d); kk++)
- 现在
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 时优化比较,但不确定。