Verilog error? (non blocking assignments + assign statement) 
Author Message
 Verilog error? (non blocking assignments + assign statement)

Roberto,

        I ran VCS5.2 on your code and the results do not seem to have the
problem. I am attaching the output of VCS.

        Regards,

                -Ajay

Chronologic VCS simulator copyright 1991-2000
Contains Synopsys proprietary information.
Compiler version 5.2R1; Runtime version 5.2R1;  Apr 12 15:54 2000

# Reset       200
# LV1 command:      1600
                2080 LV1 11101
# LV1_1 command (bit flip 11100):      2500
                2980 LV1_mod 11100
# LV1 command:      3400
                3880 LV1 11101
# BCR command:      4300
                4780 CMD 10011
                5180 BCR 0001
# ECR command:      5600
                6080 CMD 10011
                6480 ECR 0010
# CAL command:      6900
                7380 CMD 10011
                7780 CAL 0100
# LV1 command:      8200
                8680 LV1 11101
# LV1 command:      8700
                9180 LV1 11101
$finish at simulation time             10400000
           V C S   S i m u l a t i o n   R e p o r t
Time: 10400000 ps
CPU Time:   0.020 seconds; Data structure size: 0.0Mb
Wed Apr 12 15:54:53 2000

Quote:

> Hi to all,
>         i am facing a "strange" problem that is driving me mad...
> I do not know if it is a verilog "bug" or if i am somehow wrong!
> I use Cadence Verilog-XL and have no other simulator to test my code with.

> Any help would GREATLY be appreciated...
> Even "simply" running the code through another simulator would suffice!
> Please reply also to my E-Mail as i do not usually read this newsgroup!
> The address is at the end of the mail...

> Here is my problem (i include an example of the code...)

> I am developing an ASIC with a state machine which essentially decodes a serial
> stream. Therefore i have a shift register (5 bit wide) which can be partially
> cleared (4 msb only) while data shifts in.
> Then i have a state machine (many in reality, but for this example only one)
> which acts differently if different bit patterns are seen in the shift
> register. The state machine is designed in such a way that all state and
> registered outputs are triggered by the clock while all the asyncronous part is
> triggered by the occurrence of a signal change in the sensitivity list.
> In the asynchronous part there are two case statements which depend on the
> value of the shift register. All case blocks have a default: statement.
> What happens is the following: in state S0 i check the shift register against
> three possible 5bit patterns and if one is found (`CMD) i jump to state S3 and
> clear the shift register.
> In state S6 (which occours some clock cycles later) i check again the shift
> register but this time only the 4 least significant bits with another case
> statement and what happens is that AT THE SAME TIME 2 different case conditions
> are met!!! For example it happens that both BCR_logic and ECR_logic signals are
> set to 1 at the same time even if they are in two different branches of the
> case!!!!
> In order to verify this i provided a "small" example which reproduces the "bug"
> It includes a small test_bench and prints out the time and the values of the
> shift register each time a case branch is entered...
> If you run the example you will see (or at least i see) the following output:

> # ECR command:      5600
>                 6080 CMD 10011
>                 6480 BCR 0001    <----
>                 6480 ECR 0010    <----

> and you can see that at time 6480 both BCR and ECR branches are reached and the
> shift register seems to contain at the same time two different values: 0001 and
> 0010!

> I debugged the thing a little bit and found that the problem MAY be with the
> following statement:
> Line 292:  shift_reg_rst_logic <= 1;

> In fact the problem disappears if i replace the <= with <

> This signal is used to clear the 4 most significant bits of the shift register
> each time i match a pbit pattern. (i have to clear the shift register and
> cannot do without)
> This signal is not registered and is assigned to shift_reg_rst at line 229.
> (in real life shift_reg_rst is the logical or of many signals, one of them
> being shift_reg_rst_logic). It is then used to clear the shif register.

> Another way of getting rid of the problem is to add a #1 at the beginning of
> the asynchronous part of the state machine but i do not like it as i suspect
> mismatches with the synthesized design and i'd really like to understand where
> i am wrong...

> The example below is the smallest piece of my code i could make in order to
> reproduce the problem, but unfortunately solution #1 (replace <= with <) does
> not solve the problem in the whole code i am working on...

> There is probably something unclear with blocking vs nonblocking assignments,
> but i thought one could use non blocking assignments without any particular
> attention because (so i understand them) all events are scheduled at the end of
> the current simulation time and then assigned regardless of the order of
> occurrence. Here it seems that the state machine is triggered twice, once
> before and once after shifting the values in the shift register but this
> happens at the same time!!! (probably current_time and current_time + delta
> which are treated as the same time by the compiler).

> The code attached to the email contains everithing to be simulated stand
> alone, and also the output i get on my machine.

> Many many thanks in advance to all who take their time to look into the problem
> i am facing, and please remember to also send a copy of the response to my
> email!

> Ciao,
>         Roberto

> --

> Phone:  +39 10 353-6301                                 Via Dodecaneso, 33
> Fax:    +39 10 353-6319                                 I-16146 GENOVA

>   ------------------------------------------------------------------------
>                  Name: error.v
>    error.v       Type: Plain Text (TEXT/PLAIN)
>              Encoding: BASE64
>           Description: Verilog code reproducing the error

>                           Name: error_output.txt
>    error_output.txt       Type: Plain Text (TEXT/PLAIN)
>                       Encoding: BASE64
>                    Description: Output of verilog-xl by Cadence on the test code

--
Ajay Singh                                 Phone:(650) 584-5832
Synopsys  Inc                              Fax:  (650) 584-4555


Mountain View,CA 94043-4033                     1-800-VERILOG


Sun, 29 Sep 2002 03:00:00 GMT  
 Verilog error? (non blocking assignments + assign statement)

Quote:

> Hi to all,
> If you run the example you will see (or at least i see) the following output:

> # ECR command:      5600
>                 6080 CMD 10011
>                 6480 BCR 0001    <----
>                 6480 ECR 0010    <----

> and you can see that at time 6480 both BCR and ECR branches are reached and the
> shift register seems to contain at the same time two different values: 0001 and
> 0010!

in short this is normal and to be expected:

what's happening here is that you have an always statement
conditioned by two variables:


what happens if fsm_status and shift_reg change at the same clock edge
is undefined and may be simulator specific - while you think of them both
changing in the same instant inside the simulator they do change
sequentially - whether the always statement gets woken once after they've
both changed or twice as fsm_status changes and then again after
shift_reg changes is undefined and different simulators (or even
the same simulator under slightly subtly different curcumstances) will
do different things.

In the real world logic works this way too - depending on clock skew
and a host of different things two flops' outputs may change at slightly
different timeds - and if they both feed some combinatorial logic the output
may glitch just like your simulation does.

If you're using this combinatorial signal as an asynchronous reset
this would be a bad but you're not you're sampling it synchronously
with a clock so it shouldn't be a problem

My quick survey shows that 1 out of the 3 simulators I tested
behave this way for this particular verilog source

Quote:
> I debugged the thing a little bit and found that the problem MAY be with the
> following statement:
> Line 292:  shift_reg_rst_logic <= 1;

> In fact the problem disappears if i replace the <= with <

ummm - well doing that turns it into an expression that's a no-op and
has no effect - probably not what you had in mind

I'm guessing that you really have another problem you're chasing here and
that this is just a symptom of simulator non-determinism you ran across
during debugging (as a rule $display statements put in combinatorial
always statements may show up many times within a time period you
should ignore all but the last one while debugging).

Also you do seem to be overdoing the <= assigns a bit mutch - they do
tend to cause this sort of simulator ordering confusion to happen more
often - a good rule of thumb is:

        - use '=' for combinatorial assignments - reg's you think of
                as really being wires in your final design - things that are
                assigned in always statements triggered off of other
                things changing, not off of clocks

        - use '<=' (or '= #1' this is another 'religous war') for reg's
                you think of as flops - in always statements triggered from
                the edges of clocks

I hope this helps some

        Paul Campbell



Sun, 29 Sep 2002 03:00:00 GMT  
 Verilog error? (non blocking assignments + assign statement)

Quote:


> > Hi to all,
> > If you run the example you will see (or at least i see) the following output:

> > # ECR command:      5600
> >                 6080 CMD 10011
> >                 6480 BCR 0001    <----
> >                 6480 ECR 0010    <----

> > and you can see that at time 6480 both BCR and ECR branches are reached and the
> > shift register seems to contain at the same time two different values: 0001 and
> > 0010!

> in short this is normal and to be expected:

> what's happening here is that you have an always statement
> conditioned by two variables:


> what happens if fsm_status and shift_reg change at the same clock edge
> is undefined and may be simulator specific - while you think of them both
> changing in the same instant inside the simulator they do change
> sequentially - whether the always statement gets woken once after they've
> both changed or twice as fsm_status changes and then again after
> shift_reg changes is undefined and different simulators (or even
> the same simulator under slightly subtly different curcumstances) will
> do different things.

> In the real world logic works this way too - depending on clock skew
> and a host of different things two flops' outputs may change at slightly
> different timeds - and if they both feed some combinatorial logic the output
> may glitch just like your simulation does.

> If you're using this combinatorial signal as an asynchronous reset
> this would be a bad but you're not you're sampling it synchronously
> with a clock so it shouldn't be a problem

I understand this issue but i disagree with the fact that the result is
unprerdictable!!!
Both in simulation and in Real world, being the block combinatorial and the
simulation not "time oriented" but "event oriented" meaning that only clocks
are meaningful in this case, so glitches should definitly NOT be an issue, (in
fact there is absolutely no timing in the design with the exception of the
clock), so the result of these statements should be always the same and should
not depend on the order of the execution of the operands as non blocking
assignments are thought to be!
It is definitively not possible that a case statement is accessed twice in the
same timeframe it simply makes no sense...
I really think that if things are in this way one should really think to drop
verilog at all for this kind of simulations, if such HUGE ambiguities are
present in the language...
As a counter example if you take VHDL this could never happen due to the fact
that this statements are all done using <= and are therefore concurrent (at
least for my very poor notion of VHDL).
Another example is that if you synthesize the design you do not get this
behaviour and the "correct" behaviour is realized.
For my understanding this is the only reason for introducing non bloking
assignments instead of blocking ones, and it is a reason for using ALWAYS this
type of assignment exactly for getting rid of this problems...

Quote:
> My quick survey shows that 1 out of the 3 simulators I tested
> behave this way for this particular verilog source

In fact i was told that Synpsys VCS is behaving correctly!

Quote:

> I'm guessing that you really have another problem you're chasing here and
> that this is just a symptom of simulator non-determinism you ran across
> during debugging (as a rule $display statements put in combinatorial
> always statements may show up many times within a time period you
> should ignore all but the last one while debugging).

Also this is not correct for my understanding... If the $display is in two
different case branches or in twho different if, else if statements it should
definitely show up ONLY once!!!

Quote:
> Also you do seem to be overdoing the <= assigns a bit mutch - they do
> tend to cause this sort of simulator ordering confusion to happen more
> often

Again, what is the use of non blocking assignments if you should use them only
a certain (not exactly specified) amount of times but absolutely not more
otherwise your simulator may give wrong results? I found nothing of this both
in the Veriolog-XL simulator and in the Veriolg language definition...

Quote:

> I hope this helps some

>    Paul Campbell


Thank you for the response and for having looked into my problem...

Ciao,

                Roberto

P.S.: Regarding the religious war about <= versus <= #1, i think that the first
form is the correct one if you are doing a simulation without real timing
information (no real components and only clocks). Why should one artificially
introduce timing information once you know that synthesys drops this
information instantly??? Maybe this applies only for a subset of Verilog, i.e.
Verilog for Synthesys, but who would ever program Verilog not having in mind a
synthesys tool, or at least some electronics? I agree that this could be a
valid point if you are using real components with correct timing information,
but this is a different story...

--

Phone:  +39 10 353-6301                                 Via Dodecaneso, 33
Fax:    +39 10 353-6319                                 I-16146 GENOVA



Mon, 30 Sep 2002 03:00:00 GMT  
 Verilog error? (non blocking assignments + assign statement)

Quote:

> I understand this issue but i disagree with the fact that the result is
> unprerdictable!!!
> Both in simulation and in Real world, being the block combinatorial and the
> simulation not "time oriented" but "event oriented" meaning that only clocks
> are meaningful in this case, so glitches should definitly NOT be an issue, (in
> fact there is absolutely no timing in the design with the exception of the
> clock), so the result of these statements should be always the same and should
> not depend on the order of the execution of the operands as non blocking
> assignments are thought to be!
> It is definitively not possible that a case statement is accessed twice in the
> same timeframe it simply makes no sense...

The essence of your verilog looks something like this:


                s <= ....    (this is in another block)
        assign  shift_reg = s;  (this assign is implicit when you pass
                                the result to the other block thru a wire)


                fsm_status <= ....


        case (fsm_status)

                ......

                case (shift_reg)

                A:
                B:

The ordering of the updates of s and fsm_status are undefined, because
the ordering of the always blocks in which they are updated is undefined
and verilog only makes sure of the ordering of these assignments if they
are executed sequentially in the same block.

After the updates are complete there will be 2 events triggered by the change of
the variables - the assign and the last always statement because fsm_status
changed - assume that the always statement got queued first - it gets executed
but seems the old value of shift_reg because the assign hasn't been executed yet,
next the assign gets executed - as a result shift_reg changes which in turn causes
the the last always statement to be triggered again and you go thru it a second time.
That's why what you are seeing is happening.

Again real-world logic synthesised from your design COULD glitch the same way (if
for example there was a similar delay in the wire coming out of 's' to the combinatorial
logic that the last always statement represents - but like the verilog it doesn't
matter provided you meet setup on the flops in the following clock

        Paul



Mon, 30 Sep 2002 03:00:00 GMT  
 Verilog error? (non blocking assignments + assign statement)

Quote:



> > > Hi to all,
> > > If you run the example you will see (or at least i see) the following output:

> > > # ECR command:      5600
> > >                 6080 CMD 10011
> > >                 6480 BCR 0001    <----
> > >                 6480 ECR 0010    <----

> > > and you can see that at time 6480 both BCR and ECR branches are reached and the
> > > shift register seems to contain at the same time two different values: 0001 and
> > > 0010!

> > in short this is normal and to be expected:

> > what's happening here is that you have an always statement
> > conditioned by two variables:


> > what happens if fsm_status and shift_reg change at the same clock edge
> > is undefined and may be simulator specific - while you think of them both
> > changing in the same instant inside the simulator they do change
> > sequentially - whether the always statement gets woken once after they've
> > both changed or twice as fsm_status changes and then again after
> > shift_reg changes is undefined and different simulators (or even
> > the same simulator under slightly subtly different curcumstances) will
> > do different things.

> > In the real world logic works this way too - depending on clock skew
> > and a host of different things two flops' outputs may change at slightly
> > different timeds - and if they both feed some combinatorial logic the output
> > may glitch just like your simulation does.

> > If you're using this combinatorial signal as an asynchronous reset
> > this would be a bad but you're not you're sampling it synchronously
> > with a clock so it shouldn't be a problem

> I understand this issue but i disagree with the fact that the result is
> unprerdictable!!!
> Both in simulation and in Real world, being the block combinatorial and the
> simulation not "time oriented" but "event oriented" meaning that only clocks
> are meaningful in this case, so glitches should definitly NOT be an issue, (in
> fact there is absolutely no timing in the design with the exception of the
> clock), so the result of these statements should be always the same and should
> not depend on the order of the execution of the operands as non blocking
> assignments are thought to be!
> It is definitively not possible that a case statement is accessed twice in the
> same timeframe it simply makes no sense...
> I really think that if things are in this way one should really think to drop
> verilog at all for this kind of simulations, if such HUGE ambiguities are
> present in the language...
> As a counter example if you take VHDL this could never happen due to the fact
> that this statements are all done using <= and are therefore concurrent (at
> least for my very poor notion of VHDL).
> Another example is that if you synthesize the design you do not get this
> behaviour and the "correct" behaviour is realized.
> For my understanding this is the only reason for introducing non bloking
> assignments instead of blocking ones, and it is a reason for using ALWAYS this
> type of assignment exactly for getting rid of this problems...

Even for non-blocking assignments, you have to know how to use them.
Non-blocking assignments are not panaceas.
It's almost as easy to write bad code with them as with blocking assignments.

- Show quoted text -

Quote:

> > My quick survey shows that 1 out of the 3 simulators I tested
> > behave this way for this particular verilog source

> In fact i was told that Synpsys VCS is behaving correctly!

> > I'm guessing that you really have another problem you're chasing here and
> > that this is just a symptom of simulator non-determinism you ran across
> > during debugging (as a rule $display statements put in combinatorial
> > always statements may show up many times within a time period you
> > should ignore all but the last one while debugging).

> Also this is not correct for my understanding... If the $display is in two
> different case branches or in twho different if, else if statements it should
> definitely show up ONLY once!!!

> > Also you do seem to be overdoing the <= assigns a bit mutch - they do
> > tend to cause this sort of simulator ordering confusion to happen more
> > often

> Again, what is the use of non blocking assignments if you should use them only
> a certain (not exactly specified) amount of times but absolutely not more
> otherwise your simulator may give wrong results? I found nothing of this both
> in the Veriolog-XL simulator and in the Veriolg language definition...

That's not what he said.
Again, he meant there are places where non-blocking assignments should not be used.

- Show quoted text -

Quote:

> > I hope this helps some

> >       Paul Campbell

> Thank you for the response and for having looked into my problem...

> Ciao,

>                 Roberto

> P.S.: Regarding the religious war about <= versus <= #1, i think that the first
> form is the correct one if you are doing a simulation without real timing
> information (no real components and only clocks). Why should one artificially
> introduce timing information once you know that synthesys drops this
> information instantly??? Maybe this applies only for a subset of Verilog, i.e.
> Verilog for Synthesys, but who would ever program Verilog not having in mind a
> synthesys tool, or at least some electronics? I agree that this could be a
> valid point if you are using real components with correct timing information,
> but this is a different story...

> --

> Phone:  +39 10 353-6301                                 Via Dodecaneso, 33
> Fax:    +39 10 353-6319                                 I-16146 GENOVA

--

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

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/
************************************************************************



Thu, 03 Oct 2002 03:00:00 GMT  
 Verilog error? (non blocking assignments + assign statement)

Quote:


> > Again, what is the use of non blocking assignments if you should use them only
> > a certain (not exactly specified) amount of times but absolutely not more
> > otherwise your simulator may give wrong results? I found nothing of this both
> > in the Veriolog-XL simulator and in the Veriolg language definition...

> That's not what he said.
> Again, he meant there are places where non-blocking assignments should not be used.

I must admit my slight bias agains the <= form of assignment
has much to do with simulation efficiemcy - I know that
'<=' and '<= #' have to allocate a temporary storage structure
into which it stores the data waiting for assignmemnt (this is because
at compile time the compiler usually can't tell how many <= asignments
will be pending during any one time period). '=' on the other hand
requires no temporary storage and '= #' requires storage that can
be allocated staticly.

Any smart implementation is going to optimise the hell out of the
single <= case - my benchamarking of this a few years back showed a
few % advantage to '= #' over '<=' and a lot to '=' over '<='

Also remember '=' and '<=' don't have the same semantics, for example:

        temp = a+b+c;
        res <= temp+x;
vs.

        temp <= a+b+c;
        res <= temp+x

give different results because in the 2nd case the last asisgnment
picks up the previous version of res - I'm sure you all know that
but my point is that there's a trap here if you use <= indiscriminately
it should always be used carefully - my rule of thumb is that you only
use it on things that you know update at a particular time (ie a clock edge
which means flops)

        Paul Campbell

PS: I also use <= for funky slow-wire simulations like:


                b <= #100 a;

where a is changing much faster than #100



Thu, 03 Oct 2002 03:00:00 GMT  
 Verilog error? (non blocking assignments + assign statement)

Quote:

> The essence of your verilog looks something like this:


>            s <= ....    (this is in another block)
>    assign  shift_reg = s;  (this assign is implicit when you pass
>                            the result to the other block thru a wire)


>            fsm_status <= ....


>    case (fsm_status)

>            ......

>            case (shift_reg)

>            A:
>            B:

> The ordering of the updates of s and fsm_status are undefined, because
> the ordering of the always blocks in which they are updated is undefined
> and verilog only makes sure of the ordering of these assignments if they
> are executed sequentially in the same block.

> After the updates are complete there will be 2 events triggered by the change of
> the variables - the assign and the last always statement because fsm_status
> changed - assume that the always statement got queued first - it gets executed
> but seems the old value of shift_reg because the assign hasn't been executed yet,
> next the assign gets executed - as a result shift_reg changes which in turn causes
> the the last always statement to be triggered again and you go thru it a second time.
> That's why what you are seeing is happening.

> Again real-world logic synthesised from your design COULD glitch the same way (if
> for example there was a similar delay in the wire coming out of 's' to the combinatorial
> logic that the last always statement represents - but like the verilog it doesn't
> matter provided you meet setup on the flops in the following clock

I agree with you that this is what is happening but then my question turns out
to be: How do i avoid such a behaviour? I'd really like to find a clean way to
handle situations like this one...
I just want to design a shift register which is in the sensitivity list of my
state machine and i'd really like to have the FSM splitted in two parts with
one dealing with the asynchronous part and the other with the synchronous
one...
Is there a clean way to do it? It seems to me a quite "common" situation.
I'd like to find something which ensures me to be usable on any simulator and
then being still usable in synthesys without being to messy:)

Quote:
>    Paul

Many thanks,
                Roberto

--

Phone:  +39 10 353-6301                                 Via Dodecaneso, 33
Fax:    +39 10 353-6319                                 I-16146 GENOVA



Fri, 04 Oct 2002 03:00:00 GMT  
 Verilog error? (non blocking assignments + assign statement)

Quote:

> I agree with you that this is what is happening but then my question turns out
> to be: How do i avoid such a behaviour? I'd really like to find a clean way to
> handle situations like this one...
> I just want to design a shift register which is in the sensitivity list of my
> state machine and i'd really like to have the FSM splitted in two parts with
> one dealing with the asynchronous part and the other with the synchronous
> one...
> Is there a clean way to do it? It seems to me a quite "common" situation.
> I'd like to find something which ensures me to be usable on any simulator and
> then being still usable in synthesys without being to messy:)

I think that what you are doing is correct - this style of coding [splitting
the design into combinatorial part and a state/flops part]  is very
common for synthesis (I use it all the time) - the thing to remember is that
the combinatorial stuff may fire more than once per clock or time period - that's
normal, but it can it make debugging a pain, remember - you only care about the values
calculated the last time thru the combinatorial stuff after all its inputs settle
(just like any glitchy net being set up on a flop)

        Paul Campbell



Fri, 04 Oct 2002 03:00:00 GMT  
 
 [ 8 post ] 

 Relevant Pages 

1. Variable/Signal assigned by multiple non-blocking assignments

2. blocking and non-blocking assignment

3. Strange behaviour with blocking and non-blocking assignment

4. Blocking and Non-blocking assignment ?

5. "Blocking and non-blocking" assignments

6. why target cannot be assigned (in verilog) using a blocking and non-blocking assignment?

7. Non-blocking assign

8. Non blocking assign question

9. Non Blocking Assignment

10. Guaranteed ordering of non-blocking assignments

11. swapping using non-blocking assignments

12. consecutive non-blocking assignments

 

 
Powered by phpBB® Forum Software