Warning: session_start(): Cannot send session cookie - headers already sent by (output started at /home2/aefody/public_html/specman-verification.com/scripts/sb_utility.php:873) in /home2/aefody/public_html/specman-verification.com/index.php on line 11

Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at /home2/aefody/public_html/specman-verification.com/scripts/sb_utility.php:873) in /home2/aefody/public_html/specman-verification.com/index.php on line 11

Warning: strpos(): needle is not a string or an integer in /home2/aefody/public_html/specman-verification.com/index.php on line 71
Tips for HVL and HDL users with special emphasis on Specman-e, SystemVerilog and Questa
Specman Verification
Verification engineer? Verifigen has the right project for you!
Square root in SystemVerilog 
Thursday, January 29, 2009, 12:21 AM - The verification hood

module x();

   real t=10.0;



   initial 

      // either...

     t = t**0.5; 

      // or... 

     t = $sqrt(t);       

endmodule


The first option, which doesn't use a system function call, is probably slightly more efficient...

see other arithmatic functions here


  |  permalink
Avoiding races between driver and monitor 
Thursday, December 25, 2008, 06:58 AM - Hardcore verification
According to the eRM and OVM monitors and drivers should always be completely separate. This approach was adopted mainly in order to facilitate reuse of block level agents in a top level testbench: at block level both driver and monitor are used, while at top level only the monitor is used. If the code for both is mixed, then you might run into some nasty surprises when you try to rerun your code at top level with the driver disabled. For example, you might suddenly discover that your monitor is not working properly when it is not you, but some HDL block, that is driving the signals.

Having separate monitor and driver means that they will also run in independent threads of execution, and this means races between the two might occur. A race is one of these bugs that can make you eat your nails to the bone and pull out all your body hair – it normally appears all of a sudden, just at the very moment when you think your code is stable and working great. The extremely simple example below shows an example of a race, and the relatively minor code modification that can make it show its ugly face:




// The driver drives the data signal at each positive clock edge

interface driver_if(input rst, input clk, output reg [7:0] data);



always @(posedge clk or negedge rst)

  if (!rst)

    data = 0;

  else

    data = data + 1;

   

endinterface



// The monitor samples the data signal at each positive clock edge

interface monitor_if(input clk, input reg [7:0] data);



always @(posedge clk)

  $display("data value from monitor at time %d is %d", $time(), data);



endinterface



// testbench generates clock and reset and does the connections

module tb;



   reg rst;   

   reg clk = 0;

   reg [7:0] data;



   initial

     begin

        rst = 0;

        #10;

        rst = 1;

     end

   

   initial

     forever

       begin

          #20;

          clk = !clk;

       end



   monitor_if monitor_if_i(clk,data);   

   driver_if driver_if_i(rst,clk,data);   



endmodule


output:


# data value from monitor at time 20 is 0
# data value from monitor at time 60 is 1
# data value from monitor at time 100 is 2
...


If you run the code above with Questa you will see that it always runs the monitor code first (simply place a breakpoint on both driver and monitor). This, however, is just a coincidence and not anything you can rely on. If you modify the code from:


<   monitor_if monitor_if_i(clk,data);   

<   driver_if driver_if_i(rst,clk,data); 



to:


>   driver_if driver_if_i(rst,clk,data);

>   monitor_if monitor_if_i(clk,data);  



Questa will run the driver code first, and suddenly you’ll see different results:


# data value from monitor at time 20 is 1
# data value from monitor at time 60 is 2
# data value from monitor at time 100 is 3


This can also happen because you have used a different compiler – the SV standard or the plain Verilog standard don’t say anything about the order in which pending threads should be run.

Solving such races in SV is relatively easy*. As any Verilog designer knows, in the case above all you have to do to solve the race is modify the assignments from “blocking” to “non blocking”. This will postpone the assignments to the end of the delta, so the monitor will never see the new value assigned by the driver, even if its thread is the last to run. Here's the original code with the required modification:




interface driver_if(input rst, input clk, output reg [7:0] data);



always @(posedge clk or negedge rst)

  if (!rst)

    data <= 0; // modified to non-blocking

  else

    data <= data + 1; // modified to non-blocking



   

endinterface



interface monitor_if(input clk, input reg [7:0] data);



always @(posedge clk)

  $display("data value from monitor at time %d is %d", $time(), data);



endinterface



module tb;



   reg rst;   

   reg clk = 0;

   reg [7:0] data;



   initial

     begin

        rst = 0;

        #10;

        rst = 1;

     end

   

   initial

     forever

       begin

          #20;

          clk = !clk;

       end



   monitor_if monitor_if_i(clk,data);   

   driver_if driver_if_i(rst,clk,data);   



endmodule



output (will be the same independent of instansiation order):


# data value from monitor at time 20 is 0
# data value from monitor at time 60 is 1
# data value from monitor at time 100 is 2
...


So, the bottom line of this entry is: When you’re writing a driver in SV always use “non blocking assignments”. And in a more general form: “always ask yourself how designers solve this problem and try to do the same”.

*In e this might be a little bit more complex because all e assignments are “blocking”, i.e. they are executed immediately. As soon as I have access to Specman license again I’ll try to put up an e example as well.

Update: Yaron Ilani has just reminded me that the same affect is achieved in e by setting the port attribute "verilog_delta_delay" to TRUE. This will make the port always sample the previous value instead of the current one, which means that any value driven by the driver in this delta, will not be visible to the monitor.

keep unit.port.verilog_delta_delay() == TRUE;

Thanks!

  |  permalink
A new Specman blog gives me a hard time  
Sunday, December 21, 2008, 07:00 AM - Hardcore verification
As you can expect, running a blog called specman-verification and working for Mentor puts you sometimes in uncomfortable positions. For example, assume Cadence puts up (at long last, if I may say), an official Specman blog. Should I then dedicate it an entry with a link, knowing that whoever follows it will end up at the competition home ground, or should I ignore it, thereby knowingly hiding highly relevant information from the readers of this blog, who after all, come here mainly for specman related stuff? After loosing sleep over this dilemma for about a week, my amazing diplomatic talent have finally found the golden way out, one that will let me keep both my objective reputation and my job: Cadence gets the link to the new blog (also in the verification links on the side). And Mentor gets a very big credit for being such a blogger-friendly, open company that never gives me any hard time with posts like this, even though I know some of the people up there are aware of what’s going on down here. I guess only the bottom line sales of Mentor and Cadence for this quarter, will tell who got the better deal here :-).

So I hope everybody’s happy now, and that the contents of the new blog will prove worthy of all this hustle I went through (at the moment it looks more like a very good tutorial for beginners, but hopefully it will evolve to treat some corner cases and heavy methodological issues as well). Good luck!

  |  permalink

Back Next