A question about constraint how to get a random variable inside a defined array

Hello,

Here is the code I wrote.



class my_test extends uvm_test;

    `uvm_component_utils(my_test)

    function new(string name = "my_test", uvm_component parent = null);
        super.new(name, parent);
    endfunction

    extern function void build_phase(uvm_phase phase);
    extern task run_phase(uvm_phase phase);
    ...
    
    int my_arr[10] = {0,1,2,3,5,7,10,20,30,35};

    class my_fw extends uvm_object;
        rand int addr;
        rand int data;
        
        constraint my_cons {
            addr inside {my_arr};
            data == 0;
        }

    endclass : my_fw

endclass

and the error information is shown below.
Error-[SV-IRTAV] Illegal reference to automatic variable
Hierarchical reference to automatic variable ‘my_arr’ is not legal.

In reply to zz8318:

The problem here is with the use of nested class types, and a poor error message. They are not nested class objects. The nested class my_fw object needs a handle to the outer object. See 8.23 Class scope resolution operator :: in the 1800-2017 LRM.

In reply to dave_59:

I use below code instead of original one but still failed at the same error

    constraint my_cons {
        addr inside {my_test::my_arr};
        data == 0;
    }

In reply to zz8318:

Thats not enough. The inner class object needs a handle to the outer class object.

In reply to dave_59:

could you please kindly help to provide me more details or code ?

In reply to zz8318:

Hi Dave, I solve this problem with your help. Thanks a lot

In reply to dave_59:

Hi Dave ,

I have a question regarding randomize() call

I modified the above code to the following :



class Outer_Class ;
 
    typedef class nested ; 
    
    nested nest ;
    
    function new ();
    
      nest = new() ;
 
      nest.Initialize( this ); // NOTE !! . [Q1]  Will it work ?? . 
   
    endfunction 


    function bit RAND () ;
     bit b ;

      b = nest.randomize() ;
      if ( b )
      begin
       
       $display(" Success with %p ",nest);
 
      end
      return b ;

    endfunction

    int my_arr[10] = {0,1,2,3,5,7,10,20,30,35};
  

    class nested ;
     
     rand int addr;
     rand int data;
     Outer_Class oc ;
     
     function void Initialize ( input Outer_Class Outer_Object );

        oc =  Outer_Object ;
  
     endfunction

     function void pre_randomize() ;

      if ( oc == null )
      begin

        $display(" Null Object ") ;

      end

     endfunction

     constraint my_cons {                      
			  addr inside { my_arr};   
 // [Q2] Why won't it look into Upper Scope for my_arr [ Refer CODE 2 below ] ??   	
                          data == 0;
                        }
 
    endclass
 
endclass


[Q1] Am I correct in writing " nest.Initialize( this ); " .
Since I am still within the Constructor , will “this” Operate Correctly ?

[Q2] What is the Scope of the variables written within a constraint block ?

If I try the following code ::



// CODE 2 

module Main ;

int addr = 10 ; 


class A ;


function void DISP ();

 $display("  addr is %0d ",addr);

endfunction

endclass 


A a1 ;


initial begin

a1 = new() ;


a1.DISP();

end
endmodule


I get Output :: addr is 10 .

In this Case even though addr is outside the Class Scope , the code ran successfully .

" I went through the LRM and it talked about using in-line constraint to bypass the Default Scope of the randomize() call which is the Object itself ( Using which randomize( ) is Called)"

So I get that default scope of randomize() Call is the object

Regards ,
AGIS

In reply to Etrx91:

The only purpose of nested class declarations is hiding the class type from other classes. Try declaring class nested before class outer_class and get your code working. Then you can mover the nested class declaration inside the outer class.