根据Verilog

时间:2018-02-05 20:47:15

标签: verilog

我在Verilog中有一个1023位向量。我想要做的就是检查第i位是否为1,如果是1,我必须添加' i'到另一个变量。

在C中,它将类似于:

int sum=0;
int i=0;
for(i=0;i<1023;i++) {
if(a[i]==1) {
sum=sum+i;
}

当然,我正在做的补充是在伽罗瓦场上。所以,我有一个名为Galois_Field_Adder的模块来进行计算。 所以,我现在的问题是如何有条件地检查特定位是否为1,如果是,请调用我的模块进行特定添加。

注意:1023位向量被声明为输入。

1 个答案:

答案 0 :(得分:0)

如果没有看到您的模块,很难回答您的问题,因为我们无法衡量您在Verilog中的位置。你总是要考虑你的代码如何在门中翻译。如果我们想将您的C代码转换为可合成逻辑,我们可以采用相同的算法,逐个遍历每个位,并根据每个位添加总和。你会使用这样的东西:

module gallois (
  input   wire            clk,
  input   wire            rst,
  input   wire  [1022:0]  a,
  input   wire            a_valid,
  output  reg   [18:0]    sum,
  output  reg             sum_valid
);

reg [9:0]    cnt;
reg [1021:0] shift_a;

always @(posedge clk)
if (rst)
begin
  sum[18:0] <= {19{1'bx}};
  sum_valid <= 1'b0;
  cnt[9:0] <= 10'd0;
  shift_a[1021:0] <= {1022{1'bx}};
end
else
  if (a_valid)
  begin
    sum[18:0] <= 19'd0;
    sum_valid <= 1'b0;
    cnt[9:0] <= 10'd1;
    shift_a[1021:0] <= a[1022:1];
  end
  else if (cnt[9:0])
  begin
    if (cnt[9:0] == 10'd1022)
    begin
      sum_valid <= 1'b1;
      cnt[9:0] <= 10'd0;
    end
    else
      cnt[9:0] <= cnt[9:0] + 10'd1;

    if (shift_a[0])
      sum[18:0] <= sum[18:0] + cnt[9:0];

    shift_a[1021:0] <= {1'bx, shift_a[1021:1]};
  end

endmodule

您将在1023个时钟周期后获得结果。这个代码需要根据它的变化,你想要的接口等进行修改...... 这里重要的是我们使用移位寄存器来测试每个位,因此添加和的逻辑只需要shift_a [0],sum和cnt作为输入。 基于以下内容的代码也适用于模拟:

if (a[cnt[9:0])
  sum[18:0] <= sum[18:0] + cnt[9:0];

但是添加到sum的逻辑实际上将[]的所有1023位作为输入。这很难变成实际的查找表。

在模拟中,您还可以实现非常粗糙的内容,例如:

reg   [1022:0]a;
reg   [9:0] sum;
integer i;

always @(a)
begin
  sum[9:0] = 10'd0;
  for (i=0; i < 1023; i=i+1)
    if (a[i])
      sum[9:0] = sum[9:0] + i;
end

如果你试图综合这个,总和实际上会变成一大堆组合逻辑,因为总是&#39;阻止不依赖于时钟。这段代码实际上等同于:

always @(a)
  case(a):
    1023'd0: sum[18:0] = 19'd0;
    1023'd1: sum[18:0] = 19'd1;
    1023'd2: sum[18:0] = 19'd3;
    etc...

毋庸置疑,具有1023个输入位的查找表是一个非常大的内存...

然后,如果您想改进代码,并将FPGA用作FPGA而不是CPU,则需要开始考虑并行性,例如在输入的不同范围内并行工作a。但这是另一个线索......