Access a module in generate block hierarchy

Hi All,

I want to access module instance name which is instantiated under generate block.
When I try to access module instance name using local veritable then QuestaSim gives following error:
A variable index into the generate block ‘’ is illegal.

Following is example code:


generate
  for(genvar d=0;d<MAXPORTS_USB3;d++) begin:dev_env
    dut_env #(
      ,.MAX_PORTS     (MAX_PORTS)
    ) dut2_env 
    (
    .interrupt_i  (usb3dev_irq_o[d] )
    );
  end
endgenerate

Code where I am trying to access varialbe ‘var_xyz’ which is in module “dut_env” :


Foreach(sys_q[i])  //sys_q is a queue
  begin
    fork
      automatic k = i;  
      begin
        abc = dev_env[k].dut2_env.var_xyx ;
      end
    join_none
  end
wait fork;

In reply to SandipGajera:
The code inside a generate-for loop gets unrolled and the scopes it creates are not like an array that you can index with a variable. Please see accessing task of generate block using hierarchy path | Verification Academy

In reply to dave_59:

Hi Dave,

Thanks for quick help.my problem is still not solved yet.

Three problems are there:

  1. I want to pass input arguments in my tasks ‘out_data_transfer’ and ‘in_data_transfer’.
    So please let me know that following code will work for this requirements ?
  2. In following code, line “device_data_array_h = new();” gives error in Questa Sim and the error is :
    near “=”: syntax error, unexpected ‘=’, expecting IDENTIFIER or TYPE_IDENTIFIER or NETTYPE_IDENTIFIER.
    If I add this line in initial block then it gives error : ‘new’ expression can only be assigned to a class or covergroup variable.
    but in this case ‘device_data_array_h’ is already a class
  3. Also I want to access variable from ‘dut_env’ module,Is it possible without task or function ?

//========================================================================
module abc;

localparam MAXPRT = 8;

virtual class device_data_array_c;
  pure virtual task out_data_transfer(ep_num,data_lenth);
  pure virtual task in_data_transfer(ep_num,data_lenth);
endclass

device_data_array_c device_data_array_h[MAXPRT];

genvar index;
  for(index = 0; index < MAXPRT; index++) begin :class_decl_loop
  class device_data_element_c extends device_data_array_c;
    task out_data_transfer(ep_num,data_lenth);
      dev_env[index].dut2_env.out_data_transfer(ep_num,data_lenth);
    endtask
    
    task in_data_transfer(ep_num,data_lenth);
      dev_env[index].dut2_env.in_data_transfer(ep_num,data_lenth);
    endtask
  endclass

  device_data_element_c device_data_element_h;
  device_data_array_h = new(); 

  initial 
  begin
    // device_data_array_h = new(); 
    device_data_array_h[index] = device_data_element_h;
  end
    
end : class_decl_loop

endmodule :abc
//========================================================================

In reply to SandipGajera:

  1. You need data types for your arguments; otherwise it assumes they are 1-bit. Also, you should use a function instead of a task for any routine that does not consume time. (no blocking statements)
  2. You have written a procedural assignment outside of a procedural context, and then you are trying use new() on the entire array - you can only use new() on one element at a time. You can call new() in the declaration initialization of device_data_element_h, or you can move the assignment into the initial block. But there’s an easier way that doesn’t involve the intermediate device_data_element_h variable. I’ll show that in an example.
  3. You will need to put the device_data_array class and handles in a package so that it can be shared with this module and any other module or package.
package dev_data_pkg;
 
virtual class device_data_array_c; // this could also be an interface class
  pure virtual function void out_data_transfer(int ep_num,data_lenth);
  pure virtual function void in_data_transfer(int ep_num,data_lenth);
endclass
 
device_data_array_c device_data_array_h[int];

endpackage

module abc;
import dev_data_pkg::*;

localparam MAXPRT = 8;

genvar index;
  for(index = 0; index < MAXPRT; index++) begin :class_decl_loop
  class device_data_element_c extends device_data_array_c;
    function void out_data_transfer(int ep_num,data_lenth);
      dev_env[index].dut2_env.out_data_transfer(ep_num,data_lenth);
    endtask
 
    function void in_data_transfer(int ep_num,data_lenth);
      dev_env[index].dut2_env.in_data_transfer(ep_num,data_lenth);
    endfunction
  endclass
 
  initial 
    device_data_array_h[index] = device_data_element_c::new() 
end : class_decl_loop
 
endmodule :abc

In reply to dave_59:

Thanks Dave for your quick help.Above solution works for my requirements.