verilogsystem-verilogsynthesisregister-transfer-level

How to invert a bit of a packed array


logic [4:0] count_zeros;
logic [2:0] id;
integer i;
logic [7:0] [15:0] vld;

always@*
begin
  count_zeros = 5'b0; 
  for (i=0; i<2; i=i+1)
    count_zeros = count_zeros + ~vld[id][i];
end

For an input as d8, I get count_zeros as 1e. My expected output is 2. What is wrong in the above snippet?

~ is a bitwise negation and ! is logical negation. Where am I going wrong?


Solution

  • Verilog expands the single bit value (vld[id][i]) to match the width of the expression it is in, which is 5 bits because of the count_zeros signal. This is done before the bitwise invert operator is applied. Since vld[0][0] is 1'b0, 1'b0 is expanded to 5'b00000. Then~(5'b00000) results in 5'b11111.

    Create a 1-bit signal, such as temp, and directly set it to the inverted bit value. Then use it in the addition expression.

    logic temp;
    
    always @* begin
        count_zeros = 5'b0;
        for (i=0; i<2; i=i+1) begin
            temp = ~vld[id][i];
            count_zeros = count_zeros + temp;
        end
    end
    

    Refer to IEEE Std 1800-2017, section 11.6 Expression bit lengths.