Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronic Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Register Log in

Beginning and end of a time step

stanford

Full Member level 2
Joined
Feb 16, 2014
Messages
123
Helped
4
Reputation
8
Reaction score
4
Trophy points
18
Activity points
889
Non-blocking assignment evaluates the RHS expression at the beginning of a time step and schedules the LHS update to take
place at the end of the time step.

Let's say we have
Code:
always_ff @(posedge clk)
  c <= a | b;
If we have a non-blocking assignment inside a always_ff block, does the beginning of a timestep mean the current clock edge and the end of the time step mean the next clk edge? So that (a | b) is evaluated in the current clock edge but the assignment happens in the next clk edge?

Thanks!
 

dave_59

Advanced Member level 3
Joined
Dec 15, 2011
Messages
812
Helped
361
Reputation
726
Reaction score
354
Trophy points
1,353
Location
Fremont, CA, USA
Activity points
6,279
This is not the correct way of thinking about it. The RHS of non-blocking assignment gets evaluated as soon as the previous statement completes. The LHS c gets scheduled to update after in another region after everything in the current active region completes. This guarantees that any other always_ff reading c does not read the updated value until the next clock cycle.
 

ThisIsNotSam

Advanced Member level 5
Joined
Apr 6, 2016
Messages
1,998
Helped
354
Reputation
708
Reaction score
350
Trophy points
83
Activity points
10,029
Non-blocking assignment evaluates the RHS expression at the beginning of a time step and schedules the LHS update to take
place at the end of the time step.

Let's say we have
Code:
always_ff @(posedge clk)
  c <= a | b;
If we have a non-blocking assignment inside a always_ff block, does the beginning of a timestep mean the current clock edge and the end of the time step mean the next clk edge? So that (a | b) is evaluated in the current clock edge but the assignment happens in the next clk edge?

Thanks!
In my experience, people tend to misunderstand the concepts of delta cycles and how a simulator works internally. I see students that struggle with the concepts of sequential vs combinational, blocking vs non-blocking. On top of that, they try to understand the simulator internals and it's just a big mess.

So, is there a reason why you are asking this question?
 

stanford

Full Member level 2
Joined
Feb 16, 2014
Messages
123
Helped
4
Reputation
8
Reaction score
4
Trophy points
18
Activity points
889
This is not the correct way of thinking about it. The RHS of non-blocking assignment gets evaluated as soon as the previous statement completes. The LHS c gets scheduled to update after in another region after everything in the current active region completes. This guarantees that any other always_ff reading c does not read the updated value until the next clock cycle.
I'm still confused. Let's say in the waveform,
Code:
clk edge 0: a = 0, b = 0
clk edge 1: a = 1, b = 1
Now, at clk edge 1, the always_ff will be triggered and the RHS will be evaluated (a || b) = (1 || 1) = 1, or will it evaluate with the previous value (a || b) = (0 || 0) = 0? If the latter is true, how does the simulator ensure it uses the values before a or b changes?
 

dave_59

Advanced Member level 3
Joined
Dec 15, 2011
Messages
812
Helped
361
Reputation
726
Reaction score
354
Trophy points
1,353
Location
Fremont, CA, USA
Activity points
6,279
If you use blocking assignments to a and b, you have a race condition. That is the whole point of using non-blocking assignments when one always process writes, and another always process reads the same variable, and both blocks are synchronized to the same clock edge.
 

stanford

Full Member level 2
Joined
Feb 16, 2014
Messages
123
Helped
4
Reputation
8
Reaction score
4
Trophy points
18
Activity points
889
If you use blocking assignments to a and b, you have a race condition. That is the whole point of using non-blocking assignments when one always process writes, and another always process reads the same variable, and both blocks are synchronized to the same clock edge.
Let me give a more specific example to show what I'm confused about.

Code:
input in;

always_ff @(posedge clk)
  c <= a | b;

always_comb begin
  a = in;
  b = a;
end

          1     2     3
clk     __|--|__|--|__|--|__

in       _______|-------------

c         ____________|------
In the wave, we see the input 'in' change from 0 -> 1 at clk edge 2. At edge 2, isn't there a race condition as to which always block gets executed first? If always_ff is executed first, it will see a = b = 0 and c = (0 | 0) = 0 at edge 2. If always_comb block execute first, a = b = 1 and c = (1 | 1) at edge 2. I'm trying to understand the sequence of event that takes place at edge 2. If you could use this example to explain, that might help clear up my confusion better. thanks!
 
Last edited:

dave_59

Advanced Member level 3
Joined
Dec 15, 2011
Messages
812
Helped
361
Reputation
726
Reaction score
354
Trophy points
1,353
Location
Fremont, CA, USA
Activity points
6,279
You have to look at how every signal changes value. Assuming every signal that changes on a clock edge uses a non-blocking assignment, there will be no race conditions. And you may have to look through several layers of combinational logic to find the synchronous change. This means flattening the module hierarchy and finding where "in" gets its new value from.
 

stanford

Full Member level 2
Joined
Feb 16, 2014
Messages
123
Helped
4
Reputation
8
Reaction score
4
Trophy points
18
Activity points
889
Code:
input in;

always_ff @(posedge clk)
  c <= a | b;

always_ff @(posedge clk)
  in <= foo;

always_comb begin
  a = in;
  b = a;
end

          1     2     3
clk     __|--|__|--|__|--|__

foo    ___|---------------------

in       _______|-------------

a        _______|-------------

b        _______|-------------

c         ____________|------
Is the order of events below correct at clk edge 2? could you please point out clearly which step is wrong and how it should change?

1. positive clk edge 2 triggers always_ff block to execute first
2. a) RHS of always_ff is evaluated to (a | b = 0 | 0 = 0), assignment of c is delayed until end of time step
b) RHS of always_ff is evaluated to (foo = 1), assignment of in is delayed until end of time step
3. Since input 'in' does not change until the end of time step, always_comb does not get triggered?
4. LHS of non-blocking statements is assigned to the new value (c = 0, in = 1) at clk edge 2
5. always_comb gets triggered because 'in' changed and a = 1 and b = 1 gets the new value at edge 2
 
Last edited:

ads-ee

Super Moderator
Staff member
Joined
Sep 10, 2013
Messages
7,562
Helped
1,768
Reputation
3,542
Reaction score
1,710
Trophy points
113
Location
USA
Activity points
55,759
It seems like you think the always_comb is going to be triggered at the same time as the always_ff resulting in some sort of race condition.

The sensitivity for the always_ff is the low to high transition of clk. The always_comb is sensitive to changes on in and a (RHS).

So as soon as in changes at the end of the always_ff @(posedge clk) timestep the always_comb gets triggered.

Maybe you should read this paper by Cummings on the event region. It's somewhat easier to understand than Section 4 of the 1800-2017 IEEE standard.
 

stanford

Full Member level 2
Joined
Feb 16, 2014
Messages
123
Helped
4
Reputation
8
Reaction score
4
Trophy points
18
Activity points
889
It seems like you think the always_comb is going to be triggered at the same time as the always_ff resulting in some sort of race condition.

The sensitivity for the always_ff is the low to high transition of clk. The always_comb is sensitive to changes on in and a (RHS).

So as soon as in changes at the end of the always_ff @(posedge clk) timestep the always_comb gets triggered.

Maybe you should read this paper by Cummings on the event region. It's somewhat easier to understand than Section 4 of the 1800-2017 IEEE standard.
Can you take a look at my steps above? I think you are saying the same thing.
 

stanford

Full Member level 2
Joined
Feb 16, 2014
Messages
123
Helped
4
Reputation
8
Reaction score
4
Trophy points
18
Activity points
889
Code:
input in;

always_ff @(posedge clk)
  c <= a | b;

always_ff @(posedge clk)
  in <= foo;

always_comb begin
  a = in;
  b = a;
end

          1     2     3
clk     __|--|__|--|__|--|__

foo    ___|---------------------

in       _______|-------------

a        _______|-------------

b        _______|-------------

c         ____________|------
Is the order of events below correct at clk edge 2? could you please point out clearly which step is wrong and how it should change?

1. positive clk edge 2 triggers always_ff block to execute first
2. a) RHS of always_ff is evaluated to (a | b = 0 | 0 = 0), assignment of c is delayed until end of time step
b) RHS of always_ff is evaluated to (foo = 1), assignment of in is delayed until end of time step
3. Since input 'in' does not change until the end of time step, always_comb does not get triggered?
4. LHS of non-blocking statements is assigned to the new value (c = 0, in = 1) at clk edge 2
5. always_comb gets triggered because 'in' changed and a = 1 and b = 1 gets the new value at edge 2
I understand the theory, but I just wanted to make sure my understanding of the real life example makes sense. If someone has a good understanding of this topic, could you please confirm or correct it? thanks
 

dave_59

Advanced Member level 3
Joined
Dec 15, 2011
Messages
812
Helped
361
Reputation
726
Reaction score
354
Trophy points
1,353
Location
Fremont, CA, USA
Activity points
6,279
You are missing the code that changes clk and in. And nothing changes at the end of a time step. Change has to happen first, and only when there are no more changes can you proceed to the end of the time step.
 

Toggle Sidebar

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top