在 Verilog 生成循环中计算值的函数

Function to calculate a value inside a Verilog generate loop

我正在尝试为我在 Orcad 中实现的 BCD 华莱士树乘法器的乘法阶段创建一个参数化电路。我遇到的麻烦是我需要计算 BCD 乘法产生的每两个数字将驻留的位位置。 这是我的代码:

module bcd_mult_1_n #(parameter N = 8)
  (input [N * 4 - 1:0] num1, num2, output reg [2 * 4 * N * N - 1:0] partProds);

  genvar i, j;

  generate
    for(i = 0; i < N; i = i + 1) begin : dig1
      for(j = 0; j < N; j = j + 1) begin : dig2
        localparam lsd = posLSD(i, j);
        localparam msd = posMSD(i, j);
        bcd_mult_1 bcd_mult(num1[i * 4 + 3:i * 4], num2[j * 4 + 3:j * 4],
                            partProds[msd * 4 + 3:msd * 4], partProds[lsd * 4 + 3: lsd * 4]);
      end
    end
  endgenerate

在上面的代码中,numPrev(i + j) 需要 return 计算出这样的值

int numPrev(int x) {
  int acc = 0;
  for(int i = x; i > 0; i++) acc = acc + 2 * i;
  return acc;
}

感谢@Morgan 的帮助,我创建了以下函数;该逻辑旨在对从 1 上升到 N 然后下降到 1 的三角形值进行上下计数。

  function integer posLSD;
    input integer x, y;
    integer weight;
    integer acc;
    integer num;
    integer i;
    weight = x + y;
    acc = 0;
    if(weight >= N) num = N - 1;
    else num = weight;
    for(i = num; i > 0; i = i - 1)
      acc = acc + 2 * i;
    if(weight >= N) begin
      for(i = 2 * N - weight; i <= N; i = i + 1) begin
        acc = acc + 2 * i;
      end
      acc = acc + N - weight + y - 1;
    end
    else
      acc = acc + y;
    posLSD = acc;
  endfunction

  function integer posMSD;
    input integer x, y;
    integer acc;
    integer weight;
    acc = posLSD(x, y);
    weight = x + y;
    if(weight < N) acc = acc + weight + 1;
    else acc = acc + 2 * N - weight - 1;
    posMSD = acc;
  endfunction

我怎样才能实现这个功能?如果需要,我可以使用 SystemVerilog 结构。

当我更改为使用函数时出现错误Packed dimension must specify a range.我认为您需要考虑您的 partProds 宽度和连接。

使用函数:

module bcd_mult_1_n #(
  parameter N = 8
)  (
  input [N * 4 - 1:0] num1, 
  input [N * 4 - 1:0] num2, 
  output reg [2 * 4 * N * N] partProds
);

  integer prev = 1;
  genvar i, j;
  generate
    for(i = 0; i < N; i = i + 1) begin : dig1
      for(j = 0; j < N; j = j + 1) begin : dig2
        bcd_mult_1 
          bcd_mult(
            num1[i * 4 + 3:i * 4],
            num2[j * 4 + 3:j * 4], 
            partProds[numPrev(i+j) + 2*j + i + 1], 
            partProds[numPrev(i+j) + j]
          );
      end
    end
  endgenerate

  function numPrev;
    input integer x ;
    integer acc;
    begin
      acc = 0;
      for(int ij = x; ij > 0; ij++) begin
        acc = acc + 2 * ij;
      end
      numPrev = acc;
    end
  endfunction

endmodule

module bcd_mult_1(
  input [3:0]a,
  input [3:0]b,
  input c,
  input d
);

endmodule

示例 EDA Playground.