基于启用 Verilog 的位的值总和

Sum of Values based on bits enabled Verilog

我是 Verilog 的新手,我试图编写一个简单的代码,但我不确定如何以专家的方式进行。 我有一个 12 位寄存器 "data",该寄存器的每一位都有一个特定的值。例如

Bit 0 = 12;
Bit 1 = 16;
Bit 2 = 33;
......
Bit 11 = 180;

现在如果"data"寄存器的任何一位为1,那么结果应该是对应于该位值的所有值的总和。例如

data = 12'b100000000101
result = 225 (180+33+12)

现在我正在检查每一位数据,如果它是1那么我注册相应的值并将其添加到之前的注册值中。此方法需要循环数。 我怎样才能在verilog中快速完成。

谢谢

你可以试试下面的方法:-

    reg [15:0] sum;
    always @(*)begin    
       for (i=0;i<12;i++)begin
         if (data[i]) 
         sum = sum+Bit[i];
       end //for
    end //always
    assign finalSum = |data ? finalSum: 'h0;

这取决于你所说的 "fast" 是什么意思。大概你指的是时间,但请记住 time=cycles/frequency - 减少周期数通常会降低电路可以运行的最大频率。

例如,这是一个在一个周期内完成整个加法运算的电路:

always@(*) begin
    tempsum = 0;
    tempsum = tempsum + (data[0]? 12:0);
    tempsum = tempsum + (data[1]? 16:0);
    tempsum = tempsum + (data[2]? 33:0);
    //...
end
always@(posedge clock)
    result <= tempsum;

如果您合成此电路,您会看到一长串加法器。 In 可以在单个周期内计算出结果,但关键路径很长,因此 fMax 较低。这是否是 "faster" 在综合之前是不可能知道的(有太多因素无法猜测)。

更好的多循环方法可能是使用树,即:

reg [31:0] sum [29:0];
always @ (posedge clock) begin
    // level 0
    sum[0] <= (data[0]? 12:0) + (data[1]? 16:0);
    sum[1] <= (data[2]? 33:0) + (data[3]? 40:0);
  // ...
    sum[15] <=  (data[30]? 160:0) + (data[31]? 180:0);
    // level 1
    sum[16] <= sum [0] + sum [1];
    sum[17] <= sum [2] + sum [3];
  // ...
    sum[23] <= sum [14] + sum [15];
    // level 2
    sum[24] <= sum [16] + sum [17];
    sum[25] <= sum [18] + sum [19];
  // ...
    // level 3
    sum[28] <= sum [24] + sum [25];
    sum[29] <= sum [26] + sum [27];

    result <= sum [28] + sum [29];
end

综上所述,"fastest" 方法最终还取决于您系统的其他要求、您在什么基础上实施它等。