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(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 untilconditionevaluates 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(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 specificallywait(ready)cares about the level — it proceeds the momentreadyis (or becomes) 1.@(ready)cares about a change — it waits for any transition ofready, 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 flow5. Common Mistakes
waitin synthesizable design — not synthesizable; testbench-only (§2, DebugLab 1).- Confusing
wait(c)with@(c)— level (is true) vs change (transitions) (§4). waiton 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
Pitfall — wait in synthesizable design logic
module gate (input clk, ready, d, output reg q);
// Intent: capture d only when ready. But 'wait' is not synthesizable.
always @(posedge clk) begin
wait(ready); // BUG: wait in design logic
q <= d;
end
endmodule
// 'wait' blocks a process until a condition holds — a simulation behaviour
// with no hardware equivalent. Synthesis rejects it. The intended
// 'capture d only when ready' is just a conditional (if), not a wait.A design module using 'wait' inside an always block fails to synthesize with an error about a non-synthesizable construct, even though the intent (gate the capture on 'ready') is simple.
'wait' is a level-sensitive blocking construct — it suspends a process until a condition is true — which is a simulation behaviour with no hardware mapping, so it is not synthesizable. The design intent here is 'capture d on the clock edge only when ready is high,' which is an ordinary conditional (if (ready)), not a blocking wait. 'wait' belongs in testbench synchronization, not design.
The fix is to use an 'if' to gate the capture, the synthesizable way to make a register conditional.
module gate (input clk, ready, d, output reg q);
always @(posedge clk)
if (ready) q <= d; // conditional capture (synthesizable)
endmodule
// An if gates the register on 'ready' each clock edge. 'wait' is for
// testbenches; design uses if/case to make logic conditional.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
@—waitis level (is true),@is change (transitions). - Simulation-only — testbench synchronization (ready/ack/done); not synthesizable.
- In design, use
ifto make logic conditional, notwait.
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.
Related Tutorials
- Event-Based Timing Controls — Chapter 14.4.2; the
@event controlwaitcontrasts with. - Timing Controls — Chapter 14.4; the three timing controls.
- Simulation Control — Chapter 8.5; watchdogs that bound a
waitthat might never complete. - Testbench Creation Techniques — Chapter 9.5; testbench synchronization.
Standards & specifications
- Governing standard
- IEEE Std 1364 (Verilog)(opens IEEE in a new tab)
Defines the Verilog language and its simulation semantics, including the event scheduling model. Synthesis support is defined by tools, not by this standard.
This page also covers RTL structure, verification approach and debugging technique. Those are engineering practice built on the standard, not requirements the standard itself imposes.
Where this fits
Part of the Verilog HDL curriculum.
