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
ifandcase?
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):
// 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 flow4. 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 form | Infers | Holds state? | Example |
|---|---|---|---|
always @(*) | combinational logic | no | mux, decoder, adder |
always @(posedge clk) | sequential (flip-flops) | yes | register, counter, FSM |
always @(*)(oralways @(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
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 (=) — 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 inalways @(*). - 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 inalways @(posedge clk), because it correctly models registers updating together on the edge.
The rule every RTL engineer lives by:
=(blocking) in combinationalalways @(*);<=(non-blocking) in clockedalways @(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-page | Covers |
|---|---|---|
| 14.1 | Behavioural Blocks (initial & always) | the procedural blocks; sensitivity; comb vs seq inference |
| 14.2 | Sequential & Parallel Blocks | begin...end vs fork...join statement grouping |
| 14.3 | Blocking & Non-Blocking Assignments | = vs <= — the crown jewel; races, shift registers, the golden rules |
| 14.4 | Timing Controls | delay (#), event (@), and level (wait) controls (+ sub-topics) |
| 14.5 | Multiway Branching | if/else and case — and latch avoidance (+ sub-topics) |
| 14.6 | Loops | for, while, repeat, forever (+ sub-topics) |
| 14.7 | Generate Block | generate for replicated/parameterized structure (+ sub-topics) |
Visual C — the Chapter 14 roadmap
Chapter 14 sub-topics
data flow7. Industry Perspective
- Behavioural modeling is how RTL is written. The vast majority of synthesizable design — registers, FSMs, datapaths with state, control logic — is procedural
alwaysblocks. It is the everyday language of digital design. - Combinational vs sequential discipline is fundamental. Engineers reflexively separate
always @(*)combinational blocks fromalways @(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
alwaysblock 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
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:
alwaysblocks execute statements and infer hardware — combinational (always @(*)) or sequential (always @(posedge clk)); the LHS is areg.- 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.
Related Tutorials
- 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
alwaysblocks drive, and "reg is not a register." - RTL Designing — Chapter 3; the register-transfer model behavioural modeling fully realizes.