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


Tutorials



DEBUGGING


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(); 
    integer error; 
    event err; 
    //ur testbench logic
    initial  
    begin 
        #10; 
        if("There is error ") 
           -> error; 
        #10 
        if("There is error ") 
           -> error; 
        #10 
        if("There is error ") 
           -> error; 
        // call final block to finish simulation
        
    end 
    
    //Initilize error to 0
    initial 
        error = 0; 
    // count number of errors
    always@(err) 
        error = error +1 ; 
    
    // final block--to end simulation
    task finish(); 
    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 ***************"); 
        
    end 
    endtask 
    
endmodule 



Waveform Viewer:

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.

EXAMPLE:

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 
  $dumpon; 
`endif 


Log File:

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.

EXAMPLE:
always@(error) 
begin 
`ifdef DEBUG 
$display(" ERROR : at %d ",$time); 
`endif 
end 


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:

INFO: 
The messages is used to convey simple information. 
WARNING: 
This message conveys that some this is bad but doesn't stop the simulation. 
ERROR: 
This messages indicate that some error has occurred. Simulation can be terminated. 
DEBUG: 
These messages are for debugging purpose. 
NOTE: %m prints hierarchy path. 
EXAMPLE:

$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 
`else 
 `define SHOW 1 
`endif 


`define INFO $write("INFO : %5t :%m:",$time); $display 
`define WARN $write("WARN : %5t :%m:",$time); $display 
`define EROR $write("EROR : %5t :%m:",$time); $display 
`define DBUG if(`SHOW == 1) $write("DBUG : %t :%m:",$time); if(`SHOW == 1) $display 

module msg(); 

initial 
begin 
#10; 
`INFO("UR MESSAGE GOES HEAR"); 
`WARN("UR MESSAGE GOES HEAR"); 
`EROR("UR MESSAGE GOES HEAR"); 
`DBUG("UR MESSAGE GOES HEAR"); 
end 
endmodule 

When compilation is done without +define+DEBUG 
RESULTS:

INFO :    10 :msg:UR MESSAGE GOES HEAR
WARN :    10 :msg:UR MESSAGE GOES HEAR
EROR :    10 :msg:UR MESSAGE GOES HEAR


When compilation is done with +define+DEBUG 
RESULTS:

INFO :    10 :msg:UR MESSAGE GOES HEAR
WARN :    10 :msg:UR MESSAGE GOES HEAR
EROR :    10 :msg:UR MESSAGE GOES HEAR
DBUG :    10 :msg:UR MESSAGE GOES HEAR



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.

EXAMPLE:

`define INFO $write("INFO : %0t :%m:",$time); $display 
`define WARN $write("WARN : %0t :%m:",$time); $display 
`define EROR $write("EROR : %0t :%m:",$time); $display 
`define DBUG if(top.debug == 1) $write("DBUG : %0t :%m:",$time); if(top.debug == 1) $display 

module top(); 
    reg debug = 0; 
    
    initial 
        if($test$plusargs("DEBUG")) 
            #0 debug = 1; 
    
    initial 
    begin 
        #10; 
        `INFO("UR MESSAGE GOES HEAR"); 
        `WARN("UR MESSAGE GOES HEAR"); 
        `EROR("UR MESSAGE GOES HEAR"); 
        `DBUG("UR MESSAGE GOES HEAR"); 
    end 
endmodule 
When simulation is done without +DEBUG 
RESULTS:

INFO :    10 :top:UR MESSAGE GOES HEAR
WARN :    10 :top:UR MESSAGE GOES HEAR
EROR :    10 :top:UR MESSAGE GOES HEAR


When simulation is done with +DEBUG 
RESULTS:

INFO :    10 :top:UR MESSAGE GOES HEAR
WARN :    10 :top:UR MESSAGE GOES HEAR
EROR :    10 :top:UR MESSAGE GOES HEAR
DBUG :    10 :top:UR MESSAGE GOES HEAR


Passing Comments To Waveform Debugger

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.

EXAMPLE:
module pass_comments(); 
    reg [79 : 0] Comment; // holds 10 characters.
    
    reg [7:0] status; 
    
    initial 
    begin 
        #10 status = 8'b10101010; 
        comment = Preambel; 
        #10 status = 8'b10101011; 
        comment = Startofpkt; 
    end 
endmodule 


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; 
    reg a; 
    
    initial begin 
        a = 0; 
        a <= 1; 
        $display(" $display a=%b", a); 
        $strobe (" $strobe a=%b", a); 
        #1 $display("#1 $display a=%b", a); 
        #1 $finish; 
    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.
 


Index
Introduction
Linear Tb
File Io Tb
State Machine Based Tb
Task Based Tb
Self Checking Testbench
Verification Flow
Clock Generator
Simulation
Incremental Compilation
Store And Restore
Event Cycle Simulation
Time Scale And Precision
Stimulus Generation
System Function Random A Myth
Race Condition
Checker
Task And Function
Process Control
Disableing The Block
Watchdog
Compilation N Simulation Switchs
Debugging
About Code Coverage
Testing Stratigies
File Handling
Verilog Semaphore
Finding Testsenarious
Handling Testcase Files
Terimination
Error Injuction
Register Verification
Parameterised Macros
White Gray Black Box
Regression
Tips

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