【问题标题】:Using multiple genvar in Verilog loop在 Verilog 循环中使用多个 genvar
【发布时间】:2013-12-23 22:38:48
【问题描述】:

是否可以在循环中使用不同的“genvar”?有没有其他的实现方式?

我试试这个例子:

genvar i;
genvar j;
genvar k;

generate 
    k=0;
    for (i = 0; i < N; i = i + 1) 
    begin: firstfor
            for (j = 0; j < N; j = j + 1)
            begin: secondfor
                if(j>i) 
                begin 
                    assign a[i+j*N] = in[i] && p[k];
                    k=k+1;      
                end
            end
    end 
endgenerate

当我运行“检查语法”时显示此错误:

Syntax error near "=". (k=k+1)

【问题讨论】:

    标签: for-loop syntax syntax-error verilog


    【解决方案1】:

    我喜欢这个问题,因为除非非常熟悉 generate,否则它看起来应该可以工作,但是 a similar question 会尝试使用额外的 genvar。

    由于生成的展开方式,不允许使用该语法。整数只能在 always/initial 进程中使用。

    如果它只是组合接线而不是参数化实例化,您也许可以只使用整数来做您需要的事情(我通常不推荐这样做):

    integer i;
    integer j;
    integer k;
    
    localparam N = 2;
    reg [N*N:0] a ;
    reg [N*N:0] in ;
    reg [N*N:0] p ;
    
    always @* begin 
      k=0;
      for (i = 0; i < N; i = i + 1) begin: firstfor
        for (j = 0; j < N; j = j + 1) begin: secondfor
          if(j>i) begin 
            a[i+j*N] = in[i] && p[k];
            k=k+1;      
          end
        end
      end
    end 
    

    不确定合成会如何,但分配是静态的,它可能会起作用。

    【讨论】:

    • 摩根——我刚刚在这里添加了一个答案。我在创建 Verilog 方面缺乏经验,想知道避免 always @* 的实际影响——除了“嘿,巧妙的技巧”之外,它是否必要/有用?
    【解决方案2】:

    当您想使用genvar 循环进行更高级的数学运算时,可以避免使用always @*。使用localparamfunction

    使用函数将k 设为派生自genvars 的localparam,并按原意使用k

    getk 函数似乎违反了代码重用原则,基本上是从 generate 块重新创建循环,但 getk 允许每个展开的循环迭代从 genvars i 派生不可变的局部参数 kj。在所有展开的循环中没有跟踪单独的累积变量kiverilogncvlog 都对此感到满意。

    (请注意,原始示例也可以使用 j=i+1 进行优化,但导出 k 仍然存在问题。)

    module top();
    
    localparam N=4;
    
    function automatic integer getk;
      input integer istop;
      input integer jstop;
      integer i,j,k;
      begin
        k=0;
        for (i=0; i<=istop; i=i+1) begin: firstfor
          for (j=i+1; j<((i==istop)? jstop : N); j=j+1) begin: secondfor
            k=k+1;
          end
        end
        getk=k;
      end
    endfunction
    
    genvar i,j;
    generate
      for (i = 0; i < N; i = i + 1) begin: firstfor
        for (j = i+1; j < N; j = j + 1) begin: secondfor
          localparam k = getk(i,j);           
          initial $display("Created i=%0d j=%0d k=%0d",i,j,k);
        end
      end
    endgenerate
    
    endmodule
    

    输出:

    $iverilog tmptest.v $ ./a.out 创建 i=0 j=1 k=0 创建 i=0 j=2 k=1 创建 i=0 j=3 k=2 创建 i=1 j=2 k=3 创建 i=1 j=3 k=4 创建 i=2 j=3 k=5

    我在这里发现了使用函数从 genvar 中获取值的“技巧”: https://electronics.stackexchange.com/questions/53327/generate-gate-with-a-parametrized-number-of-inputs

    【讨论】:

    • 我认为这是一个更好的解决方案,用于生成静态值(localparam)。如果你想创建一个赋值映射,即组合逻辑,你需要assignalways @*
    • @Morgan - 谢谢。我主要完成了原理图->结构 Verilog 工作。我在玩generate,因为我有一个面向原理图的心态。但我认为我过度使用了它,并为组合功能创建了过于精细的结构(层次结构+连线),使用always 和特定的敏感度列表可以更简单。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-12
    相关资源
    最近更新 更多