Pointers to internal objects inside the constraints

Hello,

Below is an example of constraints, where the first implementation doesn’t work, but the second is fine.
I was under the impression that the first implementation should work as well.

Any hint would be appreciated.

Alex

class my_class;

rand my_req_class my_req;

function new();
   $display("NEW!!!");
endtask

constraint my_req_length_cnstr {    // doesn't work
      my_req.length inside { [1:4] }; 
};
     
task my_task();
	my_req = new();
	my_req.randomize() with {length == 5;}; // works
endtask

endclass

In reply to alex_kr:

Actually below code works…

class my_req_class;
   rand int length;
endclass

class my_class;
   rand my_req_class my_req;
function new();
     my_req = new();
endfunction
   constraint len_c {
      my_req.length == 4; 
   }
endclass

module main;
   initial begin
     my_class i_a;
     i_a = new();
     i_a.randomize();
     $display("length = %0d",i_a.my_req.length);
   end
endmodule

In reply to alex_kr:

It would really help to show a complete example with both classes declared and how you called randomize() in the first case.

In reply to dave_59:

In reply to alex_kr:
It would really help to show a complete example with both classes declared and how you called randomize() in the first case.


class request_c extends uvm_sequence_item;
  `uvm_object_utils_begin(protocol_pkg::request_c)

   function new(string name="request");
      super.new(name);
   endfunction : new

   rand bit unsigned [13:0]   burst_length;
   constraint legal_constraint {
      burst_length inside {[1:4096]}; }

endclass : request_c


class single_protocol_seq_c extends uvm_sequence #(protocol_pkg::request_c, protocol_pkg::response_c);

  `uvm_object_utils_begin(block_pkg::single_protocol_seq_c)
  `uvm_object_utils_end

   rand protocol_pkg::request_c my_ip_req;

   function new(string name="single_protocol_seq");
      super.new(name);
      `cn_info(("block_basic_my_ip_vseq_lib: creating the single_protocol_seq_c now."))
       my_ip_req = protocol_pkg::request_c::type_id::create("my_ip_req");
   endfunction : new

   constraint my_ip_req_burst_length_cnstr {
      my_ip_req.burst_length == 1; 
   };

   virtual task body();
      `uvm_do(my_ip_req);     
      `uvm_info("burst_length = %d\n", my_ip_req.burst_length); // prints some number

      `uvm_do_with(my_ip_req, { burst_length == 1;});
      `uvm_info("burst_length = %d\n", my_ip_req.burst_length); // prints 1

   endtask : body

endclass

In reply to alex_kr:

Thank you for providing more context. Your problem is because you put the constraint in single_protocol_sequence_c, but the `uvm_do_with macro (which we recommend against using) hides the fact that you are just randomizing my_ip_req. You need randomize single_protocol_sequence_c.

virtual task body();
      req = request_c::type_id::create("req",this);
      start_item(req);
      if(!randomize()) `uvm_error("body","Randomization 1 failed");
      finish_item(req);
      `uvm_info("burst_length = %d\n", my_ip_req.burst_length); // prints some number inside 1-4096
 
      req = request_c::type_id::create("req",this);
      start_item(req);
      if(!randomize() with (req.burst_length == 1)) `uvm_error("body","Randomization 2 failed");
      finish_item(req);
      `uvm_info("burst_length = %d\n", my_ip_req.burst_length); // prints 1
endtask : body

BTW, there is no need to declare a separate my_ip_req; req is already declared in the uvm_sequence with the parameterized type.
[br][br]

In reply to dave_59:

“You need randomize single_protocol_sequence_c.” - oops. You are right. Thank you, Dave!