Skip to content
VLSI Mentor

Verilog · Chapter 14 · Behavioural Modeling

Behavioural Modeling in Verilog — Chapter 14 Overview

This is the most important chapter in the Verilog track. Dataflow modeling gave you combinational logic, but it hit a hard wall because it has no state and cannot build a register, a counter, or a finite state machine. Behavioural modeling crosses that wall by describing hardware with procedural blocks, always and initial, that run statements like if, case, and loops and can model sequential logic, meaning clocked registers that hold a value between clock edges. Two ideas decide everything here: combinational versus sequential inference, whether an always block becomes pure logic or flip-flops based on its sensitivity list, and blocking versus non-blocking assignment, the most-tested topic and most common bug source in Verilog. This overview frames behavioural modeling and sets up the sub-pages that drill it in depth.

Foundation18 min readVerilogBehaviouralalwaysSequential LogicFSMRTL Design

Chapter 14 · Behavioural Modeling (Overview)

1. The Engineering Problem

Chapter 13 ended at a wall: dataflow models combinational logic only, so `assign count = count + 1;` is a feedback loop, not a counter. Every real design needs state — registers that hold values, counters that advance, FSMs that remember where they are, pipelines that move data across cycles. The question that opens the RTL core's most important chapter:

How do you build sequential, clocked, stateful logic — registers, counters, FSMs — that dataflow cannot express? And how do you write complex combinational logic with statements like if and case?

The answer is behavioural modeling: procedural blocks — always and initial — that execute statements and can describe both combinational and sequential hardware. An always @(posedge clk) block driving a reg is a register: it captures a value on the clock edge and holds it until the next one. This is where the counter you could not build becomes a few clean lines, where FSMs and pipelines live, and where the bulk of real RTL is written. This chapter is the spine of digital design.

2. What Is Behavioural Modeling?

Behavioural modeling describes hardware by what it does, procedurally — sequences of statements inside always/initial blocks — rather than by gates (structural) or expressions (dataflow):

behavioural-glance.v
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
   // sequential: a register that holds state (a counter)
   always @(posedge clk or negedge rst_n)
       if (!rst_n) count <= 0;
       else        count <= count + 1;     // advances each clock edge
 
   // combinational: a mux with an if (higher-level than dataflow ?:)
   always @(*)
       if (sel) y = a;
       else     y = b;

The first block is sequential — it builds a register that updates on the clock edge and holds between edges (the counter dataflow couldn't make). The second is combinational — it builds a mux, equivalent to `assign y = sel ? a : b;` but written with a statement. The same always construct does both; the sensitivity and the assignment style decide which. This dual capability — and the state it adds — is why behavioural modeling is the heart of RTL.

3. Mental Model — Procedural Blocks That Build Combinational or Sequential Hardware

Visual A — behavioural modeling completes the RTL core

The RTL core — behavioural adds state

data flow
The RTL core — behavioural adds stateOperators (Ch 10)expressionsDataflow (Ch 13)combinational onlyBehavioural comb(Ch 14)if/case logicBehavioural seq(Ch 14)registers, FSMs, state
Operators build expressions, dataflow makes them combinational hardware — but only behavioural modeling adds sequential, clocked STATE. Behavioural modeling completes the RTL core: combinational logic (also expressible in dataflow) plus the registers, counters, FSMs, and pipelines that nothing else can build.

4. Combinational vs Sequential Inference

The single most important distinction in this chapter: an always block infers combinational logic or sequential (clocked) logic, decided by its sensitivity list:

always formInfersHolds state?Example
always @(*)combinational logicnomux, decoder, adder
always @(posedge clk)sequential (flip-flops)yesregister, counter, FSM
  • always @(*) (or always @(a, b, sel)) re-evaluates on any input change and produces a pure function of the inputs — the same hardware dataflow builds, written with statements. To be correct combinational logic, every output must be assigned on every path (else a latch is inferred — a Chapter 14.5 hazard).
  • always @(posedge clk) updates only on the clock edge, so its outputs are registers that hold between edges — the state that makes counters, FSMs, and pipelines possible. A reset (negedge rst_n) sets the known starting state.

This inference rule — sensitivity decides comb vs seq — is the foundation of synchronous design, drilled in 14.1.

Visual B — combinational vs sequential always

Combinational versus sequential always blockalways @(*)→ combinational logicno statefunction of inputs nowalways @(posedge clk)→ registers (flip-flops)holds statevalue between edges12
The same always construct infers different hardware by its sensitivity. always @(*) re-evaluates on any input change → combinational logic (no state). always @(posedge clk) updates only on the clock edge → flip-flops that hold state between edges (registers, counters, FSMs). The sensitivity list decides whether you get logic or registers.

5. Blocking vs Non-Blocking — The Crown Jewel (Preview)

The second governing idea — and the most famous rule in Verilog — is the choice of assignment operator inside a procedural block:

blocking-nonblocking-preview.v
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
   // BLOCKING (=) — for COMBINATIONAL logic
   always @(*)  y = a & b;
 
   // NON-BLOCKING (<=) — for SEQUENTIAL logic
   always @(posedge clk)  q <= d;
  • Blocking = executes immediately, in order, like a software statement — the right choice for combinational logic in always @(*).
  • Non-blocking <= schedules the update to apply at the end of the time-step, so all right-hand sides are read first — the right choice for sequential logic in always @(posedge clk), because it correctly models registers updating together on the edge.

The rule every RTL engineer lives by:

= (blocking) in combinational always @(*); <= (non-blocking) in clocked always @(posedge clk). Using the wrong one produces races, wrong shift registers, and sim/synth mismatches — the #1 Verilog bug, drilled in depth in 14.3.

This preview flags it; Chapter 14.3 is the full treatment, because mastering blocking vs non-blocking is the difference between RTL that works and RTL that mysteriously doesn't.

6. What This Chapter Covers

Behavioural modeling spans seven sub-topics (several with their own children):

§Sub-pageCovers
14.1Behavioural Blocks (initial & always)the procedural blocks; sensitivity; comb vs seq inference
14.2Sequential & Parallel Blocksbegin...end vs fork...join statement grouping
14.3Blocking & Non-Blocking Assignments= vs <= — the crown jewel; races, shift registers, the golden rules
14.4Timing Controlsdelay (#), event (@), and level (wait) controls (+ sub-topics)
14.5Multiway Branchingif/else and case — and latch avoidance (+ sub-topics)
14.6Loopsfor, while, repeat, forever (+ sub-topics)
14.7Generate Blockgenerate for replicated/parameterized structure (+ sub-topics)

Visual C — the Chapter 14 roadmap

Chapter 14 sub-topics

data flow
Chapter 14 sub-topics14.1 always /initialcomb vs seq inference14.3 Blocking vsNon-Blocking= vs <= (the crownjewel)14.5 if / casebranching + latchavoidance14.6-14.7 loops /generateiteration +replication
The chapter builds from the always block (14.1), through the decisive blocking-vs-non-blocking rule (14.3), to the branching (14.5), iteration (14.6), and replication (14.7) constructs. 14.1 and 14.3 are the foundation every other page assumes.

7. Industry Perspective

  • Behavioural modeling is how RTL is written. The vast majority of synthesizable design — registers, FSMs, datapaths with state, control logic — is procedural always blocks. It is the everyday language of digital design.
  • Combinational vs sequential discipline is fundamental. Engineers reflexively separate always @(*) combinational blocks from always @(posedge clk) sequential blocks, and lint enforces correct sensitivity and assignment style.
  • Blocking vs non-blocking is a top interview question and bug source. "Use = for combinational, <= for sequential" is drilled into every RTL engineer because getting it wrong causes subtle, hard-to-find failures.
  • Latch inference is a watched hazard. A combinational always block that doesn't assign an output on every path infers an unintended latch — a classic bug that lint flags (14.5).

8. Common Misconceptions

"An always block runs once, like a function." False. An always block runs repeatedly, every time its sensitivity triggers — on every relevant input change (@(*)) or every clock edge (@(posedge clk)). It is always-active hardware, not a one-time call.

"= and <= are interchangeable styles." False, and dangerous. Blocking = and non-blocking <= model different behaviour. = for combinational, <= for sequential — using the wrong one causes races and wrong logic (14.3). This is the rule, not a preference.

"always blocks are only for sequential logic." False. always @(*) models combinational logic (with statements like if/case); always @(posedge clk) models sequential. Behavioural modeling does both — the sensitivity decides.

"Behavioural code is non-synthesizable." Misleading. Synthesizable always blocks are the core of RTL. Only certain constructs (initial for stimulus, # delays, unbounded loops) are simulation-only; the bulk of behavioural modeling synthesizes to gates and flip-flops.

9. Debugging Lab

One behavioural-modeling debug post-mortem

Pitfall — an incomplete sensitivity list makes RTL disagree with synthesis
Buggy Code
module and_gate (input a, b, output reg y);
  // Intent: combinational AND. But the sensitivity list names only 'a'.
  always @(a)
      y = a & b;        // recomputes only when 'a' changes
endmodule

// In SIMULATION the block runs only when 'a' changes. If 'b' changes while
// 'a' is steady, y is NOT recomputed — so y keeps a stale value and the
// "AND gate" appears broken. But SYNTHESIS reads the body, sees y depends on
// BOTH a and b, and builds a real AND gate sensitive to both. So the gate-
// level netlist and the RTL simulation DISAGREE: the netlist updates on 'b',
// the RTL sim does not. A classic sim/synth mismatch from a wrong sensitivity
// list.
Symptom

A combinational block produces stale outputs in RTL simulation when an input that is missing from the sensitivity list changes — the logic looks broken in sim. Yet synthesis builds correct hardware, so gate-level simulation and silicon behave differently from the RTL sim.

Root Cause

The sensitivity list controls WHEN a combinational always block recomputes, and here it lists only 'a'. So the block re-evaluates on a change of 'a' but never on a change of 'b', leaving y stale whenever only 'b' moves. Synthesis, however, ignores an incomplete sensitivity list for combinational logic and infers the full input set from the body — so it produces a gate sensitive to both a and b. The RTL sim (partial sensitivity) and the netlist (full sensitivity) therefore diverge.

Behavioural modeling is not just statements: the sensitivity list decides WHEN the logic recomputes, and for combinational logic it must include EVERY signal the block reads.

Fix
module and_gate (input a, b, output reg y);
  always @(*)           // '@(*)' = sensitive to every signal the block reads
      y = a & b;
endmodule

// '@(*)' (or '@(a or b)') makes the block recompute on a change of any input,
// so RTL simulation matches the synthesized hardware. Always use '@(*)' for
// combinational always blocks — never a hand-maintained partial list.

10. Interview Q&A

11. Summary

Behavioural modeling describes hardware with procedural blocks (always, initial) — the only style that models sequential, stateful logic, and a higher-level way to write combinational logic.

The core ideas:

  • always blocks execute statements and infer hardware — combinational (always @(*)) or sequential (always @(posedge clk)); the LHS is a reg.
  • Combinational vs sequential inference — sensitivity decides: @(*) → logic (no state), @(posedge clk) → registers (state). This is the foundation of synchronous design.
  • Blocking vs non-blocking= for combinational, <= for sequential; the #1 rule and #1 bug source (14.3).
  • It completes the RTL core — combinational dataflow plus behavioural state describe any synchronous design: registers, counters, FSMs, pipelines.

The mindset this chapter instils: an always block is hardware that re-runs on its trigger — combinational when sensitive to its inputs, a register when sensitive to a clock edge. Read the sensitivity to know what you built.

The first sub-page builds the foundation: Chapter 14.1 Behavioural Blocks (initial & always) drills the procedural blocks, the sensitivity list, and combinational-vs-sequential inference. Then the chapter reaches its crown jewel — 14.3 Blocking & Non-Blocking Assignments — and the branching, loop, and generate constructs that complete behavioural design. This is where you finally build the stateful RTL the whole track has been leading to.

  • Data-Flow Modeling — Chapter 13; combinational logic, and the state wall behavioural modeling crosses.
  • Dataflow Advanced Techniques — Chapter 13.3; the combinational/sequential boundary and the counter dataflow couldn't build.
  • reg — Chapter 5.2.1; the variable always blocks drive, and "reg is not a register."
  • RTL Designing — Chapter 3; the register-transfer model behavioural modeling fully realizes.

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.