Are begin/end blocks atomic? 
Author Message
 Are begin/end blocks atomic?

Consider the following Verilog fragment:

Module example(in1, out1);

input in1;
output out1;

wire wire1;
reg  reg1;

assign wire1 = reg1;


  begin
  reg1 = in1;
  out1 = wire1;
  end

endmodule

My question is whether the above module is valid (and produces a
deterministic reproduceable result and whether the behavior is
specified in the standard).  Moreover, I am interested in whether the
code between the begin and end execute atomicly or non-atomicly.

If the begin end block executes atomicly, the value in in1 is copied
to reg1 and the value in wire1 is then copied to out1.  The value from
reg1 is not copied to wire1 until after wire1 is copied to out1.  An
atomic interpretation effectively turns the two blocking assigments
into a wierd fake non-blocking assignment, once the code has executed
once, out1 always gets the previous value of in1.

If the begin end block executes non-atomicly, the value in in1 is
copied to reg1 and then the continuous assignment copies that value to
wire1 and after that the same value is copied from wire1 to out1.  A
non-atomic interpretation interleaves the code fragments and acts as
if a sequence of three blocking assignments were used, out1 always
gets the current value of in1.

If the result is non-deterministic (or not guaranteed by the
standard), either situation could occur, or worse some of the bits
could get copied and some not, or it could get copied sometimes and
not others, etc.

Note, that if I make the first assignment in the begin end a
non-blocking assignment, then I assume the "atomic" interpretation is
effectively enforced, since the update of reg1 is scheduled to happen
in the future (and thus the transfer from reg1 to wire1 must also
happen in the future).

// nba forces atomic interpretation

  begin
  reg1 <= in1;
  out1 = wire1; // always gets wire1 before reg1 gets in1.
  end

Conversely, if a #0 delay is inserted before the 2nd statement, the
"non-atomic" interpretation is forced, since the read of "wire1" is
delayed and the transfer of reg1 to wire1 is not.

// delay forces non-atomic interpretation

  begin
  reg1 <= in1;
  #0 out1 = wire1; // always gets wire1 after reg1 gets in1 and wire1 gets reg1.
  end

-Chris

*****************************************************************************

Compiler Resources, Inc.       Web Site   :   http://www.*-*-*.com/ ~compres  
3 Proctor Street               voice      :  (508) 435-5016
Hopkinton, MA  01748  USA      fax        :  (508) 435-4847  (24 hours)
------------------------------------------------------------------------------



Wed, 03 Sep 2003 13:06:47 GMT  
 Are begin/end blocks atomic?

Quote:

>Consider the following Verilog fragment:

>Module example(in1, out1);

>input in1;
>output out1;

>wire wire1;
>reg  reg1;

>assign wire1 = reg1;


>  begin
>  reg1 = in1;
>  out1 = wire1;
>  end

>endmodule

>My question is whether the above module is valid (and produces a
>deterministic reproduceable result and whether the behavior is
>specified in the standard).  Moreover, I am interested in whether the
>code between the begin and end execute atomicly or non-atomicly.

No the code is not valid, the procedural assignment "out1 = wire1;"
is illegal as out1 (a wire) cannot be driven in a procedural assignment.
The rest of my answer assumes out1 is a reg.

Quote:
>If the begin end block executes atomicly, the value in in1 is copied
>to reg1 and the value in wire1 is then copied to out1.  The value from
>reg1 is not copied to wire1 until after wire1 is copied to out1.  An
>atomic interpretation effectively turns the two blocking assigments
>into a wierd fake non-blocking assignment, once the code has executed
>once, out1 always gets the previous value of in1.

First the straight answer:
According to section 5.4.1(1), begin-end blocks are not atomic.
That means, code from active processes can be interleaved.

Based on section 5.6, the blocking assignment "reg1 = in1;" (2)
causes an active assignment to be scheduled for reg1.
At this point either the continuous assignment  "wire1 = reg1" (1)
or the blocking assignment "out1 = wire1" (3) may be evaluated.

Quote:

> [snipped]

>// nba forces atomic interpretation

>  begin
>  reg1 <= in1;
>  out1 = wire1; // always gets wire1 before reg1 gets in1.
>  end

Yes, the nba in this case forces atomic interpretation. This is
because the non-blocking update is not performed until all
the active events are processed. So, the continuous assignment (1)
which will be triggered after the non-blocking update event
will be evaluated after assignment (3).

Quote:
>Conversely, if a #0 delay is inserted before the 2nd statement, the
>"non-atomic" interpretation is forced, since the read of "wire1" is
>delayed and the transfer of reg1 to wire1 is not.

>// delay forces non-atomic interpretation

>  begin
>  reg1 <= in1;
>  #0 out1 = wire1; // always gets wire1 after reg1 gets in1 and wire1 gets
reg1.
>  end

No, since the #0, puts an inactive event (for the current time) on the queue
which should be retrieved before the non-blocking update event from
assignment 1 (see the psuedo-code in section 5.4).

The inactive event will cause the evaluation of assignment 3. After which
the non-blocking update will put an evaluation event for assignment 1.

Your guess would have been correct if you had used a blocking assignment
for assignment 2. This would have put an active event in the queue for the
current time to update reg1. When this event is retrieved the continuous
assignment will be evealuated (prior to assignment 3 which is still waiting
for the inactive events to be turned active).

Please note that not all simulators adhere to the specification in Chapter
5,
so what I have said may be incorrect for your simulator.

Quote:
>-Chris

Regards,
Sudhir


Thu, 04 Sep 2003 02:19:21 GMT  
 Are begin/end blocks atomic?

Quote:

> Consider the following Verilog fragment:

> Module example(in1, out1);

> input in1;
> output out1;

Note should add 'reg out1;' here

Quote:

> wire wire1;
> reg  reg1;

> assign wire1 = reg1;


>   begin
>   reg1 = in1;
>   out1 = wire1;
>   end

> endmodule

> My question is whether the above module is valid (and produces a
> deterministic reproduceable result and whether the behavior is
> specified in the standard).  Moreover, I am interested in whether the
> code between the begin and end execute atomicly or non-atomicly.

The simple answer is that it's not defined whether you can sample wire1
immediately after you write reg1 - some simulators will perform the assign
in-line, others wont. The spec is very carefull NOT to specify stuff like
this except in certain cases in and around non-blocking assignments

Quote:
> Note, that if I make the first assignment in the begin end a
> non-blocking assignment, then I assume the "atomic" interpretation is
> effectively enforced, since the update of reg1 is scheduled to happen
> in the future (and thus the transfer from reg1 to wire1 must also
> happen in the future).

> // nba forces atomic interpretation

>  begin
>  reg1 <= in1;
>  out1 = wire1; // always gets wire1 before reg1 gets in1.
>  end

yes this is defined and portable

Quote:
> Conversely, if a #0 delay is inserted before the 2nd statement, the
> "non-atomic" interpretation is forced, since the read of "wire1" is
> delayed and the transfer of reg1 to wire1 is not.

> // delay forces non-atomic interpretation

>  begin
>  reg1 <= in1;

>  #0 out1 = wire1; // always gets wire1 after reg1 gets in1 and wire1 gets
reg1.
>  end

yup - but your synthesis tool may complain

The correct, safe way to do what you want is to either sample reg1 rather
than wire1:


                reg1 = in1;
                out1 = reg1;
        end

or to create 2 seperate always blocks:


                reg1 = in1;


                out1 = wire1;
        (or even simply 'assign out1 = wire1;')

this last better addresses the problem you are trying to deal with,
especially if wire1 happens to have multiple drivers

        Paul Campbell



Wed, 03 Sep 2003 22:02:13 GMT  
 Are begin/end blocks atomic?
Thank you, Paul and Sudhir.  This is exactly the kind of information I
was looking for.  I will go reread section 5.4 et. al. and perhaps see
how the wording has changed in the new 2000 spec.

BTW, I apologize for leaving out the "reg out1;" declaration.  Our
tool infers which items should be wires and which should be regs.

More importantly, in the second example, I meant for the code to use
two blocking assignments in the always block.  Does that make the code
correct?  It's not entirely relevant as our tool does not allow
designers to put delays in their code.  However, I do like to know
which parts of the language I do and do not understand yet.

Quote:
>// delay forces non-atomic interpretation

>  begin
>  reg1 = in1;
>  #0 out1 = wire1; // always gets wire1 after reg1 gets in1 and wire1 gets
reg1.
>  end

My situation is that I am not a chip designer, just a poor software
flunky trying to write part of a tool to help the designers in my
group.  The tool intentionally does not support the entire Verilog
language, as we only want the designers using Verilog to create
combinatorial parts of their designs.  The tool has a schematic
capture part and all state elements must be drawn graphically.

Since the designers know that, they don't even try.  In fact, the
designers use the Verilog code in a very stylized fashion.  However,
the designers, being human, make mistakes and/or sometimes write
things that are perfectly valid, but outside the ability of our tool
to figure out.  The original example I showed was exactly such a case.

The real fragment is somewhat more complicated with the continuous
assignment taking an expression.  My problem is to figure out whether
to simply give an error or whether to try to figure out where the
continous assignment could be recoded as a blocking assignment in the
always block (changing wire1 to a reg, of course).

Knowing that the standard does not *guarantee* non-atomic operation
and could schedule either operation helps me to justify simply putting
out an error.  The worst case would be for the designer to use the
code with a simulator that gave one interpretation and a synthesis
tool that used a different one.  The simulator would consistently show
their code operating one way, while the actual chip acted another.
(One of my goals is to keep the chip designers out of trouble, by
making the Verilog that the tool supports as deterministic as
possible.)

-Chris

*****************************************************************************

Compiler Resources, Inc.       Web Site   :  http://world.std.com/~compres  
3 Proctor Street               voice      :  (508) 435-5016
Hopkinton, MA  01748  USA      fax        :  (508) 435-4847  (24 hours)
------------------------------------------------------------------------------



Fri, 05 Sep 2003 08:19:29 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. BLOCK/END BLOCK F2008

2. Cals Begin and End Balance

3. prob. with BEGIN/END

4. Smalltalk on the small end (was: Advice requested: GUI project beginning)

5. /BEGIN/ .. /END/ file reading

6. How to write filesearch with begin-pattern till end-pattern

7. begin/end doesn't behave as expected

8. Braces and begin/end

9. Suggestion for addition to Begin/End syntax

10. Beginning of End of Ada Mandate

11. remove begin and end tags and its content in between

12. Is Perlish BEGIN / END possible?

 

 
Powered by phpBB® Forum Software