Is there a way to get around a generate for loop allowing only one genvar variable

I realized that the generate for loop does not allow two variables and I cannot determine if there is a way to get around it. I have an example below where based on priority I get the right a_vals and c_vals out but I cannot do the same using generate statements to get ga_vals and gc_vals. The generate section does not work because of syntax issue while the always_comb does - is there an elegant way to accomplish this with generate statements? Please see example below. Thanks

module test1 #( 
                parameter int    NA = 3, 
                parameter int    NC = 2, 
                parameter int    NT = (NA+NC), 
                parameter string PRIORITY [(NT-1):0] = {"C", "A", "C", "A", "A"}
                ) 
   (
    output logic [(NA-1):0] a_vals, 
    output logic [(NC-1):0] c_vals, 
    output logic [(NA-1):0] ga_vals, 
    output logic [(NC-1):0] gc_vals
    );

   logic [(NT-1):0]         t_vals;


   initial
     begin
        t_vals = 5'b10001;
        for (int i = 0; i < NT; ++i)
          $display("Priority is %s\n", PRIORITY[i]);
        #10 
          $display("t_vals is %b, a_vals is %b and c_vals is %b \n", t_vals, a_vals, c_vals);
        #10 
          $display("t_vals is %b, ga_vals is %b and gc_vals is %b \n", t_vals, ga_vals, gc_vals);
        #10 $finish;
     end

// This does not work - syntax issues
   generate
      int y = 0;
      for (genvar x =0; x < NT; ++x)
        if (PRIORITY[x] == "A") 
          assign ga_vals[x-y] = t_vals[x];
        else if (PRIORITY[x] == "C") 
          begin
             assign gc_vals[y] = t_vals[x];
             y++;
          end

   endgenerate

// This works
   always_comb
     begin
        for (int i =0, int j=0; i < NT; ++i)
          if (PRIORITY[i] == "A") 
            a_vals[i-j] = t_vals[i];
          else if (PRIORITY[i] == "C") 
            begin
               c_vals[j] = t_vals[i];
               j++;
            end
     end

endmodule

Here is an approach you can take declaring parameters for each iteration of the loop. I don’t have this completely debugged, but this should get you started.

   generate
      for (genvar x =0; x < NT; ++x) begin : loop
        if (PRIORITY[x] == "A") begin : block
          parameter y = x==0 ? 0 : loop[x?x-1:0].block.y; // make sure you don' reference out of bounds
          assign ga_vals[x-y] = t_vals[x];
        end
        else if (PRIORITY[x] == "C") begin :block
            parameter y = x==0 ? 0 : loop[x?x-1:0].block.y+1;
             assign gc_vals[y] = t_vals[x];
          end
      end : loop
   endgenerate

Hi @dave_59
what does it mean the syntax above inside loop[x?x-1:0]?

That is just a simple ternary operator. It’s just a trick to avoid a negative index when x is zero. Although that expression might never be evaluated, the compiler will still attempt to resolve it.

1 Like