Skip to content

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 crown jewel)14.5 if / casebranching + latch avoidance14.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

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.