Skip to content

Verilog · Chapter 14.4.2 · Behavioural Modeling

Event-Based Timing Controls in Verilog — The @ Event Control

The event control runs a procedural statement when a signal event occurs, and it is the one synthesizable timing control. It is the mechanism that triggers every clocked and combinational always block. It comes in two flavours that map directly to the two kinds of logic. Edge-sensitive control fires on a clock or reset edge and is how sequential logic, meaning flip-flops, is triggered. Level-sensitive control fires on any change in the listed signals and is how combinational logic is triggered. A third form, the named event, provides explicit synchronization and is used mostly in testbenches. This page drills all three forms and connects them back to combinational-versus-sequential inference, because the event control is the sensitivity that decides which hardware an always block becomes.

Foundation13 min readVerilogEvent ControlposedgeSensitivityNamed Event

Chapter 14 · Section 14.4.2 · Behavioural Modeling

1. The Engineering Problem

Clocked logic must run on the clock edge; combinational logic must run on any input change. Both are expressed by the @ event control — the synthesizable timing mechanism:

The @ event control runs a statement on a signal event: an edge (@(posedge clk)) for sequential logic, or a level change (@(*)) for combinational. It is the synthesizable timing control — the trigger of every always block.

This page drills the @ event control's three forms — edge, level, and named events.

2. Mental Model — @ Fires on a Signal Event

3. Edge-Sensitive Events

@(posedge clk) / @(negedge clk) fire on clock (or reset) edges — the trigger of sequential logic:

edge.v
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
   always @(posedge clk)              // rising clock edge
       q <= d;                        // a flip-flop
 
   always @(posedge clk or negedge rst_n)  // edge + async reset
       if (!rst_n) q <= 0;
       else        q <= d;
  • posedge — a transition to 1 (0→1, x→1, z→1); negedge — a transition to 0.
  • Multiple edges combine with or: @(posedge clk or negedge rst_n) triggers on either, the basis of synchronous logic with asynchronous reset.
  • Edge-sensitive event control synthesizes to flip-flops — it is how all clocked state is built (14.1).

4. Level-Sensitive Events

@(*) or an explicit list fires on any change in the watched signals — the trigger of combinational logic:

level.v
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
   always @(*)                        // any change in signals read
       y = sel ? a : b;               // combinational mux
 
   always @(a, b, sel)                // explicit list (error-prone — prefer @*)
       y = sel ? a : b;
  • @(*) (Verilog-2001) auto-watches every signal the block reads — the preferred combinational form (no incomplete-list bug, 14.1).
  • @(a, b, sel) is an explicit list; legal but error-prone if incomplete (the sim/synth mismatch of 14.1).
  • Level-sensitive event control synthesizes to combinational logic.

5. Named Events

A named event provides explicit, programmer-controlled synchronization:

named-event.v
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
   event done;                        // declare a named event
 
   // trigger it:
   -> done;                           // fire the event
 
   // wait for it:
   @(done) $display("done fired");    // block until 'done' is triggered
  • event name; declares a named event; -> name; triggers it; @(name) waits for it.
  • Named events synchronize concurrent processes (a producer triggers, a consumer waits) — mostly in testbenches. They carry no data (just the trigger). (Drilled further in 14.4.4.)

Visual A — the @ event control forms

@ event control — edge, level, named

data flow
@ event control — edge, level, named@(posedge clk)edge → sequential (flip-flops)@(*)level → combinational logic@(event)named event → synchronization (sim)
The @ event control fires on three kinds of event: an edge (@(posedge clk)) triggers sequential logic, a level change (@(*)) triggers combinational logic, and a named event (@(done)) provides explicit synchronization. The edge and level forms are synthesizable and decide whether an always block infers registers or combinational logic (14.1).

6. Common Mistakes

  1. Explicit incomplete level list@(a or b) missing a read signal causes a sim/synth mismatch; use @(*) (§4, 14.1).
  2. Wrong edge polarityposedge for rising, negedge for falling (§3).
  3. Confusing edge and level — edge → sequential, level → combinational (§2).
  4. Using a named event where a signal edge is meant — named events are for explicit sync, not clocking (§5).

7. Debugging Lab

One event-control debug post-mortem

8. Interview Q&A

9. Exercises

Exercise 1 — Edge or level?

State whether each infers sequential or combinational logic: (a) @(posedge clk); (b) @(*); (c) @(a, b); (d) @(negedge clk).

Exercise 2 — Write the sensitivity

Write the event control for: (a) a flip-flop with active-low async reset; (b) a combinational block reading a, b, c.

Exercise 3 — Named event

Write the declaration, trigger, and wait for a named event start.

10. Summary

The @ event control is the synthesizable timing control:

  • Edge@(posedge clk) / @(negedge rst_n): triggers sequential logic (flip-flops); combine with or for clock + async reset.
  • Level@(*) (preferred) / @(a, b): triggers combinational logic.
  • Named eventevent e; -> e; @(e): explicit synchronization (mostly testbench).
  • It is the sensitivity that decides comb vs seq inference (14.1).

The next sub-topic is a simulation-only control: Chapter 14.4.3 Level Sensitive Timing Controls drills wait — blocking a statement until a condition becomes true.