SV-AOE: your friendly debug-companion!
Posted by Shankar Hemmady on November 9th, 2009


Ajeetha Kumari & Srinivasan Venkataramanan, Contemporary Verification Consultants (CVC),
Ramanathan Sambamurthy, Cisco Systems
As verification specialists, like some of our readers, we thrive on solving challenging problems. Specifically Debug is an area that fascinates us a lot. Here is one of them, using VCS’s Aspect Oriented Extensions (AOE) to SystemVerilog to debug a Memory blow-up in SV-TB code. The problem statement was elaborated in our previous entry: http://www.vmmcentral.org/vmartialarts/?p=385
We brainstormed on potential improvements in order to shorten debug cycles in the future. One option we explored was the use of SIZED mailboxes, when applicable:
function new();
// parameter MBOX_SIZE = 100;
this.out_mbx = new(MBOX_SIZE);
endfunction : new
A better, scalable option is to use a wrapper class around plain SV Mailboxes. That would then allow AOE to aid in debug around the “put”. For instance, consider a simple class-wrapper around a SV Mailbox:
class mbox_c;
mailbox mbox;
function new(string name);
this.name = name;
this mbox = new();
endfunction : new
virtual task put (my_xactn x0);
this.mobx.put(x0);
endtask : put
// Similarly get(), new() etc.
endclass : mbox_c
Now, instead of a plain mailbox, we have a wrapper around it called mbox_c. Assuming that this wrapper was used all across the environment instead of the mailboxes, one can leverage the VCS’s Aspect Oriented Extensions to SystemVerilog to the rescue. In a separate file one can write:
extends chan_dbg(mbox_c);
before task put(my_xactn x0);
$display (“%m AOE: Mailbox %s size is %0d”, this. name,
this.num());
endtask : put
endextends
In contrast to standard OOP, AOE allows “in-place extensions” and hence adds to existing class code without creating hierarchy new class type. This means no factory is needed to swap the base class with a derived class and other associated extra code. Instead, just an additional file with few lines and you are set to go! While some of us may debate whether this is a good coding style for developing reusable environments, for throw away code like debug this is very handy as it requires no intervention to existing code. For instance, with the above code, a typical VCS run (with the dbg.sv code included in command line) produces the following output:
mbox_c::put_before AOE: Channel S2P_BFM_IN_CHANNEL level is 0
mbox_c::put_before AOE: Channel S2P_SER_MON_OUT_CHANNEL level is 0
mbox_c::put_before AOE: Channel S2P_PAR_MON_OUT_CHANNEL level is 1
mbox_c::put_before AOE: Channel S2P_BFM_IN_CHANNEL level is 0
mbox_c::put_before AOE: Channel S2P_SER_MON_OUT_CHANNEL level is 0
mbox_c::put_before AOE: Channel S2P_PAR_MON_OUT_CHANNEL level is 2
mbox_c::put_before AOE: Channel S2P_BFM_IN_CHANNEL level is 0
mbox_c::put_before AOE: Channel S2P_SER_MON_OUT_CHANNEL level is 0
mbox_c::put_before AOE: Channel S2P_PAR_MON_OUT_CHANNEL level is 3
mbox_c::put_before AOE: Channel S2P_BFM_IN_CHANNEL level is 0
mbox_c::put_before AOE: Channel S2P_SER_MON_OUT_CHANNEL level is 0
mbox_c::put_before AOE: Channel S2P_PAR_MON_OUT_CHANNEL level is 4
mbox_c::put_before AOE: Channel S2P_BFM_IN_CHANNEL level is 0
mbox_c::put_before AOE: Channel S2P_SER_MON_OUT_CHANNEL level is 0
mbox_c::put_before AOE: Channel S2P_PAR_MON_OUT_CHANNEL level is 5
mbox_c::put_before AOE: Channel S2P_SER_MON_OUT_CHANNEL level is 0
mbox_c::put_before AOE: Channel S2P_PAR_MON_OUT_CHANNEL level is 6
Of course, there are few safe-guards for such common pit-falls. We address this topic in our VMM adoption book (http://www.systemverilog.us/vmm_adoption) in Chapter-8, Advanced Topics (Section 8.3).
· A vmm_channel (equivalent of a Mailbox in SV) is blocking and has a default size of 1 (can be increased, reconfigured at run time as well)
· It includes built-in debug messages that can be turned on via command line
· It provides a vmm_channel::sink() routine – can be useful if the consumer is not available for integration
· It allows similar AOE debug extension, a code snippet is shown below:
extends chan_dbg(vmm_channel);
before task put(vmm_data obj, int offset = -1,
`VMM_SCENARIO grabber = null);
$display (“%m AOE: Channel %s level is %0d”,
this.log.get_name(),
this.size());
endtask : put
endextends








