Nothing Special   »   [go: up one dir, main page]

OVM Open Verification Methodology: Prepared By: Saurabh Jain

Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 42

OVM

open verification methodology

Prepared by: saurabh jain


Agenda

 Introduction to OVM
 OVM Overview
 Transaction Level Modeling(TML)
 Example:XBUS
Benefit of OVM
Agenda

 Introduction to OVM
 Thinking about verification
 OVM Overview

 Transaction Level Modeling(TML)

 Example:XBUS
Thinking About Verification
 Start with a Plan
 The design specification states

 What the design does


 The verification plan states

 How to ensure that the design does (and doesn’t


do) what is specified
 Both “positive” and “negative” verification is
needed
 Approach the problem in a methodical way
 Break it down

 Take it one step at a time

 Relax

 Productive verification structure


 Execution

 End users and use model


Developing a verification plan
Agenda
 Introduction to OVM
 OVM overview
 Introduction to OVM
 OVC Overview
 The system verilog class library
 Transaction level modelingI(TLM)
 Example: XBUS
What is OVM ?
 OVM is a complete verification methodology that codifies the
best practices for development of verification environments
targeted at verifying large gate-count, IP-based SoCs.

 Verification productivity stems from the ability to quickly


develop individual verification components, encapsulate them
into larger reusable verification components (OVCs), and
reuse them in different configurations
Introduction to OVM

 OVM provides the best framework to achieve coverage-


driven verification (CDV).

 purpose of CDV
• Eliminate the effort and time spent creating hundreds of
tests.
• Ensure thorough verification using up-front goal setting.
• Receive early error notifications and deploy run-time
checking and error analysis to simplify debugging
Overview of OVC
 An OVM testbench is composed of reusable verification
environments called OVM verification components
(OVCs).

 Features of OVC

An OVC is an encapsulated, ready-to-use, configurable


verification environment for an interface protocol, a
design sub-module, or a full system.

The OVC is applied to the (DUT) to verify your


implementation

These OVCs might be stored in a company repository


and reused for multiple verification environments.
Components of OVC
 Data item(transaction)
Data items represent the input to the DUT
 Driver (BFM)
receives a data item and drives it to the DUT by
sampling and driving the DUT signals.
 Sequencer
 advanced stimulus generator that controls the items that
are provided to the driver for execution
 Monitor .
samples the DUT signal but does not drive them
Performs checking and coverage
 Agent
Encapsulate a driver,sequencer and monitor
OVM class library

 provides all the building blocks you need to quickly


develop well-constructed, reusable, verification
components and test environments

 The library consists of base classes, utilities, and


macros.
OVM class Hierarchy
OVM Environment Using OVM
library class
Transaction level modeling (TLM)
 TLM is all about communication through
interfaces
 A TLM port specifies the set of methods to be

used
 A TLM export supplies the implementation of

the methods
 Connections are between ports/exports, not
components
 Transactions are objects
 Components with the same interfaces can be
swapped transparently
 No changes to parent connect()
Basic TLM Communication
 class producer extends
ovm_component;
 ovm_blocking_put_port
#(simple_trans) put_port; // 1
parameter
 function new( string name,
ovm_component parent);
 put_port = new(“put_port”, this);  class consumer extends ovm_component;
 ...  ovm_blocking_put_imp #(simple_trans,
 endfunction consumer) put_export; // 2 parameters
 virtual task run();  ...
 simple_trans t;  task put(simple_trans t);
 for(int i = 0; i < N; i++) begin  case(t.kind)
 // Generate t. put_port.put(t);  READ: // Do read.
 end  WRITE: // Do write.
 endtask  endcase
 endtask
 endclass
Communication Between Processes:
using tlm fifo

 class my_env extends ovm_env;


 ...
 virtual function void connect();
 // component.port.connect(target.export);
 producer.blocking_put_port.connect(fifo.put_export);
 get_consumer.get_port.connect(fifo.get_export);
 ...
 endfunction
 endclass
Factory
 The OVM does not require instantiation of individual components,
as in the following example.

 red my_a;
 my_a = new(“a”,this); // hard-coded instantiation/allocation

 Instead, the OVM facilitates reuse and customization through a


class factory, which is a standard object-oriented technique allowing
components to be instantiated and initialized on-the-fly from a
central location as follows.

 ovm_component cmp;
 cmp = create_component(“red”, “a”); // flexible instantiation
 $cast(my_a,cmp);
 The advantage of using the class factory is that it may be overridden
to customize the environment.

ovm_factory::set_type_override(“red”, “blue”);
ovm_factory::set_inst_override(“top.a”, “red”, “green”);

 The set_type_override() method tells the class factory to return a


component of type blue whenever a red is requested.
Programmable Phasing
 Built-in phases handle the basics
 All phases run in-order

Instantiate top-level env

new Build/config components


Construction
post_new Define connections
Elaboration build/connect Resolve bindings
end_of_elaboration Configure components
Simulation configure Execute test (run task)
run Gather information
Report extract
check Check results
report Report results
Top file

Top Module

Test (Class) Test extends ovm_test

Environment

DUT

22
XBUS Demo Architecture
XBUS Transfer
 typedef enum { NOP,
 READ,
 WRITE
 } xbus_read_write_enum;

 class xbus_transfer extends ovm_sequence_item;

 rand bit [15:0] addr;


 rand xbus_read_write_enum read_write;
 rand int unsigned size;
 rand bit [7:0] data[];
rand int unsigned transmit_delay = 0;

 constraint c_read_write {
 read_write inside { READ, WRITE };
 }
 constraint c_size {
 size inside {1,2,4,8};
 }

 constraint c1 { addr < 16’h2000; }


 ……
 `….
 ovm_object_utils_begin(xbus_transfer)
 `ovm_field_int (addr, OVM_ALL_ON)
 `ovm_field_enum (xbus_read_write_enum, read_write, OVM_ALL_ON)
 `ovm_field_int (size, OVM_ALL_ON)
 `ovm_field_array_int(data, OVM_ALL_ON)
 `ovm_object_utils_end
 endclass : xbus_transfer
XBUS Driver

 Xbus_demo_tb0.xbus0.master0.driver
 class xbus_master_driver extends ovm_driver
#(xbus_transfer);
 Xbus_transfer trans;
 // The virtual interface used to drive and view HDL
signals.
 protected virtual xbus_if xmi;
 // OVM automation macros for general
components
 `ovm_component_utils(xbus_master_driver)
 // Constructor
 function new (string name , ovm_component
parent);
 super.new(name, parent);
 endfunction : new
 // assign_vi
 function void assign_vi(virtual interface xbus_if
xmi);
 this.xmi = xmi;
 endfunction : assign_vi
 task run();
 ...
 @(negedge xmi.sig_reset);
 forever begin // Repeat the following forever.
 @(posedge xmi.sig_clock);
 seq_item_port.get_next_item(trans); // Pull item
from sequencer.
 ...
 drive_transfer(trans); // Drive item onto signal-
level bus.
 ...
 seq_item_port.item_done(); // Indicate we are
done.
 end
 endtask
task drive_item (input xbus_transfer trans);
 ... // Add your logic here.
 endtask : drive_item
 endclass : xbus_master_driver
XBUS Sequencer
Xbus_demo_tb0.xbus0.master0.sequencer
 class xbus_master_sequencer extends ovm_sequencer #(xbus_transfer);

 // The virtual interface used to drive and view HDL signals.


 protected virtual xbus_if xmi;

 `ovm_sequencer_utils_begin(xbus_master_sequencer)
 //
 `ovm_sequencer_utils_end

 // new - constructor
 function new (string name, ovm_component parent);
 super.new(name, parent);
 `ovm_update_sequence_lib_and_item(xbus_transfer)
 endfunction : new

 // assign_vi
 function void assign_vi(virtual interface xbus_if xmi);
 this.xmi = xmi;
 endfunction

 endclass : xbus_master_sequencer

 `endif // XBUS_MASTER_SEQUENCER_SV
XBUS Agent
 class xbus_master_agent extends ovm_agent;
protected ovm_active_passive_enum is_active = OVM_ACTIVE;
 xbus_master_driver driver;
 xbus_master_sequencer sequencer;
 xbus_master_monitor monitor;
 // Provide implementations of virtual methods such as get_type_name and
create
 `ovm_component_utils_begin(xbus_master_agent)
 `ovm_field_enum(ovm_active_passive_enum, is_active, OVM_ALL_ON)
 `ovm_component_utils_end
 function void build();
 super.build();
 monitor = xbus_master_monitor::type_id::create("monitor", this);
 if (is_active == OVM_ACTIVE) begin
 sequencer = xbus_master_sequencer::type_id::create("sequencer", this);
 driver = xbus_master_driver::type_id::create("driver", this);
 end
 endfunction : build
 function void connect();
 if (is_active == OVM_ACTIVE) begin
 driver.seq_item_port.connect(sequencer0.seq_item_export);
 end
 endfunction
 // assign the virtual interfaces of the agent's children
 function void assign_vi(virtual interface xbus_if xmi);
 monitor.assign_vi(xmi);
 if (is_active == OVM_ACTIVE) begin
 sequencer.assign_vi(xmi);
 driver.assign_vi(xmi);
 end
 endfunction : assign_vi
 End class
XBUS Environment
 class xbus_env extends ovm_env;
 // Virtual Interface variable
 protected virtual interface xbus_if xi0;
 // Control properties
 protected bit has_bus_monitor = 1;
 protected int unsigned num_masters = 0;
 protected int unsigned num_slaves = 0;

 // The following two bits are used to control whether checks and coverage are
 // done both in the bus monitor class and the interface.
 bit intf_checks_enable = 1;
 bit intf_coverage_enable = 1;

 // Components of the environment


 xbus_bus_monitor bus_monitor;
 xbus_master_agent masters[];
 xbus_slave_agent slaves[];

 // Provide implementations of virtual methods such as get_type_name and create


 `ovm_component_utils_begin(xbus_env)
 `ovm_field_int(has_bus_monitor, OVM_ALL_ON)
 `ovm_field_int(num_masters, OVM_ALL_ON)
 `ovm_field_int(num_slaves, OVM_ALL_ON)
 `ovm_field_int(intf_checks_enable, OVM_ALL_ON)
 `ovm_field_int(intf_coverage_enable, OVM_ALL_ON)
 `ovm_component_utils_end
 function void build();
 string inst_name;
 super.build();
 if(has_bus_monitor == 1) begin
 bus_monitor = xbus_bus_monitor::type_id::create("bus_monitor",
this);
 end
 masters = new[num_masters];
 for(int i = 0; i < num_masters; i++) begin
 $sformat(inst_name, "masters[%0d]", i);
 masters[i] = xbus_master_agent::type_id::create(inst_name, this);
 end
 slaves = new[num_slaves];
 for(int i = 0; i < num_slaves; i++) begin
 $sformat(inst_name, "slaves[%0d]", i);
 slaves[i] = xbus_slave_agent::type_id::create("xbus_slave_agent",
 this);
 end
 endfunction: build
Testbench Environment
xbus_demo_tb.sv
 class xbus_demo_tb extends ovm_env;
 // Provide implementations of virtual methods such as get_type_name and create
 `ovm_component_utils(xbus_demo_tb)
 // xbus environment
 xbus_env xbus0;
 // Scoreboard to check the memory operation of the slave.
 xbus_demo_scoreboard scoreboard0;
 function void build();
 super.build();
 set_config_int("xbus0", "num_masters", 1);
 set_config_int("xbus0", "num_slaves", 1);
 xbus0 = xbus_env::type_id::create("xbus0", this);
 scoreboard0 = xbus_demo_scoreboard::type_id::create("scoreboard0", this);
 endfunction : build
 function void connect();
 // Connect the slave0 monitor to scoreboard.
 xbus0.slaves[0].monitor.item_collected_port.connect(
 scoreboard0.item_collected_export);
 // Assign interface for xbus0.
 xbus0.assign_vi(xbus_tb_top.xi0);
 endfunction : connect
 function void end_of_elaboration();
 // body
 endfunction : end_of_elaborationct
 test_lib.sv

 `include "xbus_demo_tb.sv"
 class xbus_demo_base_test extends ovm_test;
 `ovm_component_utils(xbus_demo_base_test)
 xbus_demo_tb xbus_demo_tb0; // XBus verification
environment
 function new(string name = "xbus_demo_base_test",
 ovm_component parent=null);
 super.new(name, parent);
 endfunction
 // OVM build() phase
 virtual function void build();
 super.build();
 // Enable transaction recording.
 set_config_int("*", "recording_detail", OVM_FULL);
 // Create the testbench.
 xbus_demo_tb0 =
xbus_demo_tb::type_id::create("xbus_demo_tb0",
this);
 endfunction
 // Built-in OVM phase
 function void end_of_elaboration();
 // Set verbosity for the bus monitor.
 endfunction : end_of_elaboration();
 // OVM run() phase
 task run();
 #2000;
 // Call global_stop_request() to end the run phase.
 global_stop_request();
 endtask
 endclass
OVM Benefits
 Bringing in the best of URM and AVM
 Structuring the Verification Environment for Reuse
 Separating Tests from Testbench
 Pure SystemVerilog
 Apache License
 Runs under Cadence Incisive & Mentor QuestaSim
 Runs under any ‘SystemVerilog Simulator’
Thank you

You might also like