Accessing class variables in a for loop

class A;
  rand bit[1:0] vindex_0; 
  rand bit[1:0] vindex_1; 
  rand bit[1:0] vindex_2; 
endclass



module test;


 initial begin
   A a;
   string idx;
    a = new();
    void'(a.randomize);
    for(int i=0; i<3; i++) begin
     idx = $sformatf("vindex_%0d",i);
     $display("idx: %s",idx); 
     $display("Print members of class a\n item value: %h, at: %0d\n",a.idx,i); 
    end
 
 end


endmodule

But, I get compile error as below:

Error-[MFNF] Member not found
test.sv, 20
“a.”
Could not find member ‘idx’ in class ‘A’, at “test.sv”, 1.

Why isn’t the code working as if I print idx it gives correctly vindex_0, vindex_1 and vindex_2 etc.

The reason is because your class A only contains three variables, vindex_0, vindex_1 and v_index2. There is no variable ‘idx’.

You can not de-reference a variable by creating a string that matches the variable name.

In reply to cgales:

Hi,

On the similar lines, I have a question:
We can form a string from a variable name using defines and ".
Similarly can we form a variable name from a string and use it?

Example:

  `define my_object_reg(NAME) \
     VtssUvmObject uvm_obj_hdl_``NAME = VtssUvmObject::get_handle(`"NAME`");

This macro if I call like this:

class cl;
int a_var;
`my_object_reg(a_var);
endclass:cl;

It would create a handle uvm_obj_hdl_a_var of type VtssUvmObject, and also passes the string argument (“a_var”) to the get_handle function call.

Similarly, if I have a string “a_var”, can I use some sort of define macros to convert string to a variable name? I tried below but I dont think it completely works:

`define field_name2(ARG) ARG
     `define field_name(ARG) `field_name2(`"ARG`")

So if I call somewhere in the above class:

class cl;
int a_var;
`my_object_reg(a_var);

function void display_val();
int interm = this.`field_name("a_var");

$display("Value present in this.a_var is %0d",interm);
endfunction:display_val;

endclass:cl;

I just tried to use one field_name macro to get the variable name from string, but I could not get it compiling, so I used two nested macros, which got compiled, but the display prints some value other than what a_var was assigned to.

In reply to Sailaja:

You must remember that macros are pre-processor compiler directives that substitute text for their arguments before any SystemVerilog syntax is parsed
When you invoke the macro `my_object_reg(a_var), you are not passing a variable, but a token of text. That token of text will be substituted to form what will become a variable name and a string.

     VtssUvmObject uvm_obj_hdl_a_var = VtssUvmObject::get_handle("a_var");

The line

int interm = this.`field_name("a_var");

should have expanded to


int interm = this.""a_var"";

and produced a compiler error. If you are using Questa, you can use vlog -E file to have the output of the pre-processor saved in a file. If it does not produce a compiler error, then that is likely a tool bug.

In reply to dave_59:

Hi Dave,

I understand that when invoke a macro, it just inserts with whatever that macro was defined.
My question is is there any way where in if a string is passed as an argument to define macro, the quotes are removed and the pre-processor inserts the unquoted string.
So if I say:
`define unquoted_string(ARG) MY NAME IS ARG // __ Something like this .

and call:
`unquoted_string(“ALICE”)

the macro should be expanded by the pre-processor to: MY NAME IS ALICE // __ Remember that ALICE Argument to the macro had quotes, now the output is printed to be unquoted.

Thanks for the -E switch.

-Sailaja.

In reply to Sailaja:

No, that is not how it works. The pre-processor only recognizes tokens like identifiers, whitespace, symbols, string literals and comments. It does not understand SystemVerilog syntax. It can replace one token for another, and can join tokens to form new tokens. The token ARG in the body of your macro will be replaced by string literal token “ALICE”
The two in your macro body don't do anything because the first joins the token that ARG will be replaced with with a whitespace token (I’m not even sure if that is legal). The second `` is never seen because it is part the comment

So the replacement text for your macro invocation is

MY NAME IS “ALICE”