|HOME |ABOUT |ARTICLES |ACK |FEEDBACK |TOC |LINKS |BLOG |JOBS |


Tutorials



UVM TESTBENCH




Uvm components, uvm env and uvm test are the three main building blocks of a testbench in uvm based verification.



Uvm_env



uvm_env is extended from uvm_component and does not contain any extra functionality. uvm_env is used to create and connect the uvm_components like driver, monitors , sequeners etc. A environment class can also be used as sub-environment in another environment. As there is no difference between uvm_env and uvm_component , we will discuss about uvm_component, in the next section.



Verification Components



uvm verification component classes are derived from uvm_component class which provides features like hierarchy searching, phasing, configuration , reporting , factory and transaction recording.

Following are some of the uvm component classes
uvm_agent
uvm_monitor
uvm_scoreboard
uvm_driver
uvm_sequencer

NOTE: uvm_env and uvm_test are also extended from uvm_component.

A typical uvm verification environment:


An agent typically contains three subcomponents: a driver, sequencer, and monitor. If the agent is active, subtypes should contain all three subcomponents. If the agent is passive, subtypes should contain only the monitor.



About Uvm_component Class:



uvm_compoenent class is inherited from uvm_report_object which is inherited from uvm_object.
As I mentioned previously, uvm_component class provides features like hierarchy searching, phasing, configuration , reporting , factory and transaction recording.
We will discuss about phasing concept in this section and rest of the features will be discussed as separate topics.


(S)UVM phases


UVM Components execute their behavior in strictly ordered, pre-defined phases. Each phase is defined by its own virtual method, which derived components can override to incorporate component-specific behavior. By default , these methods do nothing.



--> virtual function void build()


This phase is used to construct various child components/ports/exports and configures them.


--> virtual function void connect()


This phase is used for connecting the ports/exports of the components.


--> virtual function void end_of_elaboration()


This phase is used for configuring the components if required.


--> virtual function void start_of_simulation()


This phase is used to print the banners and topology.


--> virtual task run()


In this phase , Main body of the test is executed where all threads are forked off.


--> virtual function void extract()


In this phase, all the required information is gathered.


--> virtual function void check()


In this phase, check the results of the extracted information such as un responded requests in scoreboard, read statistics registers etc.


--> virtual function void report()


This phase is used for reporting the pass/fail status.

Only build() method is executed in top down manner. i.e after executing parent build() method, child objects build() methods are executed. All other methods are executed in bottom-up manner. The run() method is the only method which is time consuming. The run() method is forked, so the order in which all components run() method are executed is undefined.



Uvm_test



uvm_test is derived from uvm_component class and there is no extra functionality is added. The advantage of used uvm_test for defining the user defined test is that the test case selection can be done from command line option +UVM_TESTNAME=<testcase_string> . User can also select the testcase by passing the testcase name as string to uvm_root::run_test(<testcase_string>) method.

In the above <testcase_string> is the object type of the testcase class.


Lets implement environment for the following topology. I will describe the implementation of environment , testcase and top module. Agent, monitor and driver are implemented similar to environment.


1)Extend uvm_env class and define user environment.


class env extends uvm_env;


2)Declare the utility macro. This utility macro provides the implementation of create() and get_type_name() methods and all the requirements needed for factory.


`uvm_component_utils(env)


3)Declare the objects for agents.


agent ag1;
agent ag2;


4)Define the constructor. In the constructor, call the super methods and pass the parent object. Parent is the object in which environment is instantiated.


function new(string name , uvm_component parent = null);
super.new(name, parent);
endfunction: new


5)Define build method. In the build method, construct the agents.
To construct agents, use create() method. The advantage of create() over new() is that when create() method is called, it will check if there is a factory override and constructs the object of override type.


function void build();
super.build();
uvm_report_info(get_full_name(),"Build", UVM_LOW);
ag1 = agent::type_id::create("ag1",this);
ag2 = agent::type_id::create("ag2",this);
endfunction


6)Define connect(),end_of_elaboration(),start_of_simulation(),run(),extract(),check(),report() methods.
Just print a message from these methods, as we dont have any logic in this example to define.


function void connect();
uvm_report_info(get_full_name(),"Connect", UVM_LOW);
endfunction


(S)Complete code of environment class:

class env extends uvm_env;

`uvm_component_utils(env)
agent ag1;
agent ag2;

function new(string name, uvm_component parent);
super.new(name, parent);
endfunction

function void build();
uvm_report_info(get_full_name(),"Build", UVM_LOW);
ag1 = agent::type_id::create("ag1",this);
ag2 = agent::type_id::create("ag2",this);
endfunction

function void connect();
uvm_report_info(get_full_name(),"Connect", UVM_LOW);
endfunction

function void end_of_elaboration();
uvm_report_info(get_full_name(),"End_of_elaboration", UVM_LOW);
endfunction

function void start_of_simulation();
uvm_report_info(get_full_name(),"Start_of_simulation", UVM_LOW);
endfunction

task run();
uvm_report_info(get_full_name(),"Run", UVM_LOW);
endtask

function void extract();
uvm_report_info(get_full_name(),"Extract", UVM_LOW);
endfunction

function void check();
uvm_report_info(get_full_name(),"Check", UVM_LOW);
endfunction

function void report();
uvm_report_info(get_full_name(),"Report", UVM_LOW);
endfunction

endclass




Now we will implement the testcase.
1)Extend uvm_test and define the test case


class test1 extends uvm_test;


2)Declare component ustilits using utility macro.


`uvm_component_utils(test1)


2)Declare environment class handle.


env t_env;


3)Define constructor method. In the constructor, call the super method and construct the environment object.


function new (string name="test1", uvm_component parent=null);
super.new (name, parent);
t_env = new("t_env",this);
endfunction : new


4)Define the end_of_elaboration method. In this method, call the print() method. This print() method will print the topology of the test.


function void end_of_elaboration();
uvm_report_info(get_full_name(),"End_of_elaboration", UVM_LOW);
print();
endfunction


4)Define the run method and call the global_stop_request() method.


task run ();
#1000;
global_stop_request();
endtask : run


(S)Testcase source code:

class test1 extends uvm_test;

`uvm_component_utils(test1)
env t_env;

function new (string name="test1", uvm_component parent=null);
super.new (name, parent);
t_env = new("t_env",this);
endfunction : new

function void end_of_elaboration();
uvm_report_info(get_full_name(),"End_of_elaboration", UVM_LOW);
print();
endfunction

task run ();
#1000;
global_stop_request();
endtask : run

endclass

Top Module:




To start the testbench, run_test() method must be called from initial block.
Run_test() mthod Phases all components through all registered phases.


module top;

initial
run_test();

endmodule


(S)Download the source code


uvm_phases.tar
Browse the code in uvm_phases.tar


(S)Command to run the simulation


VCS Users : make vcs
Questa Users: make questa



(S)Log file:

[RNTST] Running test test1...
uvm_test_top.t_env [uvm_test_top.t_env] Build
uvm_test_top.t_env.ag1 [uvm_test_top.t_env.ag1] Build
uvm_test_top.t_env.ag1.drv [uvm_test_top.t_env.ag1.drv] Build
uvm_test_top.t_env.ag1.mon [uvm_test_top.t_env.ag1.mon] Build
uvm_test_top.t_env.ag2 [uvm_test_top.t_env.ag2] Build
uvm_test_top.t_env.ag2.drv [uvm_test_top.t_env.ag2.drv] Build
uvm_test_top.t_env.ag2.mon [uvm_test_top.t_env.ag2.mon] Build
uvm_test_top.t_env.ag1.drv [uvm_test_top.t_env.ag1.drv] Connect
uvm_test_top.t_env.ag1.mon [uvm_test_top.t_env.ag1.mon] Connect
uvm_test_top.t_env.ag1 [uvm_test_top.t_env.ag1] Connect
uvm_test_top.t_env.ag2.drv [uvm_test_top.t_env.ag2.drv] Connect
uvm_test_top.t_env.ag2.mon [uvm_test_top.t_env.ag2.mon] Connect
uvm_test_top.t_env.ag2 [uvm_test_top.t_env.ag2] Connect
uvm_test_top.t_env [uvm_test_top.t_env] Connect
uvm_test_top.t_env.ag1.drv [uvm_test_top.t_env.ag1.drv] End_of_elaboration
uvm_test_top.t_env.ag1.mon [uvm_test_top.t_env.ag1.mon] End_of_elaboration
uvm_test_top.t_env.ag1 [uvm_test_top.t_env.ag1] End_of_elaboration
uvm_test_top.t_env.ag2.drv [uvm_test_top.t_env.ag2.drv] End_of_elaboration
uvm_test_top.t_env.ag2.mon [uvm_test_top.t_env.ag2.mon] End_of_elaboration
uvm_test_top.t_env.ag2 [uvm_test_top.t_env.ag2] End_of_elaboration
uvm_test_top.t_env [uvm_test_top.t_env] End_of_elaboration
uvm_test_top [uvm_test_top] End_of_elaboration
----------------------------------------------------------------------
Name Type Size Value
----------------------------------------------------------------------
uvm_test_top test1 - uvm_test_top@2
t_env env - t_env@4
ag1 agent - ag1@6
drv driver - drv@12
rsp_port uvm_analysis_port - rsp_port@16
sqr_pull_port uvm_seq_item_pull_+ - sqr_pull_port@14
mon monitor - mon@10
ag2 agent - ag2@8
drv driver - drv@20
rsp_port uvm_analysis_port - rsp_port@24
sqr_pull_port uvm_seq_item_pull_+ - sqr_pull_port@22
mon monitor - mon@18

uvm_test_top.t_env.ag1.drv[uvm_test_top.t_env.ag1.drv]Start_of_simulation
uvm_test_top.t_env.ag1.mon[uvm_test_top.t_env.ag1.mon]Start_of_simulation
uvm_test_top.t_env.ag1[uvm_test_top.t_env.ag1]Start_of_simulation
uvm_test_top.t_env.ag2.drv[uvm_test_top.t_env.ag2.drv]Start_of_simulation
uvm_test_top.t_env.ag2.mon[uvm_test_top.t_env.ag2.mon]Start_of_simulatio

..
..
..
..



Observe the above log report:

1)Build method was called in top-down fashion. Look at the following part of message.



uvm_test_top.t_env [uvm_test_top.t_env] Build
uvm_test_top.t_env.ag1 [uvm_test_top.t_env.ag1] Build
uvm_test_top.t_env.ag1.drv [uvm_test_top.t_env.ag1.drv] Build
uvm_test_top.t_env.ag1.mon [uvm_test_top.t_env.ag1.mon] Build
uvm_test_top.t_env.ag2 [uvm_test_top.t_env.ag2] Build
uvm_test_top.t_env.ag2.drv [uvm_test_top.t_env.ag2.drv] Build
uvm_test_top.t_env.ag2.mon [uvm_test_top.t_env.ag2.mon] Build



2)Connect method was called in bottopm up fashion. Look at the below part of log file,



uvm_test_top.t_env.ag1.drv [uvm_test_top.t_env.ag1.drv] Connect
uvm_test_top.t_env.ag1.mon [uvm_test_top.t_env.ag1.mon] Connect
uvm_test_top.t_env.ag1 [uvm_test_top.t_env.ag1] Connect
uvm_test_top.t_env.ag2.drv [uvm_test_top.t_env.ag2.drv] Connect
uvm_test_top.t_env.ag2.mon [uvm_test_top.t_env.ag2.mon] Connect
uvm_test_top.t_env.ag2 [uvm_test_top.t_env.ag2] Connect
uvm_test_top.t_env [uvm_test_top.t_env] Connect



3)Following part of log file shows the testcase topology.





Index
Introduction
Uvm Testbench
Uvm Reporting
Uvm Transaction
Uvm Configuration
Uvm Factory
Uvm Sequence 1
Uvm Sequence 2
Uvm Sequence 3
Uvm Sequence 4
Uvm Sequence 5
Uvm Sequence 6
Uvm Tlm 1
Uvm Tlm 2
Uvm Callback

Report a Bug or Comment on This section - Your input is what keeps Testbench.in improving with time!





<< PREVIOUS PAGE

TOP

NEXT PAGE >>

copyright © 2007-2017 :: all rights reserved www.testbench.in::Disclaimer