verilogsystem-verilogvlsi

Reducing OR not working as expected when bit slicing in a loop


As for the title reducing OR not working as expected when bit slicing in a loop. This is an extract of what I have:

logic [3:0][1:0]  quad_mask_dq_qq; 
logic [1:0]       dfifo_rrdy_qq;


always_comb begin
         for (int qq = 0; qq < 2; qq++) begin
            dfifo_rrdy_qq[qq] =  (|quad_mask_dq_qq[2*qq +: 1]);
         end
end

Example of quad_mask_dq_qq = {2,0,0,1}

Expectation of dfifo_rrdy_qq = {1,1} what I actually got = {0,1}

My expectation are, writing it more explicitly, that the slicing would be the same as doing:

dfifo_rrdy_qq[0] = (|quad_mask_dq_qq[1:0]);

dfifo_rrdy_qq[1] = (|quad_mask_dq_qq[3:2]);

Is something with the looping I am not considering here?


Solution

  • In order to make this work you need to reduce two array elements at a time.
    The current design is reducing a single element.

    module tb ();
    
      logic [3:0][1:0] quad_mask_dq_qq = '{2'b10, 2'b00, 2'b00, 2'b01}; 
      logic [1:0]      dfifo_rrdy_qq;
      
      localparam NUM_ELEM_TO_REDUCE = 2;
    
      always_comb begin
    
        for (int qq = 0; qq < 2; qq++) begin
          //  dfifo_rrdy_qq[qq] =  ( | (quad_mask_dq_qq[2 * qq +: 1]));
    
          // ----------------------------------------------------------------
          // Reduce two elements at a time, not one
          // ----------------------------------------------------------------
          dfifo_rrdy_qq[qq] =  ( | quad_mask_dq_qq[2 * qq +: NUM_ELEM_TO_REDUCE] );
    
          $display("reduction = %0b", dfifo_rrdy_qq[qq]);
    
        end
      end
    
    endmodule
    

    Prints

    reduction = 1    
    reduction = 1
    

    In the part select operation a +: b
    the b term is the size ('take b elements starting at a')

    The code in the post reduces over one element.

    See IEEE 1800-2017 Standard for SystemVerilog Section 7.4.6 Indexing and slicing of arrays