Uvm Faq
Uvm Faq
UVM FAQ1
OR
We already have uvm_object, why do we need uvm_component which is actually derived class
of uvm_object?
1) uvm_components are "static" in that they are created during build_phase() and persist
throughout the simulation.
uvm_objects are transient, such as transactions that are created when needed and disappear when
not used anymore.
2) There is an extra argument for "uvm_component - new" function for which we need to define
the parent class name. so, uvm_component is a part of uvm hierarchy while uvm_object does
not.
3) uvm_component has phases while uvm_object doesn't.
Difference between export and import:
Basically, both exports and imps provide the implementations of whatever methods your TLM
port requires. The difference is an export is an indirect connection to an implementation. It
normally used when there is component hierarchy involved.
What is the difference between early randomization and late randomization of sequences?
To send a sequence_item to a driver there are four steps that need to occur in sequence:
Step 1 Creation
Step 4 - Go - finish_item()
Steps 2 and 3 could be done in any order. However, leaving the randomization of the
sequence_item until just before the finish_item() method allow the sequence_item to be
randomized according to conditions true at the time of generation. This is sometimes referred to
as late randomization.
The alternative approach is to generate the sequence_item before the start_item() call, in this
case the item is generated before it is necessarily clear how it is going to be used. This is referred
as early randomization.
What is the difference between creating an object using new() and create()?
create() is a factory method which construct an object. To override an object you need to
construct it using create(). If you use set_type_override before run then, factory replaces
constructed object with derived object (specified in override). If you use new() then you cant
override.
You should always use create() rather than using new() for classes registered with the factory.
What is the difference between sequence_item, sequence and sequencer with respect to UVM?
sequence_item:
A sequence item is an object that models a piece of information being transmitted between two
components (sometimes it's called a "transaction"). It can be can be directed, constrained
randomized or fully randomized.
sequence:
Sequences are objects whose body() method is used to generate sequence_items, optionally
randomize it and sent to the driver through sequencer.
UVM Sequences can be transient or persistent means it may drive stimulus for the duration of
the simulation, or anywhere in-between.
UVM Sequences are not part of the component hierarchy.
sequencer:
UVM Sequencer controls the flow of UVM Sequence Items (transactions) generated by one or
more UVM Sequences.
get_next_item(), item_done() is implemented in uvm_sequencer.
When multiple sequences are running in parallel, then sequencer is responsible for arbitrating
between the parallel sequences.
lock(), unlock(), grab(), ungrab() is implemented in uvm_sequencer.
sub-sequence:
sequences can call other sequences (via sequence.start()). A sequence that is started from another
sequence (as opposed to from a test) is called a sub-sequence.
Why is the build_phase() in UVM executed in a Top - Down fashion and the other phases in Bottom - Up
fashion?
The build phase has to be that way because the parent component's build_phase constructs the child
components. You couldn't call the child's build_phase before the parent's build_phase because they the
child objects haven't been constructed yet. You need a constructed object to call its method.
The build_phase() is also executed top-down so that the parent can provide override setting that the
children will use when they execute their build_phase()
The ordering within the other phases should not matter, except you might want know that the top
level's report_phase comes last.
The run_phase() of each component is executed concurrently with no defined order you can depend on.
You only need to call super.method() if you are extending a class an need the functionality of the base
method. There is nothing inside the run_phase() of a uvm_component, so there is no need to call
super.run_phase() when extending from it.
You may want to call it when extending your classes from your base classes.
One is simply the run_phase, which starts executing at time zero and continues until all
components have dropped their objections within the run_phase.
The other schedule contains twelve phases that execute parallel to the run phase. They are:
pre_reset, reset, post_reset, pre_config, config, post_config, pre_main, main, post_main,
pre_shutdown, shutdown, and post_shutdown. They execute in sequence.
Every component has the opportunity to define or not define tasks to execute these phases. A phase
starts only when all components in the previous phase have dropped their objections. A phase continues
to execute until all components have dropped their objections in the current phase.