Saturday 30 April 2016

Override in UVM using factory with Example

One of the main advantage of UVM is Creating each components using factory enables them to be overridden in different tests or environments without changing underlying code base.

uvm_factory provides four different methods to override particular instance or all instances of particular class.
set_inst_override_by_type
set_inst_override_by_name
set_type_override_by_type
set_type_override_by_name


Let's go through example of each one of above four ways.

set_inst_override_by_type
-------------------------------------------------------

-------------------------------------------------------

-------------------------------------------------------

-------------------------------------------------------


set_inst_override_by_name

-------------------------------------------------------

-------------------------------------------------------

-------------------------------------------------------

-------------------------------------------------------


set_type_override_by_type
-------------------------------------------------------

-------------------------------------------------------

-------------------------------------------------------

-------------------------------------------------------


set_type_override_by_name
-------------------------------------------------------

-------------------------------------------------------

-------------------------------------------------------

-------------------------------------------------------

set_inst_override_* has high precedence than set_type_override_*.
i.e. If any particular instance of class is override by using set_inst_override_* and type of same class is overridden by using set_type_override_* then that particular instance of class is overridden by set_inst_override_* and rest other instances are overridden by set_type_override_*

-------------------------------------------------------

-------------------------------------------------------

-------------------------------------------------------

-------------------------------------------------------



UVM also support override through command line,
+uvm_set_inst_override=,,
+uvm_set_type_override=,[,]

work like the name based overrides in the factory--factory.set_inst_override_by_name() and factory.set_type_override_by_name().

Let's implement same example as above using command line arguments.
-------------------------------------------------------

-------------------------------------------------------

Simulation time argument:
+uvm_set_inst_override=A,A_override,uvm_test_top.env.a3 \
+uvm_set_inst_override=B,B_ovr,path1.b1 \
+uvm_set_type_override=A,A_ovr \
+uvm_set_type_override=B,B_override
-------------------------------------------------------

-------------------------------------------------------

Singleton class in System Verilog

Sometimes it is required to have only one object of some classes like configuration classes. For this purpose we create singleton classes.
Only one object is created for a singleton class and whenever we try to create a new object, same object is returned.

System verilog does not provide construct to create a singleton class. But we can create it with some manipulation.

---------------------------------------------------------------------

---------------------------------------------------------------------


uvm_root class defined as a singleton class in UVM source code.
---------------------------------------------------------------------

---------------------------------------------------------------------

Monday 25 April 2016

UVM FAQ2



Why phasing is used? What are the different phases in uvm?
UVM Phases is used to control the behavior of simulation in a systematic way & execute in a sequential ordered to avoid race condition. This could also be done in system verilog but manually.

 



Which phases of UVM are Top-Down?
build_phase() & final_phase() are Top-Down, rest all phases are Bottom-Up.



Which phases of UVM are task?
run_phase(),
pre_reset_phase(), reset_phase(), post_reset_phase(),
pre_configure_phase(), configure_phase(), post_configure_phase(),
pre_main_phase(), main_phase(), post_main_phase(),
pre_shutdown_phase(), shutdown_phase(), post_shutdown_phase()



How do uvm phases initiate?
Calling run_test() constructs the UVM environment root component and then initiates the UVM phasing.



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.



What is the order of execution of run_phase() ?
The run_phase() of each component is executed concurrently with no defined order you can depend on.



During the run_phase() is there something like super.run_phase(phase) called?
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.





What is the difference between run_phase and main_phase in uvm_component?
Actually, you can start a sequence in any phase. It is more important to understand the domain/scheduling relationships between the task based (i.e. runtime) phases.
UVM undergoes a number of pre-simulation phases (build, connect, end_of_elaboration, start_of_simulation) that are all implemented with functions. Once those are completed, the task based phases begin.
The standard includes two schedules.

  • 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.



Why connect_phase() is bottom-up?

 

Sunday 24 April 2016

Difference between m_sequencer and p_sequencer in UVM

To understand difference between m_sequencer and p_sequencer, let's first go through couple of classes from UVM library.
-------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------


-------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------

When you call `uvm_declare_p_sequencer from sequence, it overrides m_set_p_sequencer function.
When you call start method of sequence, it calls set_item_context method,
Then set_item_context method calls set_sequencer method,
Then set_sequencer method assign handle of sequencer (which you pass in start method of sequence) to m_sequencer,
set_sequencer also calls m_set_p_sequencer method, but you have override the m_set_p_sequencer method by declaring `uvm_declare_p_sequencer macro.
So m_set_p_sequencer defined in macro will be executed, and it casts m_sequencer into p_sequencer,
where p_sequencer's type is specified by the argument of `uvm_declare_p_sequencer macro.


Conclusion:

m_sequencer and p_sequencer both point to the same thing (the sequencer on which the sequence is running). However, there are some important differences:
m_sequencer is a generic uvm sequencer pointer of type uvm_sequencer_base. It will always exist for an uvm_sequence and is initialized when the sequence is started.

p_sequencer is a reference to uvm_sequencer#(REQ,RSP), the user derived parameterized sequencer class.
Other way you can say that p_sequencer is a type specific sequencer pointer.
p_sequencer will not exist if the `uvm_declare_p_sequencer macros aren't used.

Advantage of p_sequencer over m_sequencer:
Being type specific, you will be able to access anything added to the sequencer (i.e. pointers to other sequencers, handle of environment class (which is defined in user derived virtual sequencer class) etc.).

Drawback of p_sequencer over m_sequencer:
p_sequencer creates an additional dependency, means sequence which use p_sequencer may not be executed on all the sequencers. Sequence requires resource in sequencer class which is declared as p_sequencer (i.e. pointers to other sequencers, handle of environment class, etc.)

Saturday 23 April 2016

Randomize Non-random (State) variable using randomize() method of Class



The randomize() method can be used to temporarily control the set of random and state variables within a class instance or object.
When randomize is called with arguments, those arguments designate the complete set of random variables within that object; all other variables in the object are considered state variables.
The randomize method accepts the special argument null to indicate no random variables for the duration of the call. In other words, all class members behave as state variables.
Consider following Example:
----------------------------------------------------
----------------------------------------------------

rand_mode and constraint_mode in System Verilog



rand_mode:

The random nature of variables declared as rand or randc can be turned on or off dynamically by using in-built method called rand_mode().  rand_mode() can be called as function or task.

In below example, rand_mode of all variable of class is disabled and enabled.
---------------------------------------------------------------------
---------------------------------------------------------------------

We can also change rand_mode of specific variable. Consider below example,
---------------------------------------------------------------------
---------------------------------------------------------------------

When rand_mode method is called as function, it returns the active status of the specified random variable.
When called as a function, rand_mode() returns the current active state of the specified random variable. It returns 1 if the variable is active (ON) and 0 if the variable is inactive (OFF).
---------------------------------------------------------------------
---------------------------------------------------------------------

A compiler error shall be issued if the specified variable does not exist within the class hierarchy or even though it exists but not declared as rand or randc. The following example illustrates the second case.

rand_mode of rand static variable,
---------------------------------------------------------------------
---------------------------------------------------------------------

 
constraint_mode


SystemVerilog supports to change the status of constraint block dynamically.
The constraint_mode() method can be used to active/inactive constraint. By default all the constraint blocks are active. When a constraint is inactive, it is not considered by the randomize() method.

It can be used as task or function.
When called as a task, the argument to the constraint_mode task method determines the operation to be performed. 
When called as a function, constraint_mode() returns the current active state of the specified constraint block. It returns 1 if the constraint is active (ON) and 0 if the constraint is inactive (OFF).

---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------
---------------------------------------------------------------------