【问题标题】:Ones count system-verilog计数系统-verilog
【发布时间】:2014-11-28 23:30:58
【问题描述】:

我有一个 64 位的线向量;

wire [63:0] sout;

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

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

【问题讨论】:

  • 我猜投反对票是因为你没有发布你试图解决的问题。
  • 是的。因为我不知道从哪里开始,没有贾里德戴维斯的回答。这就是我目前所拥有的,但肯定有一种更简洁的方式来写这个。

标签: system-verilog


【解决方案1】:

我更喜欢使用 for 循环,因为它们更容易扩展并且需要更少的输入(因此更不容易出现拼写错误)。

SystemVerilog(IEEE 标准 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 标准 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

【讨论】:

    【解决方案2】:

    “最佳”是相当主观的,但一个简单明了的表述就是:

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

    您也许可以认真思考并想出一些可以产生更好的综合结果的方法,但这可能是一个好的开始,直到计时工具说它还不够好。

    【讨论】:

      【解决方案3】:

      以下解决方案使用一个函数来计算 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多