|
|
SVUG Tips & Tricks
|
|
Share your SystemVerilog Tips and Tricks!
To add new SystemVerilog Tips and Tricks, you will first need to login. Then, simply click on the "upload" button and fill out the submission form. You can also email it to us and we'll post your Tips and Tricks for you.
You do not need to login to view, vote or comment on posted Tips and Tricks. You only have to login to submit them.
Your SystemVerilog Tips and Tricks submission will be displayed following moderator approval.
 |
|
Be careful with wild inequalities
Author : Tom Symons
Date : Thu 12/06/2007 @ 04:16
|
|
|
Wild inequalities are a useful new feature, but they can sting if you are not careful.
read article
Consider this code:
if (A ==? B) ...
This compares 4-state vectors A and B such that any x's or z's in B (and only B) act as wildcards and will match anything in A. Very useful.
But beware what happens if A contains any x’s or z’s. In this case, the result of the comparison will be ‘x, which will cause the entire expression to be evaluated as true.
Instead, this should be coded as follows:
If ( ( A ==? B ) === 1’b1) …
|
|
|
|
|
 |
|
Converting Strings to Enums
Author : JL Gray
Date : Tue 11/06/2007 @ 06:52
|
|
|
Every once and awhile, I want to convert a string to an enumeration in SystemVerilog. Casting from strings to enums is not supported in SystemVerilog, but luckily, it is possible to implement a function to do the appropriate conversion using built in methods designed for iterating over the enum values.
read article
To read the entire article, download the article by clicking the Download link...
|
|
|
|
|
 |
|
Use the storage characteristics of a clocking block to simplify BFM logic
Author : Kelly Larson
Date : Wed 09/05/2007 @ 11:09
|
|
|
By making use of the storage within a clocking block, the main control loop of a BFM can be simplified to allow back-to-back transactions, without having to resort to other mechanisms to "peek" at future transactions.
read article
To read the entire article, download the article by clicking the Download link...
|
|
|
|
|
 |
|
Extend specific bus transaction classes from common generic transaction class
Author : Kelly Larson
Date : Wed 09/05/2007 @ 11:06
|
|
|
In today’s SOC designs it’s very common to have more than one type of bus co-existing in the same system. If the various busses are similar enough, it can very useful to have a common top-level generic bus transaction class which is shared between all of the specific busses.
read article
To read the entire article, download the article by clicking the Download link...
|
|
|
|
|
 |
|
when doing verify...
Author : Zoud
Date : Tue 09/04/2007 @ 11:01
|
|
|
when doing verify, :
read article
can’t use if( a < i < b), a, b are cont,
should be written as:
if( i <= a )
begin
end
else if(i < b )
begin
end
or a < i < b will not work correctly
|
|
|
|
|
 |
|
Showing the contents of a Queue in specific format
Author : Manmohan Singh
Date : Sat 08/25/2007 @ 01:12
|
|
|
Sometimes when the Queues are very big it become very difficult to see their entire content. Similar kind of a problem I faced when I need to look at a Queue of size bit [31:00] data[$]. The contents it was showing as a continuous stream of data like 111122223333444455556666777788889999aaaabbbbccccddddeeee. In this scenario its difficult to figure out the boundaries of each location.
read article
So I came to the solution through 2 ways. 2nd may be obvious but I was not aware of it. Thats why I am sharing this with the community.
module check;
class test;
bit [31:00] data[$];
task fill_q;
data.push_back(32'h11112222);
data.push_back(32'h33334444);
data.push_back(32'h55556666);
data.push_back(32'h77778888);
data.push_back(32'h9999aaaa);
data.push_back(32'hbbbbcccc);
data.push_back(32'hddddeeee);
endtask:fill_q
endclass:test
initial
begin//{
test T = new;
T.fill_q();
$display("data=%h_%h_%h_%h_%h_%h_%h\n",T.data[0],T.data[1],T.data[2],T.data[3],T.data[4],T.data[5],T.data[6]);// Way 1
$display("data = %h",T.data);// Way 2
end//}
endmodule:check
way 1 solution:
data = 11112222_33334444_55556666_77778888_9999aaaa_bbbbcccc_ddddeeee
way2 solution:
data = 11112222 33334444 55556666 77778888 9999aaaa bbbbcccc ddddeeee
|
|
|
|
|
 |
|
Random Stability for Debug
Author : Tom Symons
Date : Wed 08/22/2007 @ 07:09
|
|
|
Consider the case where you have a failing sim that you are trying to debug. Let’s say you wish to display a memory structure or other component that requires a class object be constructed in order to utilize its handy display routines. But when you re-run the sim with this new display routine call, your sim surprisingly stops failing or fails in a different way. What do you do ?
read article
This condition is not a bug with your simulator, but rather the result of how random stability is managed in SystemVerilog. It occurs because the seed value used for the random number generator (RNG) of each newly created object is taken from the RNG of the parent thread, not from the parent object. So the creation of a new object deep down one class hierarchy can reach all the way back to the parent thread and disturb the random sequence of everything subsequently seeded by the thread. This is how your failing testcase can change unexpectedly when you add a display call that constructs a class object.
One solution is to save and restore the state of the thread’s RNG, so that the creation of an object doesn’t change its state. This can be done by creating a static function in the utility object (the one being added to the sim) which will construct the object without changing the thread’s RNG. For example:
static function foo_c new_safe();
process p = process::self();
string rng = p.get_randstate();
foo_c foo = new();
p.set_randstate(rng);
return foo;
endfunction
Then create the object as follows:
foo_c my_foo = foo_c::new_safe();
rather than calling ‘new’ directly.
Any utility object that may be added to a sim to track down a bug should be constructed in this manner.
|
|
|
|
|
 |
|
Using Interface
Author : Vivek Avachat
Date : Tue 08/21/2007 @ 11:36
|
|
|
Using interface modules in System Verilog results into seamless port mapping of various submodules to be integrated at all abstraction levels in integration.
read article
Writing Interfaces is an unique feature of System verilog. Interfaces can be written as a module separately.
Instance can be taken inside in module which use those ports declared inside it.
This structure reduces redundancy while implementation and results into.
1. Huge reduction of efforts.
2. Risk of errors.
Example of using interface is as given below.
interface fifo_ports (
input wire clk ,
input wire rst ,
input wire full ,
input wire empty ,
output logic wr_cs ,
output logic rd_cs ,
output logic rd_en ,
output logic wr_en ,
output logic [7:0] data_in ,
input wire [7:0] data_out
);
endinterface : fifo_ports
module fifo (fifo_ports A); // Where A is an instance of fifo i/o ports.
An interface can have parameters, constants,variables, functions and tasks. One can also write tasks inside interface; later can be called from module to send / receive packets between two modules sharing signls from same interface.
interface i2;
wire a, b, c, d;
modport
master (input a, b, output c, d);
modport slave (output a, b, input c, d);
endinterface
Where modports defines about direction of signals w.r.t. each other.
|
|
|
|
|
 |
|
Interface default values
Author : Stefan Sandtrom
Date : Tue 08/21/2007 @ 03:44
|
|
When simulating some subpart of a design, or an incomplete design, there are sometimes unused interface ports. The signals in these interface ports may have to be set to some default values for the design to work as expected. It may be a tedious task to set all signals in these ports to proper values. Especially if there are many ports, and/or many control signals in the ports.
read article
By adding tasks to the interface definitions that set all signals to proper default values this can be made much simpler. E.g:
interface foo;
logic a, b, c, d, e, f, g, h;
modport master(....); modport slave(.....);
task set_default; a = '1; b = '0; c = '0; d = '1; e = '0; ... endtask
endinterface
This way, a call to set_default() for each instance of foo is sufficient to set all signals to their default values (instead of setting each signal individually for each instance).
A real life example of this that I've used is for a RAM BIST interface. We had a module with maybe 30 BIST interface ports, and during simulation the BISTs in the design should be turned off. This required 6 signals in each BIST interface port to be set. By adding to the RAM BIST interface a task that set those signals, and an `ifdefed initial block that called that task, all I needed to do to set the default values for all 30 ports was adding a +define option when building the simulator. I looked something like this:
interface bistif; logic drt_bist; logic bist_clk; logic bist_clk_en; logic bist_test; logic scantest; logic run_bist; logic [1:0] bist_out;
...
task set_default; bist_clk = 0; drt_bist = 0; bist_clk_en = 0; bist_test = 0; scantest = 0; run_bist = 0; endtask
`ifdef BIST_OFF initial set_default; `endif
endinterface
|
|
|
|
|
 |
|
For comparing 2 signal strengths...
Author : Divya
Date : Thu 08/16/2007 @ 11:57
|
|
|
1. For comparing 2 signal strengths we can use $swrite and %v. For ex:
string str_dp, str_dm ;
$swrite(str_dp,"%v",dp);
$swrite(str_dm,"%v"dm);
read article
1. For comparing 2 signal strengths we can use $swrite and %v. For ex:
string str_dp, str_dm ;
$swrite(str_dp,"%v",dp);
$swrite(str_dm,"%v"dm);
Here dp and dm signal strengths are written into str_dp and str_dm respectively. Now u can compare 2 strings.
2. Two constraints blocks can be made to execute in order by using solve before. For ex:
constraint config_addr
{
addr == cfg.device_address;
solve error_injected before addr ;
}
constraint default_error_injected
{
error_injected == 32'b0;
}
Here addr constraint will be solved after error_injected constraint is solved
|
|
|
|
|
|
|
|
|

|
|