Hi Academy,
I’m looking for feedback on a pattern I’ve been following with UVM sequences. I’ve found this pattern useful. It’s generally first met with much skepticism, which I think is because it asks the coder for a little more up front. However, people usually come around to liking it. My own biggest concern with this pattern, is it could potentially add enough config_db::get calls to slow performance. However, whether that’s really an issue comes down to how frequently you randomize your sequences. Am I missing any other possible negatives? Let’s dig in.
Targetting a config_db::set to a specific nested sequence, running on a specific sequencer, requires the ::get in the sequence to have context to provide the requisite hierarchy for targeting from your ::set. That hierarchy is only available to the sequence after it’s context is set by it’s parent ( done by seq.start(…) or seq.set_item_context(…) ).
In the sequence, calling config_db::get in new() has the problem that the context has not ( and cannot ) be set yet, so it must occur later. Putting the ::get in the body() has the problem that it occurs after sequence randomization, so it cannot be used to influence randomization. This necessitates that the ::get() happens in the sequence’s pre_randomize(), but not without adding some burden where the sequence is used.
In the test, seq.start() does set the context, but has the problem that it occurs after sequence randomization. This necessitates that an additional step be taken to set the context before randomization, a call to seq.set_item_context(). With that added, the context is available during the sequence’s pre_randomize().
Facilitating this is code in the sequence’s pre_randomize() and some wherever the sequence is randomized.
Example sequence:
class LeafSequence extends uvm_sequence#();
rand bit [7:0] foo;
function void pre_randomize();
if ( uvm_config_db#(uvm_bitstream_t)::get( null, get_full_name(), "foo", foo ) )
foo.rand_mode(0);
`uvm_info( "TRACE", $sformatf( "%s.%s.rand_mode() == %0d", get_full_name(), "foo", foo.rand_mode() ), UVM_HIGH )
endfunction
`uvm_object_utils(LeafSequence)
function new( string name = "LeafSequence" );
super.new(name);
endfunction
task body();
`uvm_info( "TRACE", $sformatf( "%s.%s == %d", get_full_name(), "foo", foo ), UVM_LOW )
endtask
endclass
Example sequence usage:
LeafSequence lseq = LeafSequence::type_id::create( "lseq", this );
lseq.set_item_context(null,agt_sqr[s]); // required for this example to work
if ( ! lseq.randomize() ) `uvm_fatal( "RANDOMIZE", "Randomize failed" )
lseq.start( agt_sqr[s] );
Full example available here: targeted config_db::get in sequence pre_randomize - EDA Playground