Skip to content

Verilog · Chapter 14.4.3 · Behavioural Modeling

Level-Sensitive Timing Controls in Verilog — The wait Statement

The wait statement is Verilog's level-sensitive timing control. It blocks a procedural statement until its condition becomes true. Unlike an event control, which fires on a change such as an edge or transition, wait is sensitive to a level. If the condition is already true, execution proceeds immediately; otherwise it suspends until the condition holds. This is a simulation and testbench construct, not something you synthesize, because there is no real hardware that simply blocks until a condition is met. In practice wait is used for testbench synchronization, such as waiting for a handshake, a ready flag, or a done signal before continuing, and it never belongs in design logic. This lesson drills the level-sensitive semantics, how wait differs from the event control, and its common testbench uses.

Foundation10 min readVerilogwaitLevel SensitiveTestbenchSynchronization

Chapter 14 · Section 14.4.3 · Behavioural Modeling

1. The Engineering Problem

A testbench often needs to wait until something is ready — a ready flag, a done signal, a buffer non-empty — before proceeding. The wait statement does this, with one defining property:

wait(condition) blocks until the condition is true (level-sensitive) — proceeding immediately if it is already true. It is a simulation/testbench tool, not synthesizable.

This page drills wait and how it differs from the @ event control.

2. Mental Model — wait Blocks Until a Level Is True

3. The wait Statement

wait.v
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
   wait(ready);                    // block until ready is 1
   data = bus;                     // then proceed
 
   wait(count == 8) $display("count reached 8");
 
   // wait for a handshake in a testbench:
   send_request();
   wait(ack);                      // block until the DUT acknowledges
   send_request_done();
  • wait(condition) suspends until condition evaluates true; if already true, no suspension.
  • It is commonly followed by a statement to run once the condition holds (wait(ready) data = bus;).
  • Used in testbenches to synchronize on DUT signals — wait for a ready, an ack, a done — without polling.

4. wait vs @ — Level vs Change

The key distinction:

wait-vs-event.v
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
   wait(ready);     // LEVEL: proceeds as soon as ready IS 1 (now or later)
   @(ready);        // CHANGE: waits for ready to CHANGE (even 1→0); not "is 1"
   @(posedge ready);// EDGE: waits for ready to go 0→1 specifically
  • wait(ready) cares about the level — it proceeds the moment ready is (or becomes) 1.
  • @(ready) cares about a change — it waits for any transition of ready, regardless of the resulting value.
  • @(posedge ready) waits specifically for a rising edge.

Use wait when you want "proceed once this condition holds"; use @ when you want "fire on this change/edge." (@ is the synthesizable one; wait is testbench-only.)

Visual A — wait (level) vs @ (change)

wait vs @

data flow
wait vs @wait(c)level: proceeds when c IS true@(c)change: waits for c to CHANGE@(posedge c)edge: waits for c to go 0→1
wait is level-sensitive — it proceeds as soon as the condition is (or becomes) true, with no wait if already true. @ is change-sensitive — it waits for a transition. wait is a testbench synchronization tool; @ (especially the edge form) is the synthesizable trigger of hardware.

5. Common Mistakes

  1. wait in synthesizable design — not synthesizable; testbench-only (§2, DebugLab 1).
  2. Confusing wait(c) with @(c) — level (is true) vs change (transitions) (§4).
  3. wait on a condition that never becomes true — blocks forever (a testbench hang; pair with a watchdog, 8.5).

6. Debugging Lab

One wait debug post-mortem

7. Interview Q&A

8. Exercises

Exercise 1 — wait vs @

State the difference between wait(ready), @(ready), and @(posedge ready).

Exercise 2 — Testbench sync

Write a testbench fragment that sends a request, then waits for ack before continuing.

Exercise 3 — Replace wait in design

Rewrite always @(posedge clk) begin wait(en); q <= d; end as synthesizable design logic.

9. Summary

The wait statement is the level-sensitive timing control:

  • wait(condition) blocks until the condition is true (level-sensitive); proceeds immediately if already true.
  • vs @wait is level (is true), @ is change (transitions).
  • Simulation-only — testbench synchronization (ready/ack/done); not synthesizable.
  • In design, use if to make logic conditional, not wait.

The last timing sub-topic combines techniques: Chapter 14.4.4 Advanced Timing Techniques covers intra-assignment delays, named events, and combining timing controls — the patterns used in sophisticated testbenches.