Verilog:添加寄存器的各个位(组合逻辑,寄存器宽度可参数化)

时间:2013-06-18 01:44:29

标签: verilog system-verilog

我试图找到一种方法来添加寄存器的各个位。 例如,if regA = 111000 then regB = 3regA的位总和)。 1)Verilog或SystemVerilog中是否有可合成的函数/运算符可以直接用于执行此操作?

如果没有,那么问题可能有点有趣,特别是因为操作必须在一个时钟周期内进行(纯组合逻辑)并且寄存器宽度是可参数化的。

2)如果没有内置的Verilog或SystemVerilog操作符,那么可以做什么?

谢谢, Ujjwal

2 个答案:

答案 0 :(得分:6)

Verilog(IEEE Std 1364-2001或更新版):

integer i;
always @* begin
  B = WIDTH_LOG2'b0;
  for (i=0; i<WIDTH; i=i+1)
    B = B + A[i];
end

SystemVerilog(IEEE Std 1800-2005或更新版):

always_comb begin
  B = '0; // fill 0
  foreach(A[i])
    B += A[i];
end

两者都将合成到组合逻辑。没有闩锁或翻牌。

SystemVerilog确实有$countones(),但我不确定它是否可以合成。如果是:always_comb B = $countones(A)

答案 1 :(得分:2)

你可以尝试这样的事情。我不确定它将合成什么,但它应该有效。

int i; 
reg [`WIDTH-1:0]    A;
reg [`WIDTH_LOG2:0] B;

B = 0;

for(i = 0; i < `WIDTH; i = i + 1)
begin
   B = B + A[i];
 end

当然,有更复杂的方法可能会有更好的性能,具体取决于您的工具流程和可用内容,您可以在其中创建自己的加法器并将它们并行级联,从而减小每个步骤的大小。假设宽度为32位,类似于:

 adder1bit_1(output1, A[31:24]); 
 adder1bit_2(output2, A[23:16]);
 adder1bit_3(output3, A[15:8]);
 adder1bit_4(output4, A[7:0]);

 adder3bit_1(output5, output1, output2);
 adder3bit_2(output6, output3, output4);

 adder4bit(final_ouput, output5, output6);