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) 不是静态的,因为它取决于变量 AB.

您可以通过在 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

问题范围之外需要解决的问题:

他们使用 Btemp 的方式有点令人担忧。

  • 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