Saturday, December 1, 2012

Callback in UVM !!!

Callbacks are empty virtual methods that are embedded in the user components at strategic  points to allow the user to make customization which allows better reuse.

In UVM this can be achieved in two ways. 

  1. Simply add  empty virtual methods in the component  say in a driver  and invoke the virtual methods at appropriate locations , test writer or  the user extends the driver class implements the virtual methods and uses  set instance override to accomplish the functionality.
  2. Create a class which extends form uvm_callback class and it  implements the virtual methods.  Use `uvm_do_callbacks() to place the virtual methods at strategic points in the component say a driver. Now the test writer or user extends the callback class and implements the virtual methods and registers or associate the extended callback class with the instance of the component say the driver using add to accomplish the functionality.

Saturday, November 3, 2012

Adding user defined phase using uvm_phase !!!


In addition to the predefined phases available in uvm , the user has the option to add his own phase to a component. This is typically done by extending the uvm_phase class the constructor needs to call super.new which has three arguments 
  1. name of the phase task or function
  2. top down or bottom up phase
  3. task or function
The call_task  or call_func and get_type_name need to be implemented to complete the addition of new phase.

Example

class custom_phase extends uvm_phase;

   function new();
      super.new(“custom”,1,1);
   endfunction

   task call_task  ( uvm_component parent);
    
     my_comp_type comp;
      
     if ( $cast(comp,parent) )
             comp.custom_phase();
    
   endtask

   virtual function string get_type_name();
      return “custom”;
   endfunction

endclass

Tuesday, October 2, 2012

Usage of uvm_resource_db & uvm_config_db !!!

Both uvm_config_db and uvm_resource_db share the same underlying database to store and retrieve information. Infact you can write a value to the database using uvm_config_db ::set() method and retrieve the information using uvm_resource_db::read_by_name().  The recommended method is to use uvm_config_db when hierarchical   based access is required.  When you want to share object and access it from different location without using the hierarchy you can use uvm_resource_db.

You can set a resource to the resource db using the uvm_resource_db::set()  method

Example

uvm_resource_db# (int)::set("enable","*",1,this);

To retrieve the information from the resource db you can use uvm_resource_db::read_by_name() method

Example

   Bit success;

   Success=uvm_resource_db#(int)::read_by_name("enable",get_full_name(),value,this);

   If(success==1’b0)
      `uvm_error("ERROR","cannot locate the resource ");

Sunday, September 2, 2012

Accessing components bottom up using set_config_* and get_config_* in UVM !!!


One of the requirements in verification is to access variable bottom up  in the hierarchy this can be done in UVM using set_config_*  and get_config_*methods. In bottom up access you need to use hierarchical reference like  uvm_test_top.set_config_*  or  uvm_test_top.get_config_*  from the component in the lower level hierarchy to access component in top level hierarchy.  Top down access does not require the hierarchical reference to uvm_test_top , set_config_* and get_config_* can be used directly. 

Sunday, August 19, 2012

TLM 2.0 Non-blocking Transport in UVM !!!


Many times we need to generate a transaction reactively based on the response. One of the protocols i can think of which requires reactive generation of transaction is USB. UVM has non-blocking transport which is  an appropriate fit for reactive random stimulus generation. Non blocking transport can be used by the initiator and target to update each other’s progress. We have method like nb_transport_fw () which is used to send the transaction from initiator to target. nb_transport_bw () method is used to send transaction from the target to the initiator.  The initiator modifies the transaction before the call to the nb_transport_fw() after which the object should not be modified.  The target can modify the transaction object before the call to nb_transport_bw () after which the object should not be modified. Each call to the forward and backward methods are accompanied by phase change , different type of phases are UNINTIALIZED_PHASE, BEGIN_REQ, END_REQ, BEGIN_RESP & END_RESP. Forward and backward function return a status UVM_TLM_ACCEPTED,UVM_TLM_UPDATED & UVM_TLM_COMPLETED these status indicate the status of the transaction - accepted , updated and completed.

Saturday, July 7, 2012

Command line processor in UVM !!!



Command line processor provides  general interface to the command line arguments from the simulator to the UVM  test bench. To use the command line processor in your test bench singleton instance of command line processor has to be created as described below

uvm_cmdline_processor commandline_processor = uvm_cmdline_processor::get_inst();

To obtain the command line argument  get_arg_value() should be used

string  value = "intial_value";
int rt_value = commandline_processor.get_arg_value("+DIRECTION=",value);

Singleton class is the one which returns the same object irrespective of the number of time an object is created .command line processor is used as a singleton class.

Factory replacement options like set_type_override() ,set_inst_override() can be done using  command line processor arguments like +uvm_set_type_override   +uvm_set_inst_override , 

Saturday, June 23, 2012

Virtual sequences in UVM !!!


In a system level verification environment we require coordination of multiple components that run in parallel . Virtual sequence is used to have centralized control and coordinates stimulus generation across components. Virtual sequences executes on the virtual sequencer. Virtual sequencers have reference to other driver sequencers or other virtual sequencers. Virtual sequence can execute a transaction  items on other sequencers only.  By using virtual sequences you can reuse the sequence library of a component or a block level environment at system level.

Friday, May 11, 2012

Algorithmic comparator (Scoreboard) in UVM !!!


Algorithmic comparator (Scoreboard) in UVM is a useful utility to compare two different streams of transactions. Different types of transaction class can be compared with this scoreboard. Algorithmic comparator takes three parameters BEFORE, AFTER and TRANSFORMER. The TRANSFORMER class is the one that transforms one stream of transaction to other. TRANSFORMER class should implement a transform function with the following prototype

function AFTER transform ( BEFORE b )  

Transform function should implement how transaction class BEFORE is converted to AFTER and return the converted transaction object.  

Matches and Mismatches in this scoreboard is reported in terms of the AFTER transactions.

Tuesday, April 24, 2012

do_copy() , do_compare(), do_byte_pack() , do_is_vaild() , do_allocate() & do_byte_unpack() !!!


do_*  methods overrides the default implementation of the vmm_data methods that is created by the shorthand macros. If the do_* methods are defined, this method is used instead of the default implementation. do_* methods are very useful can work well with short hand macros example you can just override the default implementation of  byte_pack() & byte_unpack() methods using do_byte_pack and do_byte_unpack and rest of the vmm_data methods can be auto generated by short hand macros.

Wednesday, March 7, 2012

Factory services in VMM !!!

Factory in VMM was implemented by assigning different blueprints to factory place holders like randomize_obj and scenario_set[] for atomic generator and scenario generator respectively. With the introduction of factory services from VMM1.1 replacing any type of object say a transaction or transactor can be done easily using methods like override_with_new() or override_with_copy(). We can replace one particular instance of an object with the derived object or we can replace all the instances of the object with the derived object.

Following are the steps one has to follow to use VMM factory services.

  1. Use the macro `vmm_class_factory(class_name) to register the class to factory services
  2. Use create_instance() to create an object instead of using new()
  3. Use override_with_new() or override_with_copy() to replace and existing object with a derived object.
  4. Use pattern matching to replace all the instance of the class or a particular instance of the class.

Saturday, February 18, 2012

Accessing class attributes bottom up !!!

Accessing a property of a class top down is done through hierarchical access through dot operator which is very common in the HVL world. Accessing class properties bottom up through multiple levels is also a requirement we come across in verification which is little bit tricky to implement.

Following is an example on how we could do a bottom up access of a class property.

class top;
int flag;
level_1 obj;

function new();
obj=new(this);
endfunction

endclass


class level_1;
top parent_of_the_class;

function new ( top parent_of_the_class);
this.parent_of_the_class=parent_of_the_class;
endfunction

task run();
if(parent_of_the_class.flag==1)
begin
$display(" Flag set \n");
end
else
begin
$display(" Flag not set \n");
end
endtask

endclass







Saturday, January 28, 2012

Constraint solver performance !!!

Debugging constraint solver performance issues is a real challenge; even a small mistake in a constraint can impact constraint solver performance . Common mistake people do which results in constrain solver performance degradation is to constraint the data payload to a predictable pattern to enable designers to debug RTL faster. When predictable data pattern is constrained for every transaction the number of bidirectional constraints solved increases exponentially resulting in constraint solver performance degradation. The problem would be magnified further when a scenario generator is used to randomize sequence of transactions.

The solution to this is if you would require a predictable data pattern to be used in the data payload override the random value with predictable pattern in post_randomize() method instead of going for a constraint, this would improve the runtime performance of your simulation.