DFT · Chapter 3 · Scan Architecture
The Scan Flip-Flop (Mux-D)
The scan flip-flop is the building block of every scan chain: an ordinary D flip-flop with a 2:1 multiplexer added on its data input, choosing between the functional data and the scan input under the scan-enable signal. When scan-enable is low the cell is in functional mode and behaves exactly like the original flop, so scan is invisible in normal operation. When scan-enable is high the cell is in shift mode and captures the scan input, which is wired to the previous cell's output, so the flops march data along a chain. Two facts matter most: the cell is functionally identical to the flop it replaced, and the added mux delays the functional data path, so static timing analysis must budget that cost on every scan flop. In practice tools swap ordinary flops for scan library cells during insertion rather than hand-writing muxes in RTL.
Foundation13 min readDFTScan Flip-FlopMux-DScan EnableLibrary Cell
Chapter 3 · Section 3.2 · Scan Architecture
Project thread — 3.1 argued for scan; here we build the mux-D scan cell and convert the project's D flip-flop into one, on the way to a scannable counter (3.6).
1. Why Should I Learn This?
The mux-D scan cell is the atom of every scan chain — and its two properties (functionally transparent; adds path delay) drive real design decisions.
- A scan flop = D flop + a 2:1 mux on the data input, selected by scan-enable (SE).
- SE=0 → functional (captures D, identical to the original flop); SE=1 → shift (captures SI from the previous cell).
- Q feeds both functional fanout and the next cell's SI.
- The mux adds delay to the functional path — a real STA cost; tools swap in a scan library cell (not RTL muxes).
2. Real Silicon Story — the timing path that broke after scan insertion
A block closed timing cleanly in synthesis. After scan insertion, a previously-comfortable path failed setup — and the team briefly suspected the insertion tool had corrupted logic.
It hadn't. Scan insertion had swapped the ordinary flop feeding that path for a mux-D scan cell, and the 2:1 mux now sat in the functional data path, adding its propagation delay ahead of the flop. On a path with little slack, that extra mux delay was enough to violate setup. The logic was functionally identical (SE=0) — the issue was purely the added mux delay that STA now had to account for.
The fix was ordinary timing work: budget the scan-cell delay, pick a faster scan flop variant, or optimize the path — not remove scan. Lesson: a mux-D scan cell is functionally transparent in mission mode but not timing-transparent — every scan flop carries a mux delay on its functional input, and STA must plan for it.
3. Factory Perspective — the scan cell through each lens
- What the test engineer sees: a loadable/observable cell — drive SE to choose shift vs capture, load stimulus via SI, read response via the chain (3.3).
- What the yield engineer sees: that a correct scan cell is what makes structural coverage (and defect sorting) possible — a broken scan cell would block a whole chain.
- What the RTL/DV engineer sees: that their flop becomes a scan library cell (a tool swap), that mission-mode behavior is unchanged, and that a mux delay now sits in their timing path.
- What management cares about: the area of the mux per flop and the timing impact — small per cell, but multiplied by every flop, so a real PPA line item weighed against coverage/DPPM (1.5).
4. Concept — the mux-D cell, its modes, and its cost
Structure:
- A 2:1 mux feeds the flop's D pin. Mux inputs: functional data (D) and scan data (SI). Mux select = SE.
- The flop's output Q drives its functional fanout and the SI of the next cell in the chain.
- Control/observe pins at chain level: scan-enable (SE), scan-in (chain head), scan-out (chain tail) (3.3).
Two modes (set by SE):
- SE = 0 → functional/mission mode: mux passes D → the cell captures functional data → behaves exactly like the original flop. Scan is invisible to functionality.
- SE = 1 → shift mode: mux passes SI → each clock shifts the previous cell's value in → the chain acts as a shift register (loads stimulus / unloads response).
The honest cost (design for it):
- Timing: the mux adds propagation delay in the functional D path of every scan flop → STA must budget it (the story). Low-slack paths feel it most.
- Area: one mux (plus scan routing) per flop — small each, meaningful in aggregate (3.1).
- Not hand-coded: in the real flow, scan insertion swaps the flop for a scan-equivalent library cell — you write ordinary RTL flops, the tool does the rest (Chapter 4).
Other styles (brief, for literacy):
- LSSD (level-sensitive scan design): master/slave latches with separate scan clocks — robust, race-free, historically used in some methodologies; more area/clocking.
- Clocked-scan: uses an extra scan clock to shift instead of a data mux — avoids the functional-path mux delay at the cost of clock complexity.
- Muxed-D dominates for its simplicity and tool support.
The same flop, in mission mode, is indistinguishable from the original:
5. Mental Model — a track switch on a railway
Picture each flop as a station, and the mux as a track switch in front of it controlled by SE.
- SE = 0 (functional): the switch routes the normal line (functional data D) into the station — trains run exactly as they always did. The switch is there, but it doesn't change the destination — only adds a tiny delay as the train crosses it.
- SE = 1 (shift): the switch routes the scan line (SI from the previous station) in — now stations pass cargo hand-to-hand down the chain (a shift register).
- The switch is invisible to normal service (mission mode is unchanged) but always adds a small crossing delay — that's the mux delay STA budgets.
- You don't build these switches by hand at each station; the rail authority (the insertion tool) installs the standard switch (the scan library cell) everywhere.
Same railway, same destinations — plus a switch that, on command, turns the network into a conveyor for loading and reading every station.
6. Working Example — the project's flop as a mux-D scan cell
Behavioral mux-D scan flop in three languages — to show structure (real flow uses a library-cell swap):
// SystemVerilog — behavioral mux-D scan flip-flop (STRUCTURE ONLY; tools swap in a scan library cell)
module scan_dff (
input logic clk, rst_n,
input logic d, // functional data
input logic si, // scan data (from previous cell)
input logic se, // scan-enable: 0=functional, 1=shift
output logic q
);
always_ff @(posedge clk or negedge rst_n)
if (!rst_n) q <= 1'b0;
else q <= se ? si : d; // the 2:1 mux: SE selects SI (shift) vs D (functional)
endmodule// Verilog-2001 — same behavioral scan flop
module scan_dff (clk, rst_n, d, si, se, q);
input clk, rst_n, d, si, se; output reg q;
always @(posedge clk or negedge rst_n)
if (!rst_n) q <= 1'b0;
else q <= se ? si : d; // SE=1 -> shift (si), SE=0 -> functional (d)
endmodule-- VHDL — same behavioral scan flop
library ieee; use ieee.std_logic_1164.all;
entity scan_dff is
port (clk, rst_n, d, si, se : in std_logic; q : out std_logic);
end entity;
architecture rtl of scan_dff is signal q_i : std_logic; begin
process (clk, rst_n) begin
if rst_n = '0' then q_i <= '0';
elsif rising_edge(clk) then
if se = '1' then q_i <= si; -- shift mode
else q_i <= d; -- functional mode
end if;
end if;
end process;
q <= q_i;
end architecture;# What the flow ACTUALLY does — REPRESENTATIVE, tool-neutral:
# You write an ORDINARY flop: always_ff @(posedge clk) q <= d;
# Scan insertion (Ch4) SWAPS it for a scan library cell 'SDFFR' (or similar) with pins D, SI, SE, Q, CLK, RN.
# -> you do NOT hand-code the mux; the library cell contains it. SE=0 keeps mission behavior identical.
# COST: SDFF's D->Q setup path includes the internal mux delay -> STA budgets it on every scan flop.The waveform shows SE choosing which input the flop captures:
SE=0 captures D (functional); SE=1 captures SI (shift)
8 cycles7. Industry Flow — where the scan cell comes from
The scan cell enters the flow as a library-cell swap, then is timed and routed:
8. Debugging Session — a path fails setup after scan insertion
A path that closed timing in synthesis fails setup after scan insertion, and the team suspects the tool corrupted the logic; in fact the ordinary flop was swapped for a mux-D scan cell whose 2:1 mux now sits in the functional data path and adds delay -- the logic is functionally identical (SE=0), so the fix is to budget or optimize the added mux delay, never to remove scan
SCAN CELL IS FUNCTIONALLY TRANSPARENT BUT NOT TIMING-TRANSPARENT (MUX DELAY)A path that closed timing before scan insertion now fails setup. The RTL didn't change. Someone suspects scan insertion broke the logic and wants to skip scan on that flop.
Scan insertion replaced the ordinary flop with a mux-D scan cell, and the 2:1 mux now sits in the functional data path, adding its propagation delay — the logic is unchanged, but the timing is not. In mission mode SE = 0, so the mux passes D and the cell computes exactly what the original flop did — there is no functional change (that's the whole design intent of muxed-D scan). But the mux is physically present on the data path into the flop, so the D→Q setup path now includes the mux delay on top of the original logic delay. On a path that had little slack, that extra delay is enough to violate setup. This is not a tool bug and not a reason to remove scan: it's the expected, universal cost of muxed-D scan — every scan flop carries this mux delay on its functional input, and STA must budget it. (If you did remove scan from that flop, you'd re-create the untestable embedded state of 2.6 to 'fix' a routine timing path — a bad trade.)
Treat it as ordinary timing closure on the scan-cell delay — budget it, use a faster scan cell, or optimize the path — and keep scan. Options, in rough order: (1) re-optimize the path (resize/restructure logic, better placement) to recover the slack the mux consumed; (2) choose a faster scan-flop variant from the library (lower mux delay) for timing-critical flops; (3) budget the scan-cell delay explicitly in constraints so synthesis/STA plan for it from the start rather than discovering it late. What you do not do is delete the scan cell to pass timing — that reintroduces untestable state. The principle to lock in: a mux-D scan flip-flop is functionally identical to the original flop in mission mode (SE=0) but adds a real mux delay to the functional data path on every scan flop, so scan is functionally transparent yet not timing-transparent — plan for the per-flop mux delay in STA and close timing normally, never by removing scan. (Timing-aware scan handling is refined in Chapter 4; STA fundamentals live in the STA track.)
9. Common Mistakes
- Assuming scan changes functionality. At SE=0 the cell is identical to the original flop — mission behavior is unchanged.
- Forgetting the mux delay. Every scan flop adds a functional-path mux delay — STA must budget it.
- Hand-coding scan muxes in RTL. Write ordinary flops; the tool swaps in a scan library cell (Ch4).
- Removing scan to fix timing. That re-creates untestable state (2.6) — fix the path, keep the scan cell.
- Ignoring SE as a real signal. Scan-enable is a global control with its own timing/routing needs (3.4).
10. Industry Best Practices
- Use the library scan cell (muxed-D
SDFF) via scan insertion — don't hand-build muxes. - Budget the scan-cell mux delay in timing constraints from the start.
- Keep mission behavior identical — verify SE=0 equals the original flop.
- Pick faster scan variants for timing-critical flops when needed.
- Plan SE distribution — it's a global, timing-sensitive control (buffering, skew) (3.4).
11. Senior Engineer Thinking
- Beginner: "Scan insertion broke my timing — turn scan off on that flop."
- Senior: "The scan cell is functionally identical at SE=0 — nothing broke. The mux just added delay on the D path, and that path had thin slack. I budget the scan-cell delay, use a faster variant, or optimize the path — I don't delete scan and re-create untestable state. Scan is functionally transparent, not timing transparent."
The senior separates functional transparency (yes) from timing transparency (no) and closes timing with scan intact.
12. Silicon Impact
The mux-D scan cell is where scan's grand promise (3.1) meets physical reality. Its genius is functional transparency: at SE=0 it is bit-for-bit the original flop, so adding scan to a design doesn't change what the design does — a property that makes full-scan adoption safe and verification straightforward. Its cost is equally concrete: a mux in the functional data path of every scan flop, which adds area and, more importantly, timing — and because it's on every flop, it's a systematic budget item that STA and synthesis must plan for, not a surprise to discover at signoff. The single most common real-world consequence is exactly the story's: a thin-slack path fails setup after insertion, and the correct response is timing closure (budget / faster cell / optimize), never removing scan (which reintroduces the untestable embedded state of 2.6). The practical-flow insight — tools swap ordinary flops for scan library cells, you don't hand-code muxes — is what keeps RTL clean and lets DFT be applied uniformly and late-bindingly. For the RTL/DV engineer, the takeaways are direct: design with a little slack so the per-flop mux delay is absorbed, trust that mission behavior is unchanged, and understand that this humble one-mux cell, multiplied across every flop, is what physically delivers the controllability and observability that make ATPG, coverage, and the DPPM commitment (1.5) possible.
13. Engineering Checklist
- Used the muxed-D scan library cell via scan insertion (no hand-coded muxes).
- Budgeted the mux delay on the functional path in timing constraints.
- Verified mission-mode (SE=0) behavior is identical to the original flop.
- Reserved faster scan variants for timing-critical flops.
- Planned SE (scan-enable) distribution as a global, timing-sensitive control (3.4).
14. Try Yourself
- Draw the mux-D scan cell: a 2:1 mux (D, SI) selected by SE feeding a flop; label Q → next SI.
- Trace SE=0 (captures D — original behavior) and SE=1 (captures SI — shift) over a few clocks.
- From the tri-HDL, confirm the only structural addition is the mux (
se ? si : d). - Explain why a thin-slack functional path may fail setup after the swap — and list three fixes that keep scan.
- Note why you'd not hand-code the mux in RTL — the library-cell swap does it (Chapter 4).
Structure is tool-neutral. Real scan cells come from the standard-cell library; swaps happen in scan insertion (Chapter 4). No paid tool required.
15. Interview Perspective
- Weak: "A scan flop has an extra input to shift data in."
- Good: "It's a D flop with a mux choosing functional data or scan data, controlled by scan-enable."
- Senior: "A muxed-D scan flop is an ordinary D flop with a 2:1 mux on its data input selecting functional D vs scan SI under scan-enable (SE). SE=0 is mission mode — it captures D and is functionally identical to the original flop, so scan doesn't change behavior. SE=1 is shift mode — it captures SI from the previous cell, and Q feeds the next cell's SI, forming a shift register. Two costs: the mux adds delay to the functional path on every scan flop, which STA must budget, and there's a small area hit. In practice you don't hand-code it — scan insertion swaps each flop for a scan library cell. Other styles exist — LSSD, clocked-scan — but muxed-D dominates."
16. Interview / Review Questions
17. Key Takeaways
- A scan flip-flop is an ordinary D flop + a 2:1 mux on its data input, selecting functional data (D) vs scan data (SI) under scan-enable (SE) — the muxed-D style dominates (LSSD and clocked-scan are variants).
- SE=0 → functional mode: the cell captures D and is functionally identical to the original flop — scan is invisible to what the design does.
- SE=1 → shift mode: the cell captures SI from the previous cell, and Q feeds the next cell's SI, forming a shift register (the chain, 3.3).
- The mux is functionally transparent but not timing-transparent — it adds a real delay to the functional data path on every scan flop, so STA must budget it; fix timing by optimizing the path, never by removing scan.
- In the real flow you don't hand-code scan muxes — scan insertion swaps each ordinary flop for a scan library cell (Chapter 4). Next: 3.3 — scan chains: shift in, capture, shift out.
18. Quick Revision
The mux-D scan flip-flop. = D flop + 2:1 mux on the data input, selected by scan-enable (SE). SE=0 → functional mode (captures D, IDENTICAL to the original flop — scan invisible). SE=1 → shift mode (captures SI = previous cell's Q). Q feeds functional fanout AND the next cell's SI. Functionally transparent, NOT timing-transparent: the mux adds delay on the functional path of EVERY scan flop → STA must budget it (fix timing by optimizing the path, never by removing scan). You DON'T hand-code muxes — scan insertion swaps in a scan library cell (Ch4). Variants: LSSD, clocked-scan. Next: 3.3 — scan chains.