for 循环 verilog 的更好替代方案

Sha*_*Kho 2 for-loop verilog

我是verilog的新手。我一直在网上搜索,大多数人建议不要在verilog编码中使用for循环。那么有没有更好的替代方法来替代for循环呢?我现在面临的问题是我需要在一个 case 语句中执行 1 或 2 个 for 循环。我一直在考虑更好的替代方案,但没有想到。如果你们中的任何一个人能够阐明这一点,那就太好了。

我的代码示例:

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;
Run Code Online (Sandbox Code Playgroud)

Gre*_*reg 5

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
Run Code Online (Sandbox Code Playgroud)

超出问题范围需要解决的问题:

您正在使用它们的方式有点令人担忧Btemp

  • B似乎是一个输入,但您也在增加它。对于综合来说,操纵输入是非法的。如果它是输入,则创建一个默认值为 as 的局部变量B,您可以稍后在同一个始终块中更改该值。如果它不是输入,则它正在创建锁存逻辑;这不好,接下来我将用 来介绍它temp

  • temp是锁存逻辑。锁存逻辑很麻烦,因为时序很关键;了解锁存器何时透明或关闭,并遵守保持时间要求。逻辑越复杂,预测就越困难。在 RTL 中,推断锁存器的一种方式是通过组合块内的不完整分配(即always @*)。要解决此问题,请确保组合块的每次传递都分配给每个位。保护这一点的一种方法是在开始逻辑之前分配默认值。例子:

      always @(*) begin
        temp = 0; // default to a constant
        temp_B = B; // default to an input value
    
        // ... your logic ...
      end
    
    Run Code Online (Sandbox Code Playgroud)