Debugging is a methodical process of finding and reducing the number of bugs. When a the outputs are of the DUT are not what expected, then a bug may be in DUT or sometimes it may be in testbench. Debuggers are software tools which enable the verification and design engineers to monitor the execution of a program, stop it, re-start it, run it in interactive mode.
The basic steps in debugging are:
--- Recognize that a bug exists
--- Isolate the source of the bug
--- Identify the cause of the bug
--- Determine a fix for the bug
--- Apply the fix and test it
Pass Or Fail
At the end of simulation of every test, TEST FAILED or TEST PASSED report should be generated. This is called self checking. Log files and Waveform viewer can help for further debugging if test failed.
An error count should be maintained to keep track of number of errors occurred. Simplest way to increment an error counter is using named event.
EXAMPLE: module top();
//ur testbench logic
initial begin #10;
if("There is error ")
if("There is error ")
if("There is error ")
// call final block to finish simulation
//Initilize error to 0
initial error = 0;
// count number of errors
error = error +1 ;
// final block--to end simulation
begin #10; // so delay to make sure that counter increments for the last triggered error.
if( error == 0)
$dsplay("************ TEST PASSED ***************");
else $dsplay("************ TEST FAILED ***************");
For post process debug, Waveform viewer needs VCD(value change dump) file. A value change dump (VCD) file contains information about value changes on selected variables in the design stored by value change dump system tasks. Two types of VCD files exist:
a) Four state: to represent variable changes in 0, 1, x, and z with no strength information.
b) Extended: to represent variable changes in all states and strength information.
This clause describes how to generate both types of VCD files and their format.
The steps involved in creating the four state VCD file are listed below .
a) Insert the VCD system tasks in the Verilog source file to define the dump file name and to specify the variables to be dumped.
b) Run the simulation.
A VCD file is an ASCII file which contains header information, variable definitions, and the value changes for all variables specified in the task calls. Several system tasks can be inserted in the source description to create and control the VCD file.
The $dumpfile task shall be used to specify the name of the VCD file.
initial $dumpfile ("my_dump_file");
$dumpvar //Dump all the variables
// Alternately instead of $dumpvar, one could use
$dumpvar(1, top) //Dump variables in the top module.
$dumpvar(2, top) //Dumps all the variables in module top and 1 level below.
Executing the $dumpvars task causes the value change dumping to start at the end of the current simulation time unit. To suspend the dump, the $dumpoff task may be invoked. To resume the dump, the $dumpon task may be invoked.
Due to dumping the value changes to a file,there is simulation over head. Not all the time the dumping is required. So controlling mechanism to dump VCD files needs to be implemented.
EXAMPLE: `ifdef DUMP_ON
Log file keeps track of the operation in text format. Using Display system tasks, proper information can be sent to log files. The display group of system tasks are divided into three categories: the display and write tasks, strobed monitoring tasks, and continuous monitoring tasks.
These are the main system task routines for displaying information. The two sets of tasks are identical except that $display automatically adds a newline character to the end of its output, whereas the $write task does not.
The system task $strobe provides the ability to display simulation data at a selected time. That time is the
end of the current simulation time, when all the simulation events that have occurred for that simulation
time, just before simulation time is advanced.
$monitor displays when any of the arguments values change.
Message Control System:
Sending message to log file is useful for debugging. But what messages are useful to send and not. Sometimes only few messages are required to send to log file, other times very detailed messages. If the number of messages are more, the simulation time is more. So messaging should be controllable.
begin `ifdef DEBUG
$display(" ERROR : at %d ",$time);
With the above approach only one level of controlling is achieved. Messages can be conveyed with wide range of severity levels. Following is the message controlling system I used in my projects. This has 3 levels of controllability and 3 severity levels.
Message Severity Levels:
Following are the 4 severity levels of messaging:
The messages is used to convey simple information.
This message conveys that some this is bad but doesn't stop the simulation.
This messages indicate that some error has occurred. Simulation can be terminated.
These messages are for debugging purpose.
NOTE: %m prints hierarchy path.
$display(" INFO : %t : UR MESSAGE GOES HEAR",$time);
$display(" WARN : %t : UR MESSAGE GOES HEAR",$time);
$display(" EROR : %t : UR MESSAGE GOES HEAR",$time);
$display(" DBUG : %t : UR MESSAGE GOES HEAR",$time);
Message Controlling Levels
By default ,messages INFO, WARN and EROR are logged. When a special switch is used, Debug messages are logged. This example also removes lot of manly coding.
EXAMPLE: `ifndef DEBUG
`define SHOW 0
`define SHOW 1
The above results show that DEBUG messages can be disable if not needed.
With the above approach, the controllability is at compilation level. If the controllability is at simulation level, compilation time can be saved. The following message controlling system has controllability at simulation level.
This is simple trick and very useful. By passing some comments to waveform, debugging becomes easy. Just declare a string and keep updating the comments. There is no slandered way to pass comments to waveform debugger but some tools have their own methods to do this job.
initial begin #10 status = 8'b10101010;
comment = Preambel;
#10 status = 8'b10101011;
comment = Startofpkt;
The reg " Comment " holds string. This strings can be viewed in waveform debugger.
$Display N $Strobe
According to scheduling semantics of verilog, $display executes before the nonblocking statements update LHS. Therefore if $display contains LHS variable of nonblocking assignment, the results are not proper. The $strobe command shows updated values at the end of the time step after all other commands, including nonblocking assignments, have completed.
EXAMPLE: module disp_stro;
initialbegin a = 0;
a <= 1;
$display(" $display a=%b", a);
$strobe (" $strobe a=%b", a);
#1 $display("#1 $display a=%b", a);
end endmodule RESULTS:
$display a=0 $strobe a=1 #1 $display a=1
Who Should Do The Rtl Debugging?
One of the important question in debugging is who should do the RTL debugging? Verification engineer or the RTL designer?
I personally like to debug the RTL as verification engineer. This is a great opportunity to know RTL methodology. This also improves my understanding ability of RTL. Sometimes test fails because of the Verification environment, before I go and ask RTL designer, I am sure that there is no bug in my environment. By debugging RTL, the bug report is more isolated and designer can fix it sooner. Designer is fast enough to catch cause of the bug, as he knows more about the RTL then verification engineer. Verification and Designer should sit together and debug the issue, if the bug is in RTL, verification engineer can file the bug, if it is in Testbench, no need to file it.