A few tips to debug faster

Did you know ...

 

1. Divide the log handler to handle INFO, DEBUG1, DEBUG2, ERROR messages.

2. For each task/function, display the name and time of the task/function as a DEBUG2 message.

function void myClass :: findMyName; 

`LogMsg (DEBUG2, $sformatf (“%t [Xtr] findMyName started with array %s”, $time, arrayName));

endfunction

3. Whenever you write a DEBUG/INFO/ERROR message, try to include as many variable states as possible in the message.

`LogMsg (DEBUG, $sformatf (“Word not received axiWord = 0x%0h word = 0x%0h …”, axiWord, word));

4. Organize and structure your code, and make a clear demarcation between functions like :

//———————————————————————————–

//                               <Function Name1> {{{1

//————————————————————————————

function  <functionName1> ;

endfunction

//———————————————————————————–

//                               <Function Name2> {{{1

//————————————————————————————

function <functionName2>

endfunction

5. Use vim folding. To enable automatic folds, use {{{1 (for 1 level) like above example. When you hit zM, all open folds will close and you’ll get a clean version with only function names and all details will be tucked into the folds. It’s pretty neat because now you know where a function starts and ends and will save precious time later on.

6. Keep functions and tasks as external components in your class definition. This will help you identify the functions faster, and endclass will not run into multiple PgDn keystrokes away.

7. Use notations like _t (for tasks) _f (for functions) e_ (suffix for Enums) c_ (suffix for constraints) cp_ (suffix for coverpoint) cg_ (suffix for covergroups) a_ (assertions) p_ (property).

8. Keep a track on the hierarchy of classes and prepare a diagram that shows class inheritance structure.

9. Use typedef class <Name>  to forward reference a class object that you intend to use, but haven’t written a definition for.

10. Keep your enums separate in a package, and access them in other classes as :

myEnumPkg :: e_Name  myName;

myName =  myEnumPkg::Wordpress;

or

import myEnumPkg :: *; 

For import, see this before you start using them.

11. Write a perl/python script to parse log files for Errors, Assertions, Warnings. Do this early on and you’ll save a ton of time later.

 

 

Dump waveform in multiple files

Did you know ...

Say, you need to run a huge time consuming simulation that might dump an fsdb waveform with a “larger than disk” size, you have an option to let the simulator split it into multiple smaller sized files so that you can discard unwanted files if it doesn’t have what you are looking for.

$fsdbAutoSwitchDumpFile  – Automatically switch to a new dump file when the working FSDB file reaches the specified size limitation.

$fsdbAutoSwitchDumpfile(File_Size, “FSDB_name”, Number_of_Files [, log_filename]);

Example : 

$fsdbAutoSwitchDumpfile(1000,SOC_fsdb_file,20);

This will dump maximum 20 files in 1GB increments with name SOC_fsdb_file

 

 

Cadence stops support for importing packages in class ?

Compilation Errors, Did you know ...

I was compiling a piece of code

class myClass;
      import myEnum::*;

      …

endclass

when I got this warning

import myEnum::*;
|
ncvlog: *W,INOSTD (pkgEnum.sv,30|15): An import declaration shall not be used inside a class declaration.

ncvlog/INOSTD =
The SystemVerilog standard recently made a clarification regarding the use of imports inside
class declaration: using imports inside classes is not compliant with the 1800 standard.
The support of imports inside classes will be removed in a future release. The recommendation
is to use explicit full package references inside classes or move the imports outside the
class declaration.

Well, I think this sucks. Anyhow, here’s a nice article on the usage of packages and `includes.

http://blogs.mentor.com/verificationhorizons/blog/2010/07/13/package-import-versus-include/

PS : If you don’t like the *W messages in your compilation log, add “-nowarn INOSTD” as a compilation argument and it will stop showing you that particular warning.

Randomization – constrain values uniquely

Did you know ...

A simple way to allot unique values to random variables is described below :

bit [7:0] masterId [6];

rand bit [3:0] number;

function void pre_randomize ();

   foreach (masterId [i]) begin

         masterId [i] = i;

   end

endfunction

function void post_randomize ();

    repeat (number) masterId.shuffle;

endfunction


 

I know it looks dumb, but this is an easy way out. You can substitute i with another array with valid values like

bit [7:0] array [6] = ‘{8’h4e, 8’h5a, 8’hf1, 8’he3, 8’h4, 8’hbb};

function void pre_randomize ();

   foreach (masterId [i]) begin

       masterId [i] = array [i]; 

   end

endfunction

 

that you can get more information on compilation errors ?

Did you know ...

My colleague asked me about this and I thought I’ll post it here. Let’s say you get an error like

ncvlog: *E,NOTCLM (myXtr.sv,62|29): Regrite_t is not a class item

You can do

% nchelp ncvlog NOTCLM

and you’ll get

nchelp: 12.20-s008: (c) Copyright 1995-2013 Cadence Design Systems, Inc.
ncvlog/NOTCLM =
The specified name is not an item (property or method, for example) in the class.

This works for ncelab as well

% nchelp ncelab <ERROR_CODE>

 

Something with `define

Compilation Errors

I was writing code like :

`define SUB(x) reg_ctrl_x_0

genvar num;
generate for (num = 0; num < 10; num = num + 1) begin : myGen
assign mySignal [num] = `SUB (num)
end
endgenerate

I thought it would be alright and guess what, it resulted in a compilation error.
I tried the following things and I was still getting error.

`define _SUB_(X) reg_ctrl_X_0
`define sub(num) reg_ctrl_num_0
`define sub(num) {reg_ctrl, “num”, _0}

and then I realized it. This is taken like a string and it finally worked with
`define sub(num) “reg_ctrl_num_0”

How ARM platform SoC components interact in a TB

Uncategorized

class Processor;

class DDRC;

class Fabric;

class trxn;

Processor.say (SYSTEM, “Hey DDRC ! Wakeup ! your code @ 0x%0h”, codeStartAddr);

DDRC.say (DEBUG, ” Hey Proc, yea it’s been lying here for a while – didn’t see your request “);

Fabric.say (DEBUG, “What’s the core number ?”);

Processor.core0.say (INFO, ” It’s me ! I tried to read Archies comics from DDRC”);

Processor.core1.say (INFO, ” I told you to ask Mama before sending requests !”);

Fabric.say (INFO, “Okay, so I saw a request from %0d”, trxn.coreNum);

Fabric.say (WARNING, ” %s does not have permission to access, so it was denied.”, trxn.coreNum.name);

Processor.say (SYSTEM, “Let my child have access”);

Fabric.say (INFO, “Alrighty, go ahead and resend the request”);

ENUMERR

Compilation Errors

I like my compilation build to be free from warnings. Here’s how to solve this warning.

myObj.pixelValue[0] = 0;

                                 |

ncvlog: *W,ENUMERR (myChecker.sv,528|34): This assignment is a violation of SystemVerilog strong typing rules for enumeration datatypes.


pixelValue is an enumerated data type like :

typedef enum reg [1:0] {

PV_ONE      = 2’h0,

PV_THREE  = 2’h1,

PV_FIVE     = 2’h2,

PV_TEN      = 2’h3

} e_pixel;

e_pixel pixelValue;


Solution :

I have to cast the integer value 2 to e_pixel format before I can assign it to the enumeration variable. It’s called strong typing.

pixelValue = e_pixel’ (2);

but

pixelValue = PV_THREE;                        // Correct and valid

Debugging/Dumping Assertions in Verdi

Did you know ...

Debugging assertions can be painfully long and exhausting. Well, there’s an easier way to do that using Synopsys Verdi ( coz, I just found out how).

I’ll leave it upto you to find out where vericom is. It’s usually under springsoft-verdi folder in the installation directory.

vericom -sv +ignorefileext+vhd -assert svaext -useius -syntaxerrormax 2000 -top -f <fileList>

Make sure that it contains the code for assertions as well. Once it compiles, you’ll find a new folder “worklib++” in the current directory.

verdi -nologo -sv -lib work -vtop “<module_name>=<top_name>.<module_name>”

Verdi will launch, load an FSDB waveform dump, and go to

Tools > Property Tools > Statistics.

statistics
This will open up a window and show how many assertions passed/failed. Right click on one of the “Fails” and “Add to Details“. Open up the hierarchy and right click to see “Analyze Property“. Then Verdi will start analyzing the properties in the Analyzer window and you’ll get to see the values of local variables used in your assertions.

TIP : You can add the assertions to your waveform, right-click it and select “Show Driver/Load Signals > Driver Signals” and it will pull out all the signals that affect the value of the assertion. You can also middle click the assertion and pull it into the source tab and Verdi will find the assertion in the source code. You can also see the current values of the variables beside the code by enabling Source > Active Annotation and Source > Parameter Annotation.

To dump assertions in ncsim, use fsdbDumpSVA ().