Uvm_sequence randomization

Hi,

I have query in uvm_sequence randomization. All the sequences are started by using seq.start(sequence_name) method.And, this will automatically randomize whatever present inside the sequence. But, if we explicitly randomize a seq. i.e seq.randomize with {static_constraints}, when we call the start method, i.e., seq.start(sequence_name), will it take static_constraints which are explicitly randomized by seq.randomize method, or it will again randomize it and give different values.

For example, let’s say a write sequence which has write_data and address. And the sequence is a virtual sequence and declared in p_sequencer.
And, it is randomized as below,

wr_seq.randomize with {write_data == 'h03;
address == 'h0004;};
wr_seq.start(p_sequencer);

Now, when the sequence started will take the write_data as 'h03?.

In reply to Boogeyman:

  • Calling start() for a sequence doesn’t randomize the sequence. It only starts the existing sequence in its current state.
  • Calling randomize() with {} will randomize the sequence per the specified constraints. Calling start() afterwards doesn’t change any values.
  • Don’t use p_sequencer. All virtual sequences should have the required sequencer handles assigned prior to starting and run on a ‘null’ sequencer.

In reply to cgales:

Hi Cgales,

Thanks for the comment. In the below code, whatever randomized in trans_seq will be passed to write_seq right. But, while executing this code, I observed that, write_seq.write_data and write_seq.address has different data.

Note : Both are started with p_sequencer.

class write_seq extends uvm_sequence #(uvm_sequence_item);
  `uvm_object_utils(write_seq)
  `uvm_declare_p_sequencer(virtual_sequencer) 
   rand bit[31:0]   write_data;
   rand bit[31:0]   address;
endclass : write_seq

class trans_seq extends uvm_sequence #(uvm_sequence_item);
  `uvm_object_utils(trans_seq)
  `uvm_declare_p_sequencer(virtual_sequencer) 

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

   rand bit[31:0]   write_data;
   rand bit[31:0]   address; 
 
   write_seq  wr_seq;

   extern virtual task body();
endclass : trans_seq

task trans_seq::body();
    wr_seq = write_seq::type_id::create("wr_seq"); 
    wr_seq.randomize with {write_data == this.write_data;
                           address    == this.address;};
    wr_seq.start(p_sequencer);
endtask : body


In reply to Boogeyman:

If you add a little more code, you can create a self-contained example which demonstrates your issue.

Your issue is that you have variables with the same name in both trans_seq and write_seq. Section 18.7 of the LRM explains how to differentiate between a variable that is local to the class calling randomize() and a variable that is local to the class being randomized. You want to use the qualifier “local::” and not “this.”


import uvm_pkg::*;
`include "uvm_macros.svh"

class write_seq extends uvm_sequence #(uvm_sequence_item);
  `uvm_object_utils(write_seq)
  
  rand bit[31:0] write_data;
  rand bit[31:0] address;
  
  function new(string name="write_seq");
    super.new(name);
  endfunction
  
  task body();
    `uvm_info(get_name(), $sformatf("write_seq has address: %0h and write_data: %0h", address, write_data), UVM_MEDIUM);
  endtask
endclass : write_seq
 
class trans_seq extends uvm_sequence #(uvm_sequence_item);
  `uvm_object_utils(trans_seq)
 
  function new(string name = "trans_seq");
    super.new(name);
  endfunction : new

  rand bit[31:0] write_data;
  rand bit[31:0] address; 
 
  task body();
    write_seq write_seq_incorrect_randomization = write_seq::type_id::create("write_seq_incorrect_randomization");
    write_seq write_seq_correct_randomization = write_seq::type_id::create("write_seq_correct_randomization");

    `uvm_info(get_name(), $sformatf("trans_seq has address: %0h and write_data: %0h", address, write_data), UVM_MEDIUM);
    
    if (!write_seq_incorrect_randomization.randomize with {write_data == this.write_data;
                                                           address    == this.address;}) begin
      `uvm_fatal("RNDERR", "Unable to randomize write_seq_incorrect_randomization");
    end
    write_seq_incorrect_randomization.start(null);
    
    if (!write_seq_correct_randomization.randomize with {write_data == local::write_data;
                                                         address    == local::address;}) begin
      `uvm_fatal("RNDERR", "Unable to randomize write_seq_correct_randomization");
    end
    write_seq_correct_randomization.start(null);
    
  endtask : body
endclass : trans_seq

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
  
  task run_phase(uvm_phase phase);
    trans_seq test_seq = trans_seq::type_id::create("test_seq");
    repeat (10) begin
      if (!test_seq.randomize()) begin
        `uvm_fatal("RNDERR", "Unable to randomize trans_seq");
      end
      test_seq.start(null);
    end
  endtask
endclass

module testbench();
  initial begin
    run_test("my_test");
  end
endmodule

1 Like

In reply to cgales:

Hi Cgales,

Thank you so much for the help. I understood the difference between this. and local:: qualifiers. And code is working as expected.