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


Tutorials



VMM CALLBACK



Callback mechanism is used for altering the behavior of the transactor without modifying the transactor. One of the many promises of Object-Oriented programming is that it will allow for plug-and-play re-usable verification components. Verification Designers will hook the transactors together to make a verification environment. In SystemVerilog, this hooking together of transactors can be tricky. Callbacks provide a mechanism whereby independently developed objects may be connected together in simple steps.

This article describes vmm callbacks. Vmm callback might be used for simple notification, two-way communication, or to distribute work in a process. Some requirements are often unpredictable when the transactor is first written. So a transactor should provide some kind of hooks for executing the code which is defined afterwards. In vmm, these hooks are created using callback methods. For instance, a driver is developed and an empty method is called before driving the transaction to the DUT. Initially this empty method does nothing. As the implementation goes, user may realize that he needs to print the state of the transaction or to delay the transaction driving to DUT or inject an error into transaction. Callback mechanism allows executing the user defined code in place of the empty callback method. Other example of callback usage is in monitor. Callbacks can be used in a monitor for collecting coverage information or for hooking up to scoreboard to pass transactions for self checking. With this, user is able to control the behavior of the transactor in verification environment and individual testcases without doing any modifications to the transactor itself.

Following are the steps to be followed to create a transactor with callbacks. We will see simple example of creating a Driver transactor to support callback mechanism.

1) Define a facade class.
Extend the vmm_xactor_callbacks class to create a faced class.
Define required callback methods. All the callback methods must be virtual.
In this example, we will create callback methods which will be called before driving the packet and after driving the packet to DUT.


class Driver_callbacks extends vmm_xactor_callbacks;

virtual task pre_send(); endtask
virtual task post_send(); endtask

endclass


2) Calling callback method.
Inside the transactor, callback methods should be called whenever something interesting happens.
We will call the callback method before driving the packet and after driving the packet. We defined 2 methods in facade class. We will call pre_send() method before sending the packet and post_send() method after sending the packet.

Using a `vmm_callback(,) macro, callback methods are called.
There are 2 argumentd to `vmm_callback(,) macro.
First argument must be the facade class.
Second argument must be the callback method in the facade class.

To call pre_send() method , use macro
`vmm_callback(Driver_callbacks,pre_send());
and simillary to call post_send() method,
`vmm_callback(Driver_callbacks,post_send());

Place the above macros before and after driving the packet.



virtual task main();
super.main();

forever begin
`vmm_callback(Driver_callbacks,pre_send());
$display(" Driver: Started Driving the packet ...... %d",$time);
// Logic to drive the packet goes hear
// let's consider that it takes 40 time units to drive a packet.
#40;
$display(" Driver: Finished Driving the packet ...... %d",$time);
`vmm_callback(Driver_callbacks,post_send());
end
endtask



With this, the Driver implementation is completed with callback support.



Complete Source Code


class Driver_callbacks extends vmm_xactor_callbacks;

virtual task pre_send(); endtask
virtual task post_send(); endtask

endclass


class Driver extends vmm_xactor;

function new();
super.new("Driver","class");
endfunction

virtual task main();
super.main();

forever begin
`vmm_callback(Driver_callbacks,pre_send());
$display(" Driver: Started Driving the packet ...... %d",$time);
// Logic to drive the packet goes hear
// let's consider that it takes 40 time units to drive a packet.
#40;
$display(" Driver: Finished Driving the packet ...... %d",$time);
`vmm_callback(Driver_callbacks,post_send());
end
endtask

endclass



Let's run the driver in simple testcase. In this testcase, we are not changing any callback methods definitions.


Testcase 1 Source Code


program testing_callbacks();
Driver drvr = new();
initial
begin
#100 drvr.start_xactor();
#200 drvr.stop_xactor();
end
endprogram

(S) Download files


vmm_callback.tar
Browse the code in vmm_callback.tar


(S) Command to run the simulation
vcs -sverilog -f filelist -R -ntb_opts rvm -ntb_opts dtm

(S) Log report

Driver: Started Driving the packet ...... 100
Driver: Finished Driving the packet ...... 140
Driver: Started Driving the packet ...... 140
Driver: Finished Driving the packet ...... 180
Driver: Started Driving the packet ...... 180
Driver: Finished Driving the packet ...... 220
Driver: Started Driving the packet ...... 220
Driver: Finished Driving the packet ...... 260
Driver: Started Driving the packet ...... 260
Driver: Finished Driving the packet ...... 300
Driver: Started Driving the packet ...... 300
$finish at simulation time 300



Following steps are to be performed for using callback mechanism to do required functionality.
We will see how to use the callbacks which are implemented in the above defined driver in a testcase.

1) Implement the user defined callback method by extending facade class of the driver class.
We will delay the driving of packet be 20 time units using the pre_send() call back method.
We will just print a message from post_send() callback method.


class Custom_Driver_callbacks_1 extends Driver_callbacks;

virtual task pre_send();
$display("CB_1:pre_send: Delaying the packet driving by 20 time units. %d",$time);
#20;
endtask

virtual task post_send();
$display("CB_1:post_send: Just a message from post send callback method \n");
endtask



2) Construct the user defined facade class object.


Custom_Driver_callbacks CDc = new();


3) Register the callback method. vmm_xactor class has append_callback() which is used to register the callback.



drvr.append_callback(CDc_1);

Testcase 2 Source Code


program testing_callbacks();
Driver drvr = new();

class Custom_Driver_callbacks_1 extends Driver_callbacks;

virtual task pre_send();
$display("CB_1:pre_send: Delaying the packet driving by 20 time units. %d",$time);
#20;
endtask

virtual task post_send();
$display("CB_1:post_send: Just a message from post send callback method \n");
endtask

endclass

Custom_Driver_callbacks_1 CDc_1 = new();
initial
begin
drvr.append_callback(CDc_1);
#100 drvr.start_xactor();
#200 drvr.stop_xactor();
end
endprogram

(S) Download the example


vmm_callback_1.tar
Browse the code in vmm_callback_1.tar


(S) Simulation Command
vcs -sverilog -f filelist -R -ntb_opts rvm -ntb_opts dtm



Run the testcase. See the log results; We delayed the driving of packet by 20 time units using callback mechanism. See the difference between the previous testcase log and this log.


(S) Log report

CB_1:pre_send: Delaying the packet driving by 20 time units. 100
Driver: Started Driving the packet ...... 120
Driver: Finished Driving the packet ...... 160
CB_1:post_send: Just a message from post send callback method

CB_1:pre_send: Delaying the packet driving by 20 time units. 160
Driver: Started Driving the packet ...... 180
Driver: Finished Driving the packet ...... 220
CB_1:post_send: Just a message from post send callback method

CB_1:pre_send: Delaying the packet driving by 20 time units. 220
Driver: Started Driving the packet ...... 240
Driver: Finished Driving the packet ...... 280
CB_1:post_send: Just a message from post send callback method

CB_1:pre_send: Delaying the packet driving by 20 time units. 280
Driver: Started Driving the packet ...... 300
$finish at simulation time 300





Now we will see registering 2 callback methods.
1) Define another user defined callback methods by extending facade class.


class Custom_Driver_callbacks_2 extends Driver_callbacks;

virtual task pre_send();
$display("CB_2:pre_send: Hai .... this is from Second callback %d",$time);
endtask

endclass


2) Construct the user defined facade class object.


Custom_Driver_callbacks_2 CDc_2 = new();


3) Register the object


drvr.append_callback(CDc_2);

Testcase 3 Source Code


program testing_callbacks();
Driver drvr = new();

class Custom_Driver_callbacks_1 extends Driver_callbacks;

virtual task pre_send();
$display("CB_1:pre_send: Delaying the packet driving by 20 time units. %d",$time);
#20;
endtask

virtual task post_send();
$display("CB_1:post_send: Just a message from post send callback method \n");
endtask

endclass

class Custom_Driver_callbacks_2 extends Driver_callbacks;

virtual task pre_send();
$display("CB_2:pre_send: Hai .... this is from Second callback %d",$time);
endtask


endclass

Custom_Driver_callbacks_1 CDc_1 = new();
Custom_Driver_callbacks_2 CDc_2 = new();
initial
begin
drvr.append_callback(CDc_1);
drvr.append_callback(CDc_2);
#100 drvr.start_xactor();
#200 drvr.stop_xactor();
end
endprogram

(S) Download source code


vmm_callback_2.tar
Browse the code in vmm_callback_2.tar


(S) Command to run the simulation
vcs -sverilog -f filelist -R -ntb_opts rvm -ntb_opts dtm



Run the testcase and analyze the result.


(S) Log report

CB_1:pre_send: Delaying the packet driving by 20 time units. 100
CB_2:pre_send: Hai .... this is from Second callback 120
Driver: Started Driving the packet ...... 120
Driver: Finished Driving the packet ...... 160
CB_1:post_send: Just a message from post send callback method

CB_1:pre_send: Delaying the packet driving by 20 time units. 160
CB_2:pre_send: Hai .... this is from Second callback 180
Driver: Started Driving the packet ...... 180
Driver: Finished Driving the packet ...... 220
CB_1:post_send: Just a message from post send callback method

CB_1:pre_send: Delaying the packet driving by 20 time units. 220
CB_2:pre_send: Hai .... this is from Second callback 240
Driver: Started Driving the packet ...... 240
Driver: Finished Driving the packet ...... 280
CB_1:post_send: Just a message from post send callback method

CB_1:pre_send: Delaying the packet driving by 20 time units. 280
CB_2:pre_send: Hai .... this is from Second callback 300
Driver: Started Driving the packet ...... 300
$finish at simulation time 300




The log results show that pre_send() method of CDc_1 is called first and then pre_send() method of Cdc_2. This is beacuse of the order of the registering callbacks.


drvr.append_callback(CDc_1);
drvr.append_callback(CDc_2);



Now we will see how to change the order of the callback method calls.
Use prepend_callback() method for registering instead of append_callback() method.


Testcase 4 Source Code


program testing_callbacks();
Driver drvr = new();

class Custom_Driver_callbacks_1 extends Driver_callbacks;

virtual task pre_send();
$display("CB_1:pre_send: Delaying the packet driving by 20 time units. %d",$time);
#20;
endtask

virtual task post_send();
$display("CB_1:post_send: Just a message from post send callback method \n");
endtask

endclass

class Custom_Driver_callbacks_2 extends Driver_callbacks;

virtual task pre_send();
$display("CB_2:pre_send: Hai .... this is from Second callback %d",$time);
endtask


endclass

Custom_Driver_callbacks_1 CDc_1 = new();
Custom_Driver_callbacks_2 CDc_2 = new();
initial
begin
drvr.append_callback(CDc_1);
drvr.prepend_callback(CDc_2);
#100 drvr.start_xactor();
#200 drvr.stop_xactor();
end
endprogram

(S) Download the source code


vmm_callback_3.tar
Browse the code in vmm_callback_3.tar


(S) Command to run the simulation
vcs -sverilog -f filelist -R -ntb_opts rvm -ntb_opts dtm



Run and analyze the results.
Log results show that, pre_send() method of CDs_1 is called after calling CDs_2 pre_send() method.


(S) Log file report

CB_2:pre_send: Hai .... this is from Second callback 100
CB_1:pre_send: Delaying the packet driving by 20 time units. 100
Driver: Started Driving the packet ...... 120
Driver: Finished Driving the packet ...... 160
CB_1:post_send: Just a message from post send callback method

CB_2:pre_send: Hai .... this is from Second callback 160
CB_1:pre_send: Delaying the packet driving by 20 time units. 160
Driver: Started Driving the packet ...... 180
Driver: Finished Driving the packet ...... 220
CB_1:post_send: Just a message from post send callback method

CB_2:pre_send: Hai .... this is from Second callback 220
CB_1:pre_send: Delaying the packet driving by 20 time units. 220
Driver: Started Driving the packet ...... 240
Driver: Finished Driving the packet ...... 280
CB_1:post_send: Just a message from post send callback method

CB_2:pre_send: Hai .... this is from Second callback 280
CB_1:pre_send: Delaying the packet driving by 20 time units. 280
Driver: Started Driving the packet ...... 300
$finish at simulation time 300



Vmm also provides method to remove the callback methods which are registered.


Index
Introduction
Vmm Log
Vmm Env
Vmm Data
Vmm Channel
Vmm Atomic Generator
Vmm Xactor
Vmm Callback
Vmm Test
Vmm Channel Record And Playback
Vmm Scenario Generator
Vmm Opts

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