cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Visitor
Visitor
296 Views
Registered: ‎09-03-2018

Why does the order of blocks affect the behaviour of variables in this code?

Jump to solution
 

In the following code, always blocks of two variables (test1, test2) are exactly the same, but the waveform of test2 is one clock cycle ahead of test1 in Vivado simulator (but not in iverilog). I think the only difference between them is the position of their always blocks.

If I remember it correctly, all blocks are executed simultaneously regardless of their positions in the code. Am I wrong? If not, why does this happen? 

 CodeCode

Vivado outputVivado output

Icarus Verilog outputIcarus Verilog output

0 Kudos
1 Solution

Accepted Solutions
Highlighted
Guide
Guide
213 Views
Registered: ‎01-23-2009

In Verilog, it is clearly stated that there is no implicit ordering of "same type" events in the same time tick. So let's break this down.

First let's look at your two descriptions of the flip-flops. These use non-blocking assignments, which guarantee that the variable updates are done after the "blocking" operations, which are the execution of the always blocks. So the use of the non-blocking assignments ensure that the processing of the two flip-flop descriptions are independent of eachother.

However, there are other events that occur in the same time tick - specifically the change in clk, reset, and trigger. Since all of these are described with blocking assignments, there "order" within a time tick is essentially random - any simulator can choose to implement them so that they execute in a different order.

So, when each of your two "always @(posedge clk)" statements trigger, which of these three signals have already changed and which ones haven't. We know the clock has changed since it triggers these two blocks, but what about the other two? Have the "trigger" and the "reset" already made their changes during this time tick at the time the "always @(posedge clk)" executes, or have they not yet executed? The answer is that the Verilog language allows a simulator to make its own choice. That is why the two simulators are behaving differently. 

Even clearer is that you have three "@(posedge clk)" statements that are executing - two in your flip-flop descriptions and one in the generation of the "trigger" signal. When "clk" rises, all three will be triggered. Which one goes first? It is completely simulator dependent - this makes it even clearer that the "trigger" value could have already made its transition this clock tick before or after the evaluation of the two flip-flop descriptions. And that's what's happening - in one simulator one flip-flop believes that the change in trigger happened "before the clock edge" and one believes that it happened after.

In order to make these two simulations behave the same you need to remove these 0 time races. This can be done by delaying the changing of "trigger" and "reset" to times where the clock is not changing (instead of changing them at the same time tick as the clock is changing), or assigning them with non-blocking assignments, which ensures that they don't change state until after all blocking operations (the always blocks).

[Note: this is a bit simplistic - the real scheduling is a bit more complicated, but this is sufficient for understanding this issue].

Avrum

View solution in original post

1 Reply
Highlighted
Guide
Guide
214 Views
Registered: ‎01-23-2009

In Verilog, it is clearly stated that there is no implicit ordering of "same type" events in the same time tick. So let's break this down.

First let's look at your two descriptions of the flip-flops. These use non-blocking assignments, which guarantee that the variable updates are done after the "blocking" operations, which are the execution of the always blocks. So the use of the non-blocking assignments ensure that the processing of the two flip-flop descriptions are independent of eachother.

However, there are other events that occur in the same time tick - specifically the change in clk, reset, and trigger. Since all of these are described with blocking assignments, there "order" within a time tick is essentially random - any simulator can choose to implement them so that they execute in a different order.

So, when each of your two "always @(posedge clk)" statements trigger, which of these three signals have already changed and which ones haven't. We know the clock has changed since it triggers these two blocks, but what about the other two? Have the "trigger" and the "reset" already made their changes during this time tick at the time the "always @(posedge clk)" executes, or have they not yet executed? The answer is that the Verilog language allows a simulator to make its own choice. That is why the two simulators are behaving differently. 

Even clearer is that you have three "@(posedge clk)" statements that are executing - two in your flip-flop descriptions and one in the generation of the "trigger" signal. When "clk" rises, all three will be triggered. Which one goes first? It is completely simulator dependent - this makes it even clearer that the "trigger" value could have already made its transition this clock tick before or after the evaluation of the two flip-flop descriptions. And that's what's happening - in one simulator one flip-flop believes that the change in trigger happened "before the clock edge" and one believes that it happened after.

In order to make these two simulations behave the same you need to remove these 0 time races. This can be done by delaying the changing of "trigger" and "reset" to times where the clock is not changing (instead of changing them at the same time tick as the clock is changing), or assigning them with non-blocking assignments, which ensures that they don't change state until after all blocking operations (the always blocks).

[Note: this is a bit simplistic - the real scheduling is a bit more complicated, but this is sufficient for understanding this issue].

Avrum

View solution in original post