Tuesday, November 25, 2014

Interface class in system verilog !!!


System verilog 2012 has introduced interface class. Interface class is nothing but class with pure virtual methods declaration. The class which implements the interface class should implement the pure virtual methods. Interface class can extend from another interface class but it cannot extend from virtual class or regular class. Regular class can implement multiple interface class and also extend from regular class. Interface class enables better code reusability and also enables multiple inheritance.

Example 

interface class A;
    pure virtual function int get();
endclass

interface class B;
    pure virtual function void put()
endclass

class C implements A , B;

    virtual function int get();
       $display(“ Get  \n”);
     endfunction

    virtual function void put();
       $display(“ Put \n”);
    endfunction

endclass 

Sunday, September 28, 2014

p_sequencer usage in UVM !!!


UVM sequences generally do not have access to the TLM ports  In that case the TLM ports and other features available in the sequencer can be accessed from the sequence using p_sequencer reference. This feature is very useful in a layering scenario when higher level sequence is layered into the lower level sequence.

Sunday, August 31, 2014

Barrier in UVM !!!


uvm_barrier class is used for multi process synchronization mechanism. set of processes can be allowed to wait using the wait_for() method until  desired number of process reach a synchronization point. set_threshhold() method specifies how many process must be waiting on the barrier synchronization point before all the processes may proceed. reset() method resets the barrier waiter count to zero , after reset all the process should wait for the threshold again.

Saturday, July 26, 2014

uvm_event and uvm_event_pool !!!


Synchronization in a multithreaded environment in system verilog is done using event’s. In UVM uvm_event and uvm_event_pool can be used for synchronization of multiple threads or components. Simple example of uvm event is as follows.


uvm_event_pool  event_pool_s=uvm_uvm_event_pool::get_global_pool()
uvm_event           event_s=event_pool_s.get(event_s);


fork
begin
    ........

    event_s.trigger();

end
begin
    .......
  
   event_s.wait_ptrigger();

end
join

Sunday, May 25, 2014

Parameterized class in system verilog !!!


Verification component reuse is one of the basic requirement when building verification components.Parameterized class play a very important role in making a code generic. With parameterized class in system verilog data types , size of bit vectors can be declared generic in the class , different variations of the class can be created by varying the parameter value.

Example of a parameterized class

class data # ( type t=int , int size=8 )

      t                        a ;
      bit [ size-1 : 0] b ;

endclass

data # ( shortint , 16 )          halfword_data;
data # ( longint ,  32)                  word_data;

Sunday, April 20, 2014

Pure virtual functions and tasks in system verilog !!!


Virtual function/tasks defined in the base class may or may not be overridden in the derived class and the base class can have an implementation of the virtual function/task. sometime the definition of virtual functions/task in base class may not have any clarity on what need to be implemented these virtual functions/task must be overridden in the derived class and just a declaration is need in the base class. In this scenario virtual function / task is declared as pure. Declaring virtual method pure means no implementation for the function/task is required in the base class and the derived class must override the virtual function/task. 

Sunday, March 30, 2014

OOP method to access variables of the derived class !!!


We typically use virtual set_() and get_() methods to access the variables added in the extended class from the base class. class handles are created using the base class and type and instance factory overrides are used to replace the class handles respectively. Any reference to the derived class variable from base class is done using virtual set_() and get_() methods which are just empty methods in the base class. At runtime the derived class virtual methods are linked and variables are written or read using set and get methods after a type or instance override.

Friday, February 21, 2014

Mirrors in UVM RAL !!!


RAL mirrors are shadow location of the DUT registers that are updated when RAL read or write methods are accessed from the test bench  , RAL mirror give the user test bench access to the register values for synchronizing test bench events without reading the DUT register. If the DUT internally modifies the content of any field or register through its normal operations (e.g., by setting a status bit or incrementing an accounting counter), the mirrored value becomes outdated. Memory are not mirrored in UVM RAL.RAL mirror value can be set using mirror() method , Mirror value can be updated to the DUT using update() method. At any point of time mirror value can be got using the get() method. set() method can be used to set the mirror value to DUT , the value actually written only when update() method is called.

Monday, January 13, 2014

Creating directed scenario in UVM !!!


Recommended  method  for closing coverage is to have test to run with multiple seeds , but many times certain scenarios can never be covered by the randomness and we require a directed test case. The way to write a directed test in UVM  is as follows.


  • Disable the regular sequence from executing on the sequencer by setting count as 0 in the directed test case.
               set_config_int("*.sequencer", "count", 0);

  • randomize the sequence in the directed way and execute the sequence on the sequencer using execute_item() method.
                 success = item.randomize();
               *.sequencer.execute_item(item);

Sunday, December 22, 2013

Collecting Coverage using white box assertion and functional coverage !!!


One of the essential requirement for verification closure  is to close functional coverage , coverage measured  should accurately measure if the event has occurred in the DUT and the DUT has responded as expected for the event , this requirement can typically be covered using white box assertion and having cover property on the assertion. Using assertion coverage instead of functional coverage is a tradeoff that has to be taken , assertion coverage removes the need for coding coverage monitor but the assertion coverage constructs are not as powerful as the the functional coverage construct in terms of covering cross coverage , having excludes in cross coverage. Most of the cross in assertion coverage need to be done manually. Best strategy one can use is to partition the coverage model between white box coverage assertion and functional coverage on the IO bus to get the best out of both the coverage approach. 

Sunday, November 3, 2013

TLM 2.0 Sockets in UVM !!!


Normally the connection between two processes is through port and export , but with TLM 2.0 we have sockets which provide asynchronous pipelined bi directional connectivity between components. Socket has both a export and port packaged together. A socket can  be initiator socket or target socket. Data flows in the forward direction from the initiator socket to target socket , there is also a backward path between Target socket to initiator socket. TLM connectivity between components can be easily encapsulated using sockets.

Sunday, October 13, 2013

Phases in UVM !!!


UVM component have different phases like build() , connect() , end_of_elaboration() , start_of_simulation(), run() , extract() , check() & report().  Except run() all other phases are virtual functions , run() phase is a virtual task.
phases operate in a particular sequence  as follows build ->  connect  -->  end_of_elaboration --> start_of_simulation --> run --> extract --> check --> report. All the phases except build() phase is bottom up , build phase is top down. In UVM we have provision to add custom phase.

Sunday, September 29, 2013

TLM process communication using TLM FIFO !!!


With normal TLM ports put will result in the consumers ability to process the transaction right away , TLM FIFO component in UVM is used to buffer transactions so that producer and consumer are independent of each other. TLM FIFO has methods like put() , get() and peek() to access transaction from the TLM FIFO. peek() method gets the transaction without removing transaction from the TLM FIFO. Some of the applications of TLM FIFO is buffering transactions for score boarding. 

Thursday, August 15, 2013

Build in command line options in UVM !!!


here are some of the useful build in command line options in UVM.

instance specific factory override  :   +uvm_set_inst_override
type specific factory override          :   +uvm_set_type_override
integer configuration                        :   +uvm_set_config_int
string configuration                           :   +uvm_set_config_string
Timeout                                               :   +UVM_TIMEOUT
Max quit count                                   :   +UVM_MAX_QUIT_COUNT
Objection trace                                  :   +UVM_OBJECTION_TRACE


These command line options helps in quick debug and test writing. 

Saturday, July 13, 2013

System verilog assertion coverage !!!


Functional coverage collection with passive monitor is the method recommended by methodology to collect coverage. There is alternative ways to collect coverage in system verilog using assertion coverage. This feature is very useful if you want to collect coverage on some important DUT events , using assertion coverage has its own advantages  and disadvantages.

Advantages of assertion coverage 

  1. Coverage monitors are not required to collect required coverage event and then trigger a cover group.
  2. Coverage is collected using  assertions and using cover property , binding the assertion to the module or instance is required to collect coverage from the DUT. 
  3. Implementing and collecting assertion coverage is faster compared to writing functional coverage for DUT events.
  4. Assertion coverage is perfect fit for collecting coverage on important DUT events.

Disadvantages of assertion coverage

  1. Assertions coverage if not coded appropriately takes considerable amount of simulation time.
  2. Debugging assertion failures is slightly complex than debugging coverage events in a passive monitor.

Saturday, June 1, 2013

Sequence library in UVM !!!


Sequences can be grouped using  uvm sequence library ,  sequences can be registered to sequence library using the macro `uvm_add_to_seq_lib(). When the sequence library is started it randomly selects and executes the sequence depending on the selection mode. Selection modes can be any of the following

UVM_SEQ_LIB_RAND      --  Random selection of sequence 
UVM_SEQ_LIB_RANDC   --  Random selection without repeating the sequences
UVM_SEQ_LIB_ITEM       --  Execute  a single sequence item
UVM_SEQ_LIB_USER      --  user selects  sequences using select_sequence() method


Selection mode of the sequence library is set using  uvm_config_db().

sequence library can be used to create system level scenario using random sequences.

Thursday, May 2, 2013

Interrupt handling using grab() and ungrab() sequencer in UVM !!!


One of the basic functionality on the processor interface of a verification environment is to service interrupts along with register read / write operations. Servicing the interrupt requires  stoping the ongoing register access sequence and executing the ISR sequence . This can be achieved  using grab()  method on the sequencer on an interrupt to stop the register read/write sequence and execute the interrupt sequence. ungrab() method should be used to return the sequencer control back to the register read/write sequence.


Saturday, April 6, 2013

Generic Payload in UVM !!!


Generic payload is the default transport vehicle for TLM2  blocking and non blocking transport interface. Generic payload is a transaction class derived from uvm_sequence_item which enables it to be generated in sequences and transported to drivers through sequencers. Generic payload can be used for any memory mapped bus based system. Generic payload has property like m_address , m_command, m_byte_enables etc. Generic payload class has access methods for each of the property which is virtual enabling it to be used in the class that extends generic payload class.

It would be good idea to explore the generic payload transaction class before writing your own transaction class for memory mapped bus interface.

Sunday, March 10, 2013

Base class library specific to product on top of RVM/VMM/OVM/UVM !!!


RVM/VMM/OVM/UVM provides rich set of features that can be used to develop a sophisticated test bench. Extending your Driven/monitor/scoreboard/sequence directly from the methodology may not be an ideal solution with respect to product specific requirement. The ideal way is have a set of base class extending from the methodology class which adds specific requirement which will be product line specific. Having company/product specific base class helps in better reuse and isolates the users from the changes introduced  due to new releases in the methodology. When ever specific base class is changed it can be qualified with the supported version of tool,methodology and VIP. This approach also helps to incrementally move towards the latest releases of the methodology ensuring current development effort is not stalled.

Saturday, February 2, 2013

Layering sequences in UVM !!!



We come across different types of layering requirement for different  protocols. Basic ones are as follows.

  1. One to one mapping  --  One higher level protocol frame is mapped to the payload of one lower level protocol frame.
  2. One to many mapping -- One higher level protocol frame is mapped to the payload of many lower level protocol frames.
  3. Many to one mapping  -- Many higher  level protocol frames are mapped to the payload of single lower level protocol frame.
  4. Many to many mapping  -- Many higher level protocol frames are mapped to the payload of many lower level protocol frames. 


What ever be the layering scenario , the basic principle to generate a layering transaction is to randomize the higher level sequence and use byte_pack to convert it to a byte stream and package the bytes in the lower level sequence.