一个计算系统verilog

时间:2014-11-28 23:30:58

标签: system-verilog

我有一个64位的导线向量;

wire [63:0] sout;

我想计算这些位的总和,或者等价地计算1的数量。

最好的方法是什么? (它应该是可合成的)

3 个答案:

答案 0 :(得分:12)

我更喜欢使用for-loops,因为它们更容易扩展,并且需要更少的打字(从而更不容易出现拼写错误)。

SystemVerilog(IEEE Std 1800):

logic [$clog2($bits(sout)+1)-1:0] count_ones;

always_comb begin
  count_ones = '0;  
  foreach(sout[idx]) begin
    count_ones += sout[idx];
  end
end

Verilog(IEEE Std 1364-2005):

parameter WIDTH = 64;
// NOTE: $clog2 was added in 1364-2005, not supported in 1364-1995 or 1364-2001
reg [$clog2(WIDTH+1)-1:0] count_ones; 
integer idx;

always @* begin
  count_ones = {WIDTH{1'b0}};  
  for( idx = 0; idx<WIDTH; idx = idx + 1) begin
    count_ones = count_ones + sout[idx];
  end
end

答案 1 :(得分:0)

“最佳”是相当主观的,但简单而明确的表述只是:

wire [6:0] sout_sum = sout[63] + sout[62] + ... + sout[1] + sout[0];

你可能会认真思考并想出能产生更好合成结果的东西,但这可能是一个良好的开端,直到计时工具说它不够好。

答案 2 :(得分:0)

以下解决方案使用一个函数来计算64位宽总线中置位(为高)位的总数:

function logic [6:0] AddBitsOfBus (
    input [63:0] InBus
);
    AddBitsOfBus[2:0] = '0;
    for (int k = 0; k < 64; k += 1) begin // for loop
        AddBitsOfBus[6:0] +=  {6'b00_0000, InBus[k]};
    end
endfunction