Using an index as part of signal with full design hierarchy

can anyone tell me how to access a signal with an array index in its hierarchy?

for example , conside signal : top.a.b[0].signal_name

instance b is an array [4:0] .
rand int x;

int i;

i = x;
when i am using force top.a.b[i].singal_name , am hitting in to error "index is not constant " , how to avoid this?

In reply to Kartheek Domakuntla:

Because of the possibility of parameter overriding, arrays of instances are not true arrays where each element has an identical type. You cannot index them dynamically with a variable. You will have to use either a generate-for loop, or a case statement.

case(i)
0: force top.a.b[0].signal_name =
1: force top.a.b[1].signal_name =
2: force top.a.b[2].signal_name =
3: force top.a.b[3].signal_name =
4: force top.a.b[4].signal_name =
endcase

In reply to dave_59:

Thanks Dave. But i have like 70 instances of module. I cant use Case for each instance , 70 times . I need see if i can meet my requirement any other way.

In reply to Kartheek Domakuntla:

You can use the Abstract/Concrete class design pattern

module top;
  a b[0:69] ();
endmodule
module a;
  wire signal;
  always @signal $display("%t %m.signal %v",$realtime,signal);
endmodule
      
module test_top;
  virtual class enforcer; // abstract class used to build list
    static enforcer list[int];
    function new(int index);
      list[index] = this;
    endfunction
    pure virtual function void do_force(bit [31:0] value);
    pure virtual function void do_release;
  endclass
  for (genvar i=0; i<70; i++) begin
    class enforcer_concrete extends enforcer;
      function new(int index);
        super.new(index);
      endfunction
      static bit [31:0] m_value; //RHS of force can only contain "static" variables
      function void do_force(bit [31:0] value);
        m_value = value;
        force top.b[i].signal = m_value;
      endfunction
      function void do_release;
        release top.b[i].signal;
      endfunction
    endclass
    enforcer_concrete h = new(i);
  end
  
  initial repeat(10) begin
    int x;
    x = $urandom_range(69);
    #10 enforcer::list[x].do_force(0);
    #10 enforcer::list[x].do_release;
  end
endmodule

Also see how to drive the signals which is inside DUT | Verification Academy

In reply to dave_59:

Hi Dave,

Why do we need to use an abstract class here? Can’t we do exactly what enforcer_concrete is doing in a regular class? I didn’t understand the need/value behind use of abstract class in this context.