Re: Fwd: Verilog Races in Combinatorial Logic

From: Stuart Sutherland (stuart@sutherland-hdl.com)
Date: Thu Sep 21 2000 - 09:46:53 PDT


<x-html>

First, I'm proud to say that I explicitly teach students in my Verilog
course to NOT use the same variable for loop control in too parallel
loops. I teach them to declare a local variable within each
parallel procedure.
Second, Shalom's example helped jog my memory of a similar race condition
I ran into once, with Verilog-XL. I just quickly threw together an
example and ran in on Verilog-XL. The example is certainly not all
inclusive, but provides the potential of seeing:
- Interleaving in the same time step between two initial procedures
- Interleaving in the same time step between a procedure and a module
instance
- Interleaving in the same time step between a procedure and a continuous
assign
As you can see from the results which follow, interleaving does indeed
occur in Verilog-XL (no turbo switches set) between a for-loop and a
continuous assignment! I'm fairly certain that at least VCS will do
the same interleaving with this example, but I do not have access to VCS
or any other simulator at the moment.
Stu
Verilog code
------------
`timescale 1ns / 1ns
module test2 (i, j);
  input [31:0] i, j;
  
  always @(i or j)
    begin
      $display ("In %m: i=%0d
j=%0d", i, j);
    end
endmodule
module test1;
  integer i, j;
  wire [31:0] w;
  
  assign w = func1(i, j);
  
  test2 test2 (i, j);
  
  initial
    begin
      $display("\nLoop to increment
i");
      for (i=0; i<=3; i=i+1)
        begin
          j = i;
        end
      #1 $finish;
    end
  initial
    begin
      $display("\nLoop to decrement
i");
      for (i=7; i>=4; i=i-1)
        begin
          j = i;
        end
      #1 $finish;
    end
  function [31:0] func1;
    input [31:0] i, j;
    begin
      $display ("In %m: i=%0d
j=%0d", i, j);
      func1 = i;
    end
  endfunction
  
endmodule
---------------
Verilog-XL's output
-------------------
Loop to increment i
In test1.func1: i=0 j=x
In test1.func1: i=0 j=0
In test1.func1: i=1 j=0
In test1.func1: i=1 j=1
In test1.func1: i=2 j=1
In test1.func1: i=2 j=2
In test1.func1: i=3 j=2
In test1.func1: i=3 j=3
In test1.func1: i=4 j=3
Loop to decrement i
In test1.func1: i=7 j=3
In test1.func1: i=7 j=7
In test1.func1: i=6 j=7
In test1.func1: i=6 j=6
In test1.func1: i=5 j=6
In test1.func1: i=5 j=5
In test1.func1: i=4 j=5
In test1.func1: i=4 j=4
In test1.func1: i=3 j=4
In test1.test2: i=3 j=4
L36 "test.v": $finish at simulation time 1
At 04:44 AM 9/21/2000, Shalom Bresticker (r50386) wrote:
<blockquote type=cite cite>We must not limit ourselves to hardware
descriptions.
I like to use the following example (one of several which emphasize the
point):
initial begin
  for (i = 0; i < 100; i = i + 1) array1[i] = i ; // initialize
array1
initial begin
  for (i = 0; i < 527; i = i + 1) array2[i] = 2*i + 4 ; //
initialize array2
This is a very common programming practice.
"i" is used as a loop index, a general purpose variable.
The programmer will assume that one of the array initializations will be
performed,
then the other. It does not matter what order.
What is important is that the execution not be interleaved, because then
the value of "i"
will not be preserved within the loop.
We cannot declare such basic programming styles non-deterministic,
but that is what the standard indeed says today.
Shalom
  
"Joseph P. Skudlarek" wrote:
<blockquote type=cite cite>Hi, Steve. Good point, but I see another
side of things too.
I agree that reasoning is easier if we
        know that when x event control
"wakes up", y has value 1'b0
but that's not what hardware does, so that's not the meaning that
Verilog should have.
A real world example which shows this uncertain behavior is when using
Verilog to model at a higher level of abstraction. Let z be a
memory
location which is shared between two independent subsystems. Each
always block represents a subsystem. It is certainly possible for
the
execution history (where x/y/z is the after value) to be either
       
Fred
Ginger
x
y z
       
-------------------------------------------------
        z =
0
x0 y0 0
        x =
y
y0 y0 0
        y =
z
y0 0 0
                       
z = 1
y0 0 1
       
-------------------------------------------------
-or-
       
Fred
Ginger
x
y z
       
-------------------------------------------------
        z =
0
x0 y0 0
        x =
y
y0 y0 0
                       
z = 1
y0 y0 1
        y =
z
y0 1 1
       
-------------------------------------------------
Both are legal outcomes. In once case, y has the value 0; in the
other,
y has the value 1.
This situation occurs because z is shared between the two processes, and
the accesses can interleave. It's this interleaving that is an
essential aspect of what (concurrent) hardware does, and what Verilog
must model. It's why VHDL had to specify shared variable semantics.
It's the nature of the beast.
I still hold that the primary objective of the 1364 standard is to be a
clear, complete, and correct specification of a useful Verilog. It
needs to specify enough that an implementor could create a valid (and
useful) Verilog implementation just from the standard. It also
needs to
describe useful guaranteed behavior well enough that users can model
effectively.
I hope this helps. /Jskud</blockquote>

-- 

************************************************************************ Shalom Bresticker email: shalom@msil.sps.mot.com Motorola Semiconductor Israel, Ltd. Tel #: +972 9 9522268 P.O.B. 2208, Herzlia 46120, ISRAEL Fax #: +972 9 9522890 http://www.motorola-semi.co.il/ ************************************************************************ </blockquote> <div>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</div> <div>Stuart Sutherland Sutherland HDL Inc.</div> <div>stuart@sutherland-hdl.com 22805 SW 92nd Place</div> <div>phone: 503-692-0898 Tualatin, OR 97062</div> <div>www.sutherland-hdl.com</div> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

</x-html>



This archive was generated by hypermail 2.1.4 : Mon Jul 08 2002 - 12:54:14 PDT and
sponsored by Boyd Technology, Inc.