Post on 30-Oct-2014
description
Open verification methodology
BY
SHAIK MOHAMMED NAWAZ
SOCtronics technologies.
Introduction to Methodologies• What is a Methodology?
−Methodology is a systematic way of doing things with a rich set of standard rules and guidelines. Methodology provides the necessary infrastructure to build a robust, reliable and complete Verification environment.
Why do we go for Verification Methodology?
• Methodology is basically set of base
class library which we can use to
build our test benches.
Continued..!!!
• Just for an example consider transaction
class. Common functions you will require
here is display, compare, copy
transactions..etc.
• Now what you will do is, you will keep
these common functions in some
common area and you will access them
through out the design. So this common
area is nothing but your 'methodology'.
Continued..!!!
• So the verification giants have
already defined such common
classes and functions which we will
mostly require to build test benches
and have formed one library. That's
it; they call this base class library
a methodology
why 'base' class library?
• Well you can extend these classes
to function it as per your
requirement.
Methodologies have following advantages
Methodology Based verification includes:
List of verification Methodologies • AVM Advanced Verification Methodology
(System C & Systemverilog) by Mentor
Graphics
• RVM Reference Verification Methodology
(open Vera) by Synopsys
• OVM Open verification Methodology
(systemverilog) by Mentor Graphics
• VMM Verification Methodology Manual
(systemverilog) by Synopsys
• OVM is explored in this presentation.
OVM VERIFICATION ENVIRONMENT
• The OVM Verification environment consist
of OVM components like− OVM Transactor−OVM Sequencer−OVM sequence− OVM Driver−OVM Monitor−OVM Scoreboard
OVM Transaction
• A transaction is data item which is
eventually or directly processed by
the DUT.− packets, instructions, pixels are data
items.
• In ovm, transactions are extended
from− ovm_transactions class− or ovm_sequence_item class.
Continued ..!!!
• Transactions are extended from
ovm_transaction if randomization is
not done in sequence and
transactions are extended from
ovm_sequence_item if the
randomization is done in sequence.
Example(Transaction)
class alu_item extends ovm_sequence_item;
//This Example uses the sequencer hence the transaction class must be derived from
//ovm_sequence_item class, which is child class of ovm_transaction.
rand reg [ 7:0] data_in1 ;
rand reg [ 7:0] data_in2 ;
rand reg [ 2:0] select;
rand bit reset_N;
constraint rest_c1{reset_N == 1'b1;}
`ovm_object_utils_begin (alu_item)
`ovm_field_int(data_in1 , OVM_ALL_ON)
`ovm_field_int(data_in2 , OVM_ALL_ON)
`ovm_field_int(select , OVM_ALL_ON)
`ovm_field_int(reset_N , OVM_ALL_ON)
`ovm_object_utils_end
Example continued..!!!
// new constructor
//constructor new is passed a string used to build
//unique instance name of transaction.function new (string name = "alu transaction instant") ;
super.new(name);
endfunction
endclass
Continued...!!!• As transactions are created we need to copy, compare,
print, pack, and unpack those transactions is done
automatically by inbuilt ovm macros as shown below.
`ovm_object_utils_begin (alu_item)
`ovm_field_int(data_in1 , OVM_ALL_ON)
`ovm_field_int(data_in2 , OVM_ALL_ON)
`ovm_field_int(select , OVM_ALL_ON)
`ovm_field_int(reset_N , OVM_ALL_ON)
`ovm_object_utils_end
• The flag OVM_ALL_ON indicates that the given field
should be copied printed, included in any comparison for
equality between two transactions, and so on.
OVM sequence.
• A sequence is a series of transaction. User can
define the complex stimulus. sequences can be
reused, extended, randomized, and combined
sequentially and hierarchically in various ways.
• A complete sequence generation requires
following 4 classes.
1- Sequence item(Transaction).
2- Sequence
3- Sequencer
4- Driver
sequence:
• User should extend ovm_sequence class and
define the construction of sequence of
transactions. These transactions can be directed,
constrained randomized or fully randomized
//example
• class ovm_sequence #(
type REQ = ovm_sequence_item,
type RSP = REQ
)
Sequencer:• sequencer is responsible for the coordination
between sequence and driver.
• Sequencer sends the transaction to driver and
gets the response from the driver.
• The response transaction from the driver is
optional. When multiple sequences are running
in parallel, then sequencer is responsible for
arbitrating between the parallel sequences.
• There are two types of sequencers :
ovm_sequencer and ovm_push_sequencer
Continued..!!!
//example for sequencer
• class ovm_sequencer #(
type REQ = ovm_sequence_item,
type RSP = REQ
)
//example for push sequencer
class ovm_push_sequencer #(
type REQ = ovm_sequence_item,
type RSP = REQ
)
Driver :• User should extend ovm_driver
class to define driver component.
• ovm driver is a component that
initiate requests for new
transactions and drives it to lower
level components.
• There are two types of drivers:− ovm_driver −and ovm_push_driver.
Continued..!!!• class ovm_driver #(
type REQ = ovm_sequence_item,
type RSP = REQ
)
class ovm_push_driver #(
type REQ = ovm_sequence_item,
type RSP = REQ
)
• In pull mode , ovm_sequencer is connected to ovm_driver ,
in push mode ovm_push_sequencer is connectd to
ovm_push_driver.
Continued..!!!
• Ovm_sequencer and ovm_driver are
parameterized components with request and
response transaction types.
• REQ and RSP types by default are
ovm_sequence_type types. User can specify REQ
and RSP of different transaction types.
• If user specifies only REQ type, then RSP will be
REQ type.
Driver And Sequencer Connectivity: • Deriver and sequencer are connected using TLM.
• Ovm_driver has seq_item_port which is used to get the
transaction from ovm sequencer.
• This port is connected to ovm_sequencer
seq_item_export Using − <driver>.seq_item_port.connect(<sequencer>.seq_item_export);
driver and sequencer can be connected.
• Simillarly "res_port" of driver which is used to send
response from driver to sequencer is connected to
"res_export" of the sequencer using− <driver>.res_port.connect(<sequencer>.res_export);
Continued..!!!
Sequence And Driver Communication:
Continued..!!!
Simple Example• //simple instruction example with
//PUSH_A,PUSH_B,ADD,SUB,MUL,DIV and POP_C.
Sequence item code:
class instruction extends ovm_sequence_item;
typedef enum {PUSH_A,PUSH_B,ADD,SUB,MUL,DIV,POP_C} ins
t_t;
rand inst_t inst;
`ovm_object_utils_begin(instruction)
`ovm_field_enum(inst_t,inst, OVM_ALL_ON)
`ovm_object_utils_end
function new (string name = "instruction");
super.new(name);
endfunction
endclass
• Sequence code
class operation_addition extends ovm_sequence #(instruction);
instruction req;
function new(string name="operation_addition");
super.new(name);
endfunction
`ovm_sequence_utils(operation_addition, instruction_sequencer)
virtual task body();
req = instruction::type_id::create("req");
wait_for_grant();
assert(req.randomize() with {
inst == instruction::PUSH_A;
});
send_request(req);
wait_for_item_done();
//get_response(res); This is optional. Not using in this example.
• req = instruction::type_id::create("req");
wait_for_grant();
req.inst = instruction::PUSH_B;
send_request(req);
wait_for_item_done();
//get_response(res);
req = instruction::type_id::create("req");
wait_for_grant();
req.inst = instruction::ADD;
send_request(req);
wait_for_item_done();
//get_response(res);
req = instruction::type_id::create("req");
wait_for_grant();
req.inst = instruction::POP_C;
send_request(req);
wait_for_item_done();
//get_response(res);
endtask
endclass
• Sequencer Code;
class instruction_sequencer extends ovm_sequencer #(instruction);
function new (string name, ovm_component parent);
super.new(name, parent);
`ovm_update_sequence_lib_and_item(instruction)
endfunction
`ovm_sequencer_utils(instruction_sequencer)
endclass
Driver: • This driver is used in pull mode. Pull mode means, driver
pulls the transaction from the sequencer when it requires.
Ovm driver has 2 TLM ports.
1) Seq_item_port: To get a item from sequencer, driver
uses this port. Driver can also send response back using
this port.
2) Rsp_port : This can also be used to send response back
to sequencer.
Seq_item_port methods:
• class instruction_driver extends ovm_driver #(instruction);
// Provide implementations of virtual methods such as get_type_name and create
`ovm_component_utils(instruction_driver)
// Constructor
function new (string name, ovm_component parent);
super.new(name, parent);
endfunction
task run ();
forever begin
seq_item_port.get_next_item(req);
$display("%0d: Driving Instruction %s",$time,req.inst.name());
#10;
// rsp.set_id_info(req); These two steps are required only if
// seq_item_port.put(esp); responce needs to be sent back to sequence
seq_item_port.item_done();
end
endtask
endclass
Testcase Code:
module test;
instruction_sequencer sequencer; instruction_driver driver;
initial begin set_config_string("sequencer", "default_sequence", "operation_addition"); sequencer = new("sequencer", null); sequencer.build(); driver = new("driver", null); driver.build();
driver.seq_item_port.connect(sequencer.seq_item_export); sequencer.print(); fork begin run_test(); sequencer.start_default_sequence(); end #2000 global_stop_request(); join end
endmodule
Log file Output
OVM_INFO @ 0 [RNTST] Running test ...0: Driving Instruction PUSH_A10: Driving Instruction PUSH_B20: Driving Instruction ADD30: Driving Instruction POP_C
References:
• www.systemverilog.in
• www.asicguru.com
• www.testbench.in
• www.verificationacademy.com
THANK ‘U’