Search code examples
moduleinterfacesystem-verilog

How to set a param or variable in a generate block to run another generate block


I wanted to loop-in a generate block 'gen_for_il1' which resides in an interface file. The scenario is that I have to run this loop based on a value captured from another generate block 'gen_for1'. However, I don't know which definition to use to the capture value. I tried defining it as a parameter (line 9) as shown in Example1 and a logic variable (line 3) as shown in example2. In both the cases I am blocked by different compilation error. Any idea how i can achieve this requirement? Any help here is appreciated.

FYI, For simplicity param1 is shown as a simple variable here, but in real case, param1 is dependent on generate block and genvar variables since it is accessed through a hierarchy of array of modules to capture value for param1.

//Example1: 
interface test2;
logic [7:0] tydef_sig;

genvar i,j;
generate 
for (i=0; i<2; i++) begin: gen_for1
  for (j=0; j<2; j++) begin: gen_for2
    parameter param1 = 4; // line 9, the value set in here will run the generate block 'gen_for_il1'
  end
end
endgenerate

genvar i1;
generate 
for (i1=0; i1<param1; i1++) begin: gen_for_i1  // line 16
  assign tydef_sig[i1] = 'b1;
end
endgenerate

endinterface

module test4;
  test2 test2_intf();
  initial begin
    $display("tydef_sig=%0b",test2_intf.tydef_sig);
  end
endmodule

Error-[IND] Identifier not declared, line 16

Identifier 'param1' has not been declared yet. If this error is not expected, please check if you have set `default_nettype to none.

I tried providing generate block hierarchy to access param1 in line 16. like this;

for (i1=0;i1<gen_for1[0].gen_for2[0].param1; i1++) begin: gen_for_i1

Still, it didn't work for me.

Error-[V2KGEUV] Unknown or bad value for genvar

Example2, where i tried a int variable instead of a parameter.

//Example2:
interface test2;

int param1[2][4]; // line 3
logic [7:0] tydef_sig;

genvar i,j,k;
generate 
  for (i=0; i<2; i++) begin: gen_for1
    for (j=0; j<2; j++) begin: gen_for2
      assign param1[i][j] = 2;                   
    end
  end
endgenerate

genvar i1;
generate 
  for (i1=0;i1<gen_for1[0].gen_for2[0].param1[0][0]; i1++) begin: gen_for_i1 // line 19
    assign tydef_sig[i1] = 'b1;
  end
endgenerate

endinterface

module test4;
  test2 test2_intf();
  initial begin
    $display("tydef_sig=%0b",test2_intf.tydef_sig);
  end
endmodule

Error-[V2KGEUV] Unknown or bad value for genvar, line 19

..


Solution

  • It is not possible to code what you are asking given the requirements you have listed. This is an XY problem.

    Your first attempt does not work because the single reference to param1 is ambiguous. There are 4 declarations of param1 and you only need one of them.

    Your second attempt does not work because you are not allowed to have hierarchical references to other parameters. This is because the order of elaboration is not defined and you cannot have generate block depend on another.

    Your third attempt does not work because variables get initialized at run-time, after elaboration of the generate blocks.

    If you could your change your first generate block into a constant function, then we can get your original example to work

    interface test2;
    
      typedef int a_2_4[2][4]; // need typedef to allow unpacked array return
    
      parameter a_2_4 param1 = f();
      function a_2_4 f;
        for (int i=0; i<2; i++) 
          for (int j=0; j<2; j++) 
            f[i][j] = 2+i*j;                   
      endfunction
        
      logic [7:0] tydef_sig;
    
      for (genvar i1=0;i1<param1[0][0]; i1++) begin: gen_for_i1 
            assign tydef_sig[i1] = 'b1;
      end
    
    endinterface
    

    But without seeing the rest of your code, or at least all the requirements needed for this particular piece, we cannot give you a better solution.