Constrained randomization

Hi Experts,

I am new to UVM. Just started working on it. I have the following query on randomizing variables defined in sequence class from the test. Please help on this.

class sample_sequence extends uvm_sequence();
rand int num_seq;
`uvm_object_utils_begin(sample_sequence )
	`uvm_field_int(num_seq, UVM_ALL_ON);
`uvm_object_utils_end

//code for sequence generation
...............
...............
...............


endclass: sample_sequence 

How do i randomize variable num_seq from the test before invoking this sequence??

Thanks for your inputs in advance.

In reply to chethan2807:
You call randomize() before starting it in your test.

task my_test::run_phase(uvm_phase phase);
   ...
   seq = simple_sequence::type_id::create(...);
   if (!seq.randomize()) `uvm_fatal("RANDOMFAIL","Could not randomize sequence");
   seq.start();
...
endtask

1 Like

In reply to dave_59:

Hi Dave,

Thank you so much for the answer. If i understood correctly seq.randomize() will randomize the entire sequence, what if i want to randomize any particular variable defined in the sequence rather all??.

In reply to chethan2807:

Probably not a good idea, but you have three choices:

  1. Use rand_mode(0) to turn of the random variables you do not want randomized
  2. using seq.randomize(num_seq) will randomize just num_seq, all active constraints are still considered.
  3. using std::randomize(seq.num_seq) will randomize just num_seq, only the constraints provided using the with{} clause are considered.

I say this is not recommended because once you start randomizing class variables one at a time, it becomes difficult to randomize the entire class and preserve the previously generated random variables.

In reply to dave_59:

Hi Dave,

Thank you very much for the detailed explanation.

My intention is not to randomize any of the transaction item variable from a test case rather, I was trying to control number of sequence to be generated from a test by randomizing the variable defined inside a sequence.

Here is what i meant. sram_test → sram_sequence → sram_transaction

class sram_test extends sram_base_test;

  sram_sequence sram_seq;

  `uvm_component_utils(sram_test)

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

  virtual function void build_phase(uvm_phase phase);

    super.build_phase(phase);
   
    sram_seq = sram_sequence::type_id::create( "sram_seq", this);
	uvm_config_db#(int)::set(this,"sram_ev.sram_agt.monitor", "check_enable", 1);
	uvm_config_db#(int)::set(this,"sram_ev.sram_agt.sram_seqr", "num_seq", 5);
	
	endfunction : build_phase

  task run_phase (uvm_phase phase);

     `uvm_info(get_type_name(), "Running sram_test ...", UVM_MEDIUM)
     phase.raise_objection(this);
	 sram_seq.randomize()
     sram_seq.start( sram_ev.sram_agt.sram_seqr);
     #1ns;
     phase.drop_objection(this);
     `uvm_info(get_type_name(), "sram_test end ", UVM_MEDIUM)

  endtask
     
endclass: test
class sram_sequence extends uvm_sequence# (sram_transaction, sram_transaction); //request and response types
	rand int item_cnt;
	`uvm_object_utils_begin(sram_sequence)
		`uvm_field_int(num_seq, UVM_ALL_ON);
	`uvm_object_utils_end
	`uvm_declare_p_sequencer(sram_sequencer);
	function new(string name ="sram_sequence");
		super.new(name);
	endfunction
	
	virtual task body();
		uvm_config_db #(int)::get(p_sequencer,"","num_seq",num_seq); 
		`uvm_info(get_type_name(),  $sformatf("number of sequences to be generated = %d", num_seq), UVM_MEDIUM );
		repeat(item_cnt)
		`uvm_do(req);
	endtask : body
endclass : sram_sequence
class sram_transaction extends uvm_sequence_item;
	rand bit [9:0] Addr;
	rand bit [31:0] DataIn;
	bit [31:0] DataOut;
	rand bit WbCyc;
	rand bit WbStrb;
	rand bit WbWr;
	constraint addreslimit {Addr < 500; }
	constraint datanotzero {DataIn !='0;	}

	constraint WbCyc_range { WbCyc dist { [0:1]:/ 2 }; }
	constraint WbStrb_range { WbStrb dist { [0:1]:/ 2 }; }
	constraint WbWr_range { WbWr dist {0:=3, 1:=7 }; } //P(0) = 3/10 ; P(1) = 7/10
	`uvm_object_utils_begin(sram_transaction )
		`uvm_field_int(Addr, UVM_ALL_ON) 
		`uvm_field_int(DataIn, UVM_ALL_ON)
		`uvm_field_int(WbCyc, UVM_ALL_ON)
		`uvm_field_int(WbStrb, UVM_ALL_ON)
		`uvm_field_int(WbWr, UVM_ALL_ON)
	`uvm_object_utils_end
	function new (string name ="sram_transaction ");
		super.new(name); //super is referring to the base class constructor function
	endfunction: new

endclass : sram_transaction

In reply to chethan2807:

Does this mean you don’t want to randomize ‘num_seq’ while randomizing all other data mebers of your seq_item?

BTW in your sram_sequence you have to declare num_seq, either in the class or in the body method.