基于位启用Verilog的值之和

时间:2016-05-07 01:59:26

标签: verilog fpga hdl

我是Verilog的新手,我试图写一个简单的代码,但我不知道如何以专家的方式做到这一点。 我有一个12位寄存器"数据",该寄存器的每一位都有一个特定的值。例如

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

现在,如果有任何"数据"寄存器为1然后结果应该是与该位值相对应的所有值的总和。 e.g。

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

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

谢谢

2 个答案:

答案 0 :(得分:1)

这取决于你所说的“快”。大概你的意思是时间,但要记住时间=周期/频率 - 减少周期数通常会降低电路工作的最大频率。

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

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。在你合成它之前,这是否会“更快”是不可能知道的(有太多的因素需要猜测)。

更好的多周期方法可能是使用树,即:

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

所有这一切,最终“最快”的方法还将取决于您系统的其他要求,您正在实施的内容等。

答案 1 :(得分:0)

您可以尝试以下内容: -

    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;