Verilog · Chapter 17.1 · Delay Modeling
Distributed vs Lumped Delay in Verilog — Where Delay Lives in a Model
Once a model has delay, the first design decision is where to put it, and Verilog gives two styles. Distributed delay places a delay on every internal element, so each gate and each continuous assignment carries its own. Every internal node then has realistic timing, and the model can reproduce internal transitions, including glitches and hazards. Lumped delay collapses all of that into a single delay at the output element and treats the internal logic as instantaneous. It is simpler and faster, but it models only the input-to-output delay, not the shape of what happens inside. The choice is a trade-off between accuracy and simplicity, and it has a sharp consequence: a lumped model can hide an internal glitch that a distributed model would expose. This page drills both styles and that key difference.
Intermediate13 min readVerilogDelay ModelingDistributed DelayLumped DelayGlitch
Chapter 17 · Section 17.1 · Delay Modeling
1. The Engineering Problem
You have a small combinational block — out = (a & b) | c — and you want its simulation to behave in time, the way the real gates will. So you give it delay. But where does the delay go?
// The same logic, two different timing models:
// Option A — a delay on EVERY gate:
and #2 g1 (n1, a, b); // AND takes 2 time units
or #1 g2 (out, n1, c); // OR takes 1 time unit
// Option B — ONE delay, at the output gate only:
and g1 (n1, a, b); // internal: zero delay
or #3 g2 (out, n1, c); // everything lumped into the outputBoth models make out settle 3 time units after a change on a — so for a simple input-to-output measurement they look equivalent. But they are not the same model. Option A knows that the internal node n1 changes 2 units before out; Option B pretends n1 changes instantly. That difference is invisible until the inputs switch in a way that makes the block glitch — and then only one of the two models shows it.
There are two styles of placing delay in a module: distributed (a delay on every internal element) and lumped (one delay at the output). They agree on input-to-output delay but disagree on internal behaviour — and a lumped model can hide a glitch a distributed model would reveal.
This page is about that choice and its consequences.
2. Mental Model — Delay at Every Step vs Delay at the Exit
3. The Hardware View
The block out = (a & b) | c is two gates: an AND feeding an OR. The two delay styles differ only in where the # sits.
Visual A — distributed: delay on every element
Distributed delay — each gate carries its own
data flowVisual B — lumped: one delay at the output
Lumped delay — one delay, at the exit only
data flowBoth diagrams produce the same out arrival time (t = 3). The difference is entirely about whether n1 has a real transition time — and that is what decides glitch visibility.
4. Distributed Delay
Distributed delay places a delay on each structural element — every gate primitive or every continuous assignment.
module aoi_distributed (output out, input a, b, c);
and #2 g1 (n1, a, b); // each gate has its own delay
or #1 g2 (out, n1, c);
wire n1;
endmoduleThe dataflow form is the same idea with continuous assignments:
module aoi_distributed (output out, input a, b, c);
wire n1;
assign #2 n1 = a & b; // each assign carries a delay
assign #1 out = n1 | c;
endmoduleEvery internal node has realistic timing. n1 changes 2 units after its inputs; out changes 1 unit after n1. Because the intermediate node moves at a real time, the model reproduces the actual sequence of internal transitions — and therefore any glitch those transitions create. Distributed delay is the more faithful model.
5. Lumped Delay
Lumped delay leaves the internal elements at zero delay and places a single delay on the element that drives the module output.
module aoi_lumped (output out, input a, b, c);
and g1 (n1, a, b); // zero delay (instantaneous)
or #3 g2 (out, n1, c); // the whole block's delay, lumped here
wire n1;
endmodule module aoi_lumped (output out, input a, b, c);
wire n1;
assign n1 = a & b; // zero delay
assign #3 out = n1 | c; // single output delay
endmoduleThe internal logic is instantaneous; only the output transition is delayed. n1 changes the moment a, b change. The output then transitions 3 units later. Lumped delay is simpler to write and faster to simulate — there is only one delayed event per output change — but it models only the boundary. It is the right choice when you care about input-to-output delay and nothing about internal behaviour.
6. The Key Difference — Internal Glitch Visibility
This is the whole point. Consider the inputs switching so that the block has a static-1 hazard — the output should stay 1, but momentarily dips to 0 because one internal path is slower than another.
// out = (a & b) | c, with a transition that creates a hazard:
// start: a=1 b=1 c=0 → n1 = 1, out = 1
// change: a=1 b=1 c=1→0 AND b=1→? ... a switching path makes n1 fall
// briefly before c rises, so out momentarily sees (n1=0, c=0) = 0.
//
// DISTRIBUTED model: n1 falls at t=2, the compensating change arrives
// later → out GLITCHES low for a window, then recovers. The glitch
// is VISIBLE in the waveform.
//
// LUMPED model: n1 changes instantly, so the two internal changes line
// up at t=0 and the output simply transitions once (or not at all).
// The glitch is INVISIBLE — the model never produced it.- Distributed delay shows the glitch. Because each internal node moves at its own real time, a momentary disagreement between two paths produces a real, observable pulse on the output.
- Lumped delay hides the glitch. With zero-delay internals, the disagreeing transitions collapse to the same instant, so the hazard never forms in the model.
This is not a rounding difference — it is a difference in what class of behaviour the model can represent. A lumped model is structurally incapable of showing an internal hazard. If glitch behaviour matters (and in real timing verification it often does), you need distributed delay — or, better, the pin-to-pin path delays of 17.4 that real cell libraries use.
7. Accuracy vs Simplicity — The Trade-off
| Distributed delay | Lumped delay | |
|---|---|---|
| Delay placement | on every internal element | one delay, on the output element |
| Internal node timing | realistic (each node moves at its own time) | instantaneous (zero-delay internals) |
| Input-to-output delay | accurate | accurate |
| Internal glitches / hazards | reproduced (visible) | hidden (cannot form) |
| Simulation cost | higher (more delayed events) | lower (one delayed event per output) |
| Authoring effort | more (a number per element) | less (one number) |
| Best for | accurate timing / glitch studies | quick behavioural models, I/O-delay-only |
The headline: lumped trades internal fidelity for simplicity. It is a legitimate, useful simplification when you only need the boundary delay — but you must know what it throws away, because the thing it throws away (internal glitch behaviour) is sometimes exactly the bug you are hunting.
8. Where Each Is Used
- Lumped appears in quick behavioural models and abstract block models where only input-to-output delay matters and internal detail is deliberately omitted — a fast, coarse approximation.
- Distributed appears where internal timing matters — small structural models, hazard analysis, and any model that must reproduce the shape of internal transitions.
- Neither is how real standard cells are modelled. Production cell libraries use pin-to-pin (module path) delays in a
specifyblock (17.4), which specify the delay from each input pin to each output pin directly — more precise than either distributed or lumped, and the form that back-annotated SDF timing rides on. Distributed and lumped are the conceptual stepping stones to that model; understanding why lumped hides glitches is what makes the precision of path delays make sense.
9. Common Mistakes
- Assuming lumped and distributed are equivalent because the I/O delay matches. They agree on boundary delay but differ on internal behaviour — lumped cannot show internal glitches (§6).
- Hunting a glitch in a lumped model. If your model has zero-delay internals, the hazard you are looking for cannot form. Switch to distributed (or path) delays before concluding "no glitch."
- Over-lumping a multi-output block. Lumping at one output says nothing about the other outputs' internal timing; each output path needs its own treatment.
- Expecting any of this to synthesise. Distributed and lumped delays are simulation models — synthesis ignores them (see the Chapter 17 overview).
10. Debugging Lab
The lumped model that swore there was no glitch
11. Interview Q&A
12. Exercises
Exercise 1 — Place the delay
For out = (a | b) & c written as two gates with a total path delay of 4 units, write (a) a distributed version and (b) a lumped version. State where n1 (the internal node) transitions in each.
Exercise 2 — Predict glitch visibility
A block has a known static-1 hazard. You simulate it once with a lumped model and once with a distributed model. In which simulation does the glitch appear, and why does it not appear in the other?
Exercise 3 — Choose the model
For each scenario, pick distributed or lumped and justify in one line: (a) a quick behavioural model where only input-to-output latency matters; (b) analysing whether a decode block produces a hazard that could trigger a downstream latch; (c) the fastest-simulating model of a large block whose internals are irrelevant.
Exercise 4 — Explain the trap
A teammate says "my lumped model shows no glitch, so the circuit is safe." Explain in two sentences why that conclusion is unfounded.
13. Summary
Distributed vs lumped delay is the choice of where a model's delay lives:
- Distributed — a delay on every internal element; every internal node has real timing; reproduces internal glitches. Accurate, costlier.
- Lumped — one delay at the output; zero-delay internals; hides internal glitches. Simple, faster, boundary-only.
- They agree on input-to-output delay but differ on internal behaviour — and that difference is glitch visibility.
- Both are simulation-only (synthesis ignores them); real cells use pin-to-pin path delays (17.4), the more precise model these lead up to.
The takeaway worth keeping: a glitch-free waveform from a lumped model proves nothing — match the model's fidelity to the question you are asking.
The next sub-topic moves from where delay lives to how a pulse behaves travelling through it: Chapter 17.2 Inertial vs Transport Delay — why a narrow pulse can be silently swallowed.
Related Tutorials
- Delay Modeling — Chapter 17 overview; why timing-aware simulation exists.
- Gate Delays — Chapter 11.2; the
#delay on a primitive, the building block both styles use. - Continuous Assignments — Chapter 13.1; the
assignwhose delayed form carries distributed/lumped dataflow delay. - Predefined Gate Primitives — Chapter 11.1; the gates these delay models are attached to.