for循环verilog的更好选择
better alternative on for loop verilog
我是verilog的新手。我一直在网上搜索,大多数人都建议不要在 verilog 编码中使用 for-loop。那么有没有更好的替代方法来替代 for-loop 呢?
我现在面临的问题是我需要在 case 语句中执行 1 或 2 个 for 循环。我一直在考虑更好的选择,但想出了 none。如果你们中的任何人能对此有所了解,那就太好了。
我的代码示例:
always @(*)
case (help)
4'd1: for (i=A; i<=20;i=i+B)
begin temp[i-1]=1; end
4'd2: for (i=A; i<=20;i=i+B)
begin temp[i-1]=1; B=B+1; end
4'd3: begin
for (i=A; i<=20;i=i+B)
begin temp[i-1]=1; B=B+1; end
for (i=A; i>=1;i=i-B)
begin temp[i-1]=1; B=B+1; end
end
default: temp = 0;
For 循环在 Verilog 中很好,但如果您计划进行综合,它们需要能够静态展开。静态展开意味着循环不依赖于任何外部变量。例如 for(i=0;i<10;i=i+1)
是静态的。 for(i=A; i<=20;i=i+B)
不是静态的,因为它取决于变量 A
和 B
.
您可以通过在 for 循环内移动变量作为条件来使循环静态化。 for(i=A; i<=20;i=i+B)
变为:
tmp_var = A;
for (i=0; i<=20;i=i+1) begin
if (i==tmp_var) begin
// ... your logic here ...
tmp_var = tmp_var+B;
end
end
问题范围之外需要解决的问题:
他们使用 B
和 temp
的方式有点令人担忧。
B
似乎是一个输入,但您也在增加它。对于合成,操纵输入是非法的。如果它是输入,则创建一个默认值为 B
的局部变量,您稍后可以在同一个 always 块中更改此值。如果它不是输入,那么它正在创建锁存逻辑;这不好,接下来我将用 temp
.
来介绍
temp
是锁存逻辑。锁存逻辑很麻烦,因为时序很关键;知道闩锁何时透明或关闭,并遵守保持时间要求。逻辑越复杂,就越难预测。在 RTL 中,推断锁存器的一种方式是通过组合块内的不完整分配(即 always @*
)。要解决此问题,请确保在组合块的每次传递中都为每个位分配了值。保护这一点的一种方法是在启动逻辑之前分配默认值。示例:
always @(*) begin
temp = 0; // default to a constant
temp_B = B; // default to an input value
// ... your logic ...
end
我是verilog的新手。我一直在网上搜索,大多数人都建议不要在 verilog 编码中使用 for-loop。那么有没有更好的替代方法来替代 for-loop 呢? 我现在面临的问题是我需要在 case 语句中执行 1 或 2 个 for 循环。我一直在考虑更好的选择,但想出了 none。如果你们中的任何人能对此有所了解,那就太好了。
我的代码示例:
always @(*)
case (help)
4'd1: for (i=A; i<=20;i=i+B)
begin temp[i-1]=1; end
4'd2: for (i=A; i<=20;i=i+B)
begin temp[i-1]=1; B=B+1; end
4'd3: begin
for (i=A; i<=20;i=i+B)
begin temp[i-1]=1; B=B+1; end
for (i=A; i>=1;i=i-B)
begin temp[i-1]=1; B=B+1; end
end
default: temp = 0;
For 循环在 Verilog 中很好,但如果您计划进行综合,它们需要能够静态展开。静态展开意味着循环不依赖于任何外部变量。例如 for(i=0;i<10;i=i+1)
是静态的。 for(i=A; i<=20;i=i+B)
不是静态的,因为它取决于变量 A
和 B
.
您可以通过在 for 循环内移动变量作为条件来使循环静态化。 for(i=A; i<=20;i=i+B)
变为:
tmp_var = A;
for (i=0; i<=20;i=i+1) begin
if (i==tmp_var) begin
// ... your logic here ...
tmp_var = tmp_var+B;
end
end
问题范围之外需要解决的问题:
他们使用 B
和 temp
的方式有点令人担忧。
来介绍B
似乎是一个输入,但您也在增加它。对于合成,操纵输入是非法的。如果它是输入,则创建一个默认值为B
的局部变量,您稍后可以在同一个 always 块中更改此值。如果它不是输入,那么它正在创建锁存逻辑;这不好,接下来我将用temp
.temp
是锁存逻辑。锁存逻辑很麻烦,因为时序很关键;知道闩锁何时透明或关闭,并遵守保持时间要求。逻辑越复杂,就越难预测。在 RTL 中,推断锁存器的一种方式是通过组合块内的不完整分配(即always @*
)。要解决此问题,请确保在组合块的每次传递中都为每个位分配了值。保护这一点的一种方法是在启动逻辑之前分配默认值。示例:always @(*) begin temp = 0; // default to a constant temp_B = B; // default to an input value // ... your logic ... end