Monday, September 6, 2010

Default seed of VCS can

In system verilog,if a packet class is created with rand items and every independent run with vcs generates the same values for rand items.

image

 

The above code having three 2-bit rand variables, when run with vcs command:

> vcs –sverilog –R test.sv

will output same value a=2, b=2, c=1 for all 10 iterations even when run again with the same above command. This is because, every vcs executes the test always with the default seed, which is equal to 1. And hence, randomize() function will always execute for constant seed (=1) in this process.

Utilizing the characteristics of rand type, the above code can be modified to dump different values of a, b, c in each iteration when run with the vcs command.

image

This will dump out unique values of a, b and c in each iteration.

The same can be run by changing RNG value for seeding from the command line using +ntb_random_seed. For running regression this is the best solution.

Friday, August 20, 2010

fork…join_none and for loop

An interesting case with fork…join_none block defined inside a for loop in system verilog is shown here as an example:

image

 

The intended result of this code is to display the iteration count value, i, from 0 to 3. That is, each call to system task, $display, will hold a unique value of i.

But the output of the above example is:

image

This can be explained as: Each iteration in the for loop initiates a parallel thread to display the value of variable i (iteration count). Because of join_none keyword, none of the threads (blocks) are waited for completion of their execution. So the immediately next statement after the for loop (zero time delay) is executed, which in this case is $display (“THE END”) system task and hence is the first line of output observed.

By the end of execution of for loop (zero time), the value of i is 4. This is the value that gets updated across all the threads (blocks) that has been initiated to display the value of i. Even before the threads begin to start executing the value of i has been changed to 4, which is what is observed in the output. This result implies that variable i is a static variable.

For this particular example replacing join_none by join statement will result into the expected output. That is, each parallel thread will display unique value of i and the output seen is i changing in consecutive order from 0 to 3.

In case join_none statement cannot be replaced because, say for example, of time consuming user defined task being called and the logic requires that no time is to be spent before executing the next statement following the for loop, then create an automatic variable inside a for loop and assign i to it before starting the fork…join_none block.

image

Here, keyword automatic can be ignored as well. Variable k is roughly similar to C automatic variable. Now, the lifetime of automatic variable k is the lifetime of each fork...join_none block. So each block will have a unique value of k, which doesn’t get changed even after completion of for loop. 

image

Wednesday, March 3, 2010

Part Select or Slice implementation in SV

To optimize the following system verilog code:

sample[0] = &dq[7:0];

sample[1] = &dq[15:8];

sample[2] = &dq[23:16];

sample[3] = &dq[31:24];

...

so on for 64-bit packed array dq. This was simplified by using for loop with system verilog slice or part select of packed arrays as:

for (int i=0,j=0; i<ST_W; i+=8, j++) begin //ST_W=DATA_WIDTH/16

sample[j] = &dq[i+:8];

end

The index i represents position of the slicing which is added to a constant 8 to determine the size of part select or slice. Thus, the code can be reused for any data width with reduced code density and easy readability.


Powered By Blogger