Verilog Timing Control

Timing control statements are required in simulation to advance time. The time at which procedural statements will get executed shall be specified using timing controls.

There are the following types of timing controls in Verilog:

  • Delay control
  • Edge sensitive event control
  • Level sensitive event control
  • Named events

The delay control is a way of adding a delay between when the simulator encounters the statement and when it executes.

The event expression allows the statement to be delayed until the occurrence of some simulation event, which can change of value on a net or variable or an explicitly named event triggered in another procedure.

Simulation time can be advanced by one of the following methods. Nets and gates have been modeled to have internal delays, also advance simulation time.

Delay Control

Delay control is achieved by specifying the waiting time to execution when the statement is encountered. The symbol # is used to specify the delay.

We can specify the delay based timing control in three ways:

  1. Regular delay control: It will be specified on the procedural assignment left as a non-zero number.
  2. Intra- assignment delay control: In this case, delays will be specified on the assignment operator's right-hand side. The right-hand side expression will be evaluated at the current time, and the assignment will occur only after the delay.
  3. Zero delay control: Zero delay control statement specifies zero delay value to the left-hand side of a procedural assignment. This method is used to ensure the statement is executed at the end of the simulation time. It means, zero delay control statement is executed after all other statements in that simulation time are executed.

Event Control

An event controls the execution of a statement or a block of a statement. Value changes on variables and nets can be used as a synchronization event to trigger the execution of other procedural statements and is an implicit event.

The event is based on the direction of change like towards 0, which makes it a negedge and change towards 1 make it a posedge.

  • A negedge is a transition from 1 to X, Z or 0 and from X or Z to 0
  • A posedge is a transition from 0 to X, Z or 1 and from X or Z to 1

A transition from the same state to the same state does not suppose to be an edge. The edge event can be detected only on the LSB of a vector signal or variable.

If an expression evaluates to the same result, then it cannot be considered as an event. There are different types of event-based controls.

1. Regular event control: Execution of statement will happen on signal changes or at positive or negative transitions of signals. For example, posedge of a clock, and the negedge of reset, etc.

2. Named Event Control: The event keyword can be used to declare a named event that can be triggered explicitly.

An event cannot hold any data, no time duration, and can be made to occur at any particular time.

A named event is triggered by the -> operator by prefixing it before the named event handle. A named event can be waited upon through the @ operator.

Named events are used to synchronize two or more concurrently running processes. Events can be declared as arrays.

For example, the always block and the second initial block are synchronized by a_event. Events can be declared as arrays such as in the case of b_event, which is an array of size 5, and index 3 is used for trigger and wait for purpose.

3. Event OR control: The transitions of signal or event can trigger statements' execution, as shown below.

The or operator can wait until any one of the listed events is triggered in an expression. The comma (,) can be used instead of the or operator.

Edge Sensitive Event Control

In Verilog, the @ character specifies an edge-sensitive event control that blocks until there is a transition in value (an edge) for one of the event's identifiers.

The edge events are queued and then serviced by @(...) guards, rather than @(?) being a guard that waits on edge events, blocking until an edge event happens.

The only edge events that matter to an @(...) guard are those that happen while it is waiting. Edge events that happen before reaching the guard are irrelevant to the guard.

Level Sensitive Event Control

A procedural statement's execution can be delayed until a condition becomes true and accomplished with the wait keyword. And it is a level-sensitive control.

The wait statement evaluates a condition, and if it is false, the procedural statements remain blocked until the condition becomes true.

After completion the execution, it produces the following output:

Implicit Event Expression List

The event expression list or sensitivity list is often a common cause for many functional errors in the RTL because the user may forget to update the sensitivity list after introducing a new signal in the procedural block.

Now execute the above code and we will get the following output:

ncsim> run
T=0 a=0 b=0 c=0 d=0 x=0 y=0
T=10 a=0 b=1 c=0 d=0 x=1 y=0
T=20 a=0 b=0 c=0 d=1 x=0 y=1
T=30 a=1 b=0 c=0 d=1 x=1 y=1
ncsim: *W,RNQUIE: Simulation is complete.

If the user decides to add new signal e and capture the inverse into z, then special care must be taken to add e also into the sensitivity list.

And the output is given below:

ncsim> run
T=0 a=0 b=0 c=0 d=0 e=0 x=0 y=0 z=1
T=10 a=0 b=0 c=1 d=0 e=0 x=0 y=1 z=1
T=20 a=0 b=0 c=0 d=0 e=1 x=0 y=0 z=0
T=30 a=0 b=1 c=0 d=0 e=1 x=1 y=0 z=0
ncsim: *W,RNQUIE: Simulation is complete.

Verilog allows the sensitivity list to be replaced by * which is a convenient shorthand that eliminates these problems by adding all nets and variables read by the statement as shown in the below code.

The output looks as below:

ncsim> run
T=0 a=0 b=0 c=0 d=0 e=0 x=0 y=0 z=1
T=10 a=0 b=0 c=1 d=0 e=0 x=0 y=1 z=1
T=20 a=0 b=0 c=0 d=0 e=1 x=0 y=0 z=0
T=30 a=0 b=1 c=0 d=0 e=1 x=1 y=0 z=0
ncsim: *W,RNQUIE: Simulation is complete.