I have a wire vector with 64 bits;
wire [63:0] sout;
I want to compute the sum of these bits or, equivalently, count the number of ones.
What is the best way to do this? (it should be synthesizable)
SystemVerilog has $countones to count number of ones in a bit vector. The more general form of this function is $countbits, which you can used to count 0, 1, x, or z in a bit vector. You can refer to LRM 20.9 for more information.
It returns the number of bits that have the value 1 in a variable. I typically use $countones(var_name) to quickly find out if a variable if one-hot encoded. $countones() is actually a convenience function associated with another system function $countbits() .
$bits. The $bits() system function returns the number of bits required to hold an expression as a bit stream. In the example below it is used to get the bitstream size of a struct and an array. One big advantage of the $bits() function is that it can be used as an elaboration time constant.
$countones Count number of bits in a vector with value high. $isunknown Check whether a vector has a bit with value x or z.
I prefer using for-loops as they are easier to scale and require less typing (and thereby less prone to typos).
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With