How to use a random variable value generated in one sequence in another sequence

Hi,

I have a scenario where one random id is generated in one sequence and need to send next transaction using the same id in another sequence. I cannot use virtual sequence, since I have one agent only with one driver and one sequencer. Also I cannot use driver to remember the id generated in one sequence since the same id need to be used in the sequence_item created in next sequence for crc calculation post_randomization. I am not getting any hint on how to do it.

class seq_item extends uvm_seq_item;
.....
rand id;
...
endclass

class sequence1 extends uvm_sequence;
...
`uvm_do(req)
...
endclass

class sequence2 extends uvm_sequence;
...
`uvm_do(req)  // id generated should be same as that generated in sequence1
...
endclass

one seq_item, one driver and one sequencer

In reply to vivekbalanandan:

I have found the solution by using config_db .Thanks!

In reply to vivekbalanandan:

You should not be using the config_db to pass information between sequences. The config_db should only be used to pass configuration items between components during the build phase only. Trying to use the config_db to pass data can significantly impact your simulation performance.

There is nothing that prevents you from using virtual sequences with only one agent. The purpose of a virtual sequence is to coordinate the behavior between multiple sequences, even if they are being used on one sequencer.

Also, don’t use the `uvm_do* macros. They are very limiting and severely restrict your ability to control your sequences/sequence_items. You should create/start your items directly.

In reply to cgales:

In reply to vivekbalanandan:
You should not be using the config_db to pass information between sequences. The config_db should only be used to pass configuration items between components during the build phase only. Trying to use the config_db to pass data can significantly impact your simulation performance.
There is nothing that prevents you from using virtual sequences with only one agent. The purpose of a virtual sequence is to coordinate the behavior between multiple sequences, even if they are being used on one sequencer.
Also, don’t use the `uvm_do* macros. They are very limiting and severely restrict your ability to control your sequences/sequence_items. You should create/start your items directly.

Okay cgales. I had a reference to the thread Can we set a config db in sequence body() method and get it in scoreboard? - UVM - Verification Academy and a similar one.

Also could you please elaborate with one example where we can use virtual_sequence and a single sequencer-driver pair? I have seen some examples in stack overflow where they tried starting 2 sequencers inside virtual sequence and after randomization of first sequence trying to access those variable in seq2 as seq1.field_name. How we can access seq1 variable by dot operator from seq2. It won’t work. Do you think any other way we can access seq1 variable from seq2 after it is completed if at all virtual sequence with a single sequencer-driver pair work? Also please try to share how we can wait exactly until first sequence completed for the next sequence to start.

In reply to vivekbalanandan:


class seq_item extends uvm_seq_item;
  `uvm_object_utils(seq_item)
  rand int id;
endclass
 
class sequence1 extends uvm_sequence#(seq_item);
  `uvm_object_utils(sequence1)

  rand int id;
  task body();
    req = seq_item::type_id::create("req");
    req.start_item();
    if (!req.randomize() with {id == local::id})
      `uvm_fatal("RNDERR", "Error randomizing req");
    req.finish_item();
  endtask
endclass
 
class sequence2 extends uvm_sequence#(seq_item);
  `uvm_object_utils(sequence1)

  rand int id;
  task body();
    req = seq_item::type_id::create("req");
    req.start_item();
    if (!req.randomize() with {id == local::id})
      `uvm_fatal("RNDERR", "Error randomizing req");
    req.finish_item();
  endtask
endclass

// This virtual sequence needs to run on the same agent sequencer
// as sequence1 and sequence2 since it utilizes the m_sequencer pointer
class virt_seq extends uvm_sequence#(uvm_sequence_item);
  `uvm_object_utils(virt_seq)
  
  task body();
    sequence1 seq1;
    sequence2 seq2;
    
    seq1 = sequence1::type_id::create("seq1");
    seq2 = sequence2::type_id::create("seq1");
    
    if (!seq1.randomize()) // You could specify a 'id' if required
      `uvm_fatal("RNDERR", "Unable to randomize seq1");
    seq1.start(m_sequencer);  // This is blocking until seq1 finishes
    
    if (!seq2.randomize() with { id == seq1.id }) // Sets seq2.id to seq1.id
      `uvm_fatal("RNDERR", "Unable to randomize seq2");
    seq2.start(m_sequencer);
  endtask
  
endclass