Skip to content

DFT · Chapter 13 · DFT Debug Methodology

Debugging Scan-Chain Failures

This is the first debug you run, because a broken chain makes every pattern miscompare and you can burn days chasing a bug that is not there. Before debugging patterns or logic, answer one question: is the chain itself good? The tool is the chain-integrity or flush test, which shifts a known pattern such as alternating ones and zeros in and observes it coming out delayed by the chain length. In equals out means the chain is good and you have license to debug patterns; a mismatch means it is broken. Signatures tell you the mode: a stuck chain gives a constant output, an open chain leaves everything downstream dead, and a timing chain fails at fast shift but passes slow. Because the chain is an ordered shift register, counting the good bits locates the last good cell. Always verify clocks and resets in shift mode first.

Intermediate14 min readDFTScan ChainFlush TestDebugLocalization

Chapter 13 · Section 13.2 · DFT Debug Methodology

Project thread — the mini-SoC's scan chain: flush it first, read the signature, localize the break by counting. A good flush licenses the pattern debug of 13.3.

1. Why Should I Learn This?

Scan-chain debug is the first and most leverage-rich debug — a dead chain fails every pattern, so flushing first saves you from chasing phantom logic bugs.

  • The flush test: shift a known pattern in, observe it out (delayed)In=Out = GOOD, mismatch = BROKEN.
  • Signatures: stuck = constant out; open = downstream dead; timing = fails fast / passes slow (hold, 12.2); clock/reset = looks like a break.
  • Localize by counting — the cell position of the break maps to a physical cell/net (last-good cell).
  • A good flush is the license to debug patterns — fix the chain first, or everything else is noise.

2. Real Silicon Story — three days chasing a bug that wasn't there

A team saw every scan pattern miscompare on one chain of a new part. They assumed a logic defect and spent three days debugging individual patterns, poring over failing bits and ATPG values.

The chain was broken. A 30-second flush test — shift 0011… in, watch the output — would have shown a constant output (the chain was stuck), meaning no pattern could ever pass and the pattern debug was pointless. When they finally flushed, they counted to the stuck cell and found the cause: a clock-gating cell whose shift clock enable was left OFF in shift mode (11.x), so that cell never clocked and held its value — killing the chain from that point. They fixed the shift-clock enable (a 12.5 shift-run issue), the flush passed, and the patterns then debugged normally (most passed). Lesson: flush first. A broken chain fails every pattern, so structure before function (13.1) is not optional — a good flush is the license to debug patterns, and localization is just counting to the cell where the flush breaks.

3. Factory Perspective — chain debug through each lens

  • What the test/DFT engineer sees: the flush test as step zero — read the signature (stuck/open/timing), localize by counting, and only then debug patterns.
  • What the physical engineer sees: the chain route/order and the cell the count points to — an open/short or a clock issue at a specific instance.
  • What the STA engineer sees: the shift-mode timing (a timing chain = a hold violation, 12.2/12.5) or a shift clock gated off (11.x).
  • What management cares about: that the team doesn't waste days on phantom logic bugs — a 30-second flush protects schedule and points at the real break.

4. Concept — the flush test, signatures, and counting

The flush (chain-integrity) test:

  • Shift a known pattern — e.g. 0011 0011… or a walking 1/0in at scan-in; observe it at scan-out, delayed by the chain length.
  • In = Out (delayed) → chain GOOD. In ≠ Out → chain BROKEN. This is the first test on any device and the first debug step for any scan failure.

Failure signatures (read the output):

  • STUCK chain (stuck-at-0/1 somewhere): output is a constant (all 0 / all 1) regardless of input → the stuck bit position localizes the bad cell.
  • OPEN/BROKEN chain: pattern doesn't propagate past a pointdownstream reads constant/garbage, upstream is fine → the transition point localizes the break.
  • SLOW/TIMING chain: flushes at slow shift, fails at fast shift → a HOLD violation between adjacent cells (12.2 shift=hold) or a missing lock-up latch (4.x) → data races through / double-clocks; intermittent / at-speed, passes slow.
  • SHORTED/INVERTED/CLOCK: a bridge, an odd inversion in the path, or a cell not clocked (its shift clock gated off, 11.x, or an async reset firing in shift) → each has a distinct flush signature; a not-clocked cell holds its value.

Localization = counting:

  • A chain is an ordered shift register, so the cell position where the flush breaks maps to a physical cell/net.
  • Count the good bits before the break → that's the last-good cell → the break is at/after it. Chain-diagnosis tools automate this.

Clocks/resets as chain killers:

  • A cell whose shift clock is gated off in shift (11.x ICG/test-clock), or an async reset firing in shift, corrupts the chain and looks like a break.
  • Verify clocks/resets in SHIFT mode (12.5 shift run) before blaming the cell.

The rule:

  • A good flush is the license to debug patterns. If the flush fails, everything else is noisefix the chain first. Multiple chains → flush each; the failing chain is isolated.

Flush: shift 0011… in, observe it out (delayed) = GOOD; a stuck chain = constant out

8 cycles
A known flush pattern shifted into the chain appears at the output delayed by the chain length when good, but a stuck chain outputs a constant regardless of the input patternGOOD: input appears at output, delayed by chain lengthGOOD: input appears at…STUCK: output constant regardless of inputSTUCK: output constant…shift_clk10101010101010101010scan_inscan_out (GOOD)scan_out (STUCK)t0t1t2t3t4t5t6t7
Figure 1 - the chain-integrity (flush) test and its signatures (representative). Shift a KNOWN pattern (e.g. 0011 0011) IN at scan-in and observe it OUT at scan-out, DELAYED by the chain length. In = Out (delayed) -> chain GOOD (license to debug patterns). A STUCK chain outputs a CONSTANT (all 0/1) regardless of input -> the stuck bit position localizes the bad cell. A BROKEN/OPEN chain propagates fine UPSTREAM of a break but reads garbage/constant DOWNSTREAM -> the transition point localizes the break. A TIMING chain flushes SLOW but fails FAST (a hold violation / missing lock-up, 12.2/4.x). A CLOCK-off cell holds its value (looks like a break).

5. Mental Model — testing a garden hose before blaming the sprinkler

Debugging a scan chain is like testing a garden hose before you blame the sprinkler for not spraying.

  • The hose is the chain; the water you push in is the flush pattern; the water out the end is the scan-out. If you push water in one end and the same water comes out the other (delayed by the hose length), the hose is good — now you can debug the sprinkler (the patterns/logic).
  • If nothing comes out, or a constant trickle no matter what you push, the hose is blocked or cut — debugging the sprinkler is pointless. A constant output is a kink that's fully shut (stuck); water coming out fine up to a point then nothing is a cut at that point (open) — and you localize by walking the hose to where the flow stops (counting to the last-good cell).
  • A hose that works at low pressure but bursts at high pressure is a timing chain (fine slow, fails fast — a hold issue). And a valve someone left shut (a gated shift clock) blocks flow just like a cut — check the valves (clocks/resets in shift) before you replace the hose.

Test the hose (flush the chain) before blaming the sprinkler (patterns) — a constant/no output means a blockage or cut; walk the hose to localize; check the shut valves (clocks) too.

6. Working Example — flush, classify, localize by counting

Trace a flush and localize the break:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
# Scan-chain flush + localization - REPRESENTATIVE, tool-neutral:
  FLUSH: shift a known pattern IN, observe OUT (delayed by chain length N)
    scan_in  : 0 0 1 1 0 0 1 1 ...
    scan_out : ......  0 0 1 1 0 0 1 1   (delayed by N)  -> In = Out  -> CHAIN GOOD -> license to debug patterns
  --- if BROKEN, classify by signature ---
    scan_out = 0 0 0 0 0 0 ...  (constant, any input)         -> STUCK chain (stuck-at-0) ; stuck-bit position -> bad cell
    scan_out good for first k bits then garbage/constant       -> OPEN chain ; break AT/after cell k (count the good bits)
    flush OK at SLOW shift, corrupts at FAST shift             -> TIMING chain ; hold violation / missing lock-up (12.2/4.x)
    one bit inverted vs expected everywhere                    -> INVERTED path segment
  --- LOCALIZE by COUNTING (ordered shift register) ---
    count GOOD bits before the break = position of LAST-GOOD cell -> the break is at/after it -> map to physical cell/net
  --- CLOCK/RESET check (chain killers) ---
    a cell whose SHIFT clock is gated OFF (11.x) holds its value -> looks like a break ; an async reset firing in shift corrupts
    -> verify clocks/resets in the SHIFT run (12.5) BEFORE blaming the cell
  RULE: a good FLUSH is the LICENSE to debug patterns ; if flush fails, EVERYTHING else is noise -> fix the chain first.

A break at cell k kills everything downstream while upstream stays good — so counting localizes it:

The scan chain is an ordered shift register; a break at cell k leaves upstream cells flushing correctly and downstream cells reading garbage, so counting good bits localizes the break to cell kscan-inflush pattern enterscells 1..k-1 (GOOD)flush correctly → last-good= k-1cell k: BREAKstuck / open / clock-off /resetcells k..N (DEAD)constant/garbage downstreamLocalize by countinggood bits before break →the cell/netCheck clocks/resetsfirstgated shift clock / asyncreset looks like a break(12.5)12
Figure 2 - localizing a chain break by counting (representative). The chain is an ORDERED shift register: scan-in -> cell 1 -> cell 2 -> ... -> cell N -> scan-out. A break at cell k means every cell UPSTREAM (1..k-1) flushes correctly but everything DOWNSTREAM (k..N) reads a constant/garbage. Counting the GOOD bits before the break gives the LAST-GOOD cell (k-1), so the break is AT/after cell k -> map that position to a physical cell/net. A gated shift clock or async reset at a cell produces the same 'looks-broken' signature -> check clocks/resets in the shift run first (12.5).

7. Industry Flow — flush first, then branch

The flow branches on the flush: a good flush licenses pattern debug; a bad flush is classified, localized, and fixed:

Flush each chain first; a good flush licenses pattern debug, while a bad flush is classified by signature, localized by counting, checked for clock and reset issues, and fixed before re-flushingFlush each chain → good? debug patterns : bad? classify → localize → check clocks → fix → re-flushFlush each chain → good? debug patterns : bad? classify → localize → check clocks → fix → re-flush1Flush each chainshift a known pattern in/out2GOOD flushlicense to debug PATTERNS (13.3)3BAD: classify signaturestuck / open / timing / clock-off4Localize by countinggood bits → last-good cell → net/cell5Check clocks/resets → fixshift run (12.5) → re-flush
Figure 3 - scan-chain debug flow (representative). (1) FLUSH each chain (shift a known pattern in/out). (2) GOOD flush? -> the chain is the license to debug PATTERNS (13.3). (3) BAD flush? -> CLASSIFY the signature (stuck=constant / open=downstream-dead / timing=fails-fast / clock-off) -> LOCALIZE by counting to the last-good cell -> CHECK clocks/resets in the shift run (12.5) -> FIX the chain -> re-flush. Only a GOOD flush unlocks pattern/logic debug. With multiple chains, flush each; the failing chain is isolated.

8. Debugging Session — every pattern fails on one chain

1

Every scan pattern miscompares on one chain of a new part, and the team spends three days debugging individual patterns assuming a logic defect, but a simple flush test shows the chain outputs a constant regardless of input, meaning the chain is stuck and no pattern could ever pass -- counting to the stuck cell reveals a clock-gating cell whose shift clock enable was left off in shift mode so it never clocks and holds its value, and the fix is to enable the shift clock in shift mode, after which the flush passes and the patterns debug normally

FLUSH FIRST — A BROKEN CHAIN FAILS EVERY PATTERN, SO VERIFY THE CHAIN BEFORE DEBUGGING PATTERNS OR LOGIC
Symptom

Every scan pattern miscompares on one chain of a new part. The team assumes a logic defect and spends three days debugging individual patterns — poring over failing bits and ATPG values. No pattern passes. Logic bug, or something else?

Root Cause

The chain is broken, not the logic: a flush test shows the chain outputs a constant regardless of input (a stuck chain), so no pattern could ever pass — and counting to the stuck cell reveals a clock-gating cell whose shift clock enable was left off in shift mode, so it never clocks and holds its value, killing the chain from that point. This is the structure-before-function lesson made concrete (13.1): the chain is the delivery mechanism for every pattern, so if the chain is dead, all patterns miscompare — and debugging individual patterns is chasing a logic bug that doesn't exist. A 30-second flush — shift 0011… in, watch scan-out — would have shown a constant output immediately, the signature of a STUCK chain. The localization is counting: the chain is an ordered shift register, so counting the good bits before the constant points to the exact cell where the chain dies. Here the count lands on a clock-gating cell (ICG) whose shift-mode clock enable was left OFF (an 11.x test-control / 12.5 shift-run issue): with its clock gated off in shift, that cell never captures the shifting data — it holds its value, so everything downstream reads a constant and the flush fails. It's not a logic defect and not the patterns — it's a chain infrastructure break that made every pattern noise.

Fix

Flush first and fix the chain: recognize the constant-output stuck signature, localize the stuck cell by counting, find the clock-gating cell with its shift clock disabled, enable the shift clock in shift mode, then re-flush — after which the flush passes and the patterns debug normally. The immediate correction to the process is to run the flush before any pattern debug: a known pattern in, observe out; In=Out (delayed) licenses pattern debug, a constant out says STUCK and stops the pattern chase. Then localize by counting to the stuck cell, and check clocks/resets in the shift run (12.5) — which reveals the clock-gating cell whose shift-mode enable was off. Enable the shift clock for that cell in shift mode (ensure the ICG passes the shift clock when scan_enable/test_mode is active, 11.x), re-flush to confirm In=Out, and then debug patterns — most of which now pass (the "failures" were the dead chain). The principle to lock in: a scan chain is the ordered delivery mechanism for every pattern, so a broken chain makes every pattern miscompare — which means you must flush first (structure before function): shift a known pattern in and observe it out, where in-equals-out (delayed by the chain length) is the license to debug patterns and a mismatch stops you cold; read the signature (a stuck chain outputs a constant, an open chain kills everything downstream of a break, a timing chain fails fast but passes slow from a hold violation or missing lock-up, and a cell whose shift clock is gated off or whose async reset fires in shift looks like a break), localize by counting the good bits to the last-good cell, and verify clocks and resets in the shift run before blaming the cell — because three days debugging patterns on a chain that a thirty-second flush would have shown dead is the classic, avoidable DFT-debug waste. (Structure-before-function is 13.1; shift=hold and the shift run are 12.2/12.5; test clocks/ICG are 11.x; lock-up latches are 4.x; pattern debug on a good chain is 13.3.)

9. Common Mistakes

  • Debugging patterns before flushing. A dead chain fails every patternflush first (structure before function, 13.1).
  • Ignoring the signature. Constant = stuck; downstream-dead = open; fast-fail/slow-pass = timing (12.2) — each localizes differently.
  • Not counting to localize. The cell position of the break maps to a physical cell — count the good bits.
  • Blaming the cell before checking clocks/resets. A gated shift clock or async reset in shift looks like a break (12.5).
  • Not flushing each chain. With multiple chains, flush each to isolate the failing one.

10. Industry Best Practices

  • Flush every chain first — a known pattern in/out — as step zero of any scan debug.
  • Read the signature (stuck/open/timing/clock) to classify the failure before localizing.
  • Localize by counting the good bits to the last-good cell; use chain-diagnosis tools.
  • Verify shift-mode clocks/resets (12.5) before blaming a cell — they're common chain killers.
  • Only debug patterns on a good flush — the flush is the license.

11. Senior Engineer Thinking

  • Beginner: "Every pattern fails on this chain — must be a big logic bug; let me debug the patterns."
  • Senior: "Every pattern failing on one chain smells like a dead chain, not logic. Flush first: a constant output = stuck. I count the good bits to the stuck cell, and I check shift-mode clocks/resets before blaming the cell — often it's a gated shift clock (11.x). Fix the chain, re-flush, then debug patterns. A good flush is the license to debug patterns."

The senior flushes first, reads the signature, and localizes by counting — never debugging patterns on an unverified chain.

12. Silicon Impact

Scan-chain debug is the highest-leverage step in the entire debug chapter, because the chain is the delivery mechanism for every pattern — so its health gates the meaning of everything downstream. The governing insight, inherited from structure before function (13.1), is blunt: a broken chain makes every pattern miscompare, so debugging patterns or logic on a dead chain is chasing a bug that doesn't exist — the classic, avoidable DFT waste (three days on a chain a 30-second flush would have shown dead). The flush (chain-integrity) test is the antidote: shift a known pattern in and observe it out, delayed by the chain lengthIn=Out is the license to debug patterns, and a mismatch stops you cold. Crucially, a chain fails in readable signatures: a STUCK chain outputs a constant regardless of input (the stuck bit localizes the cell); an OPEN chain kills everything downstream of a break while upstream stays good (the transition point localizes it); a TIMING chain flushes slow but fails fast — the HOLD violation between adjacent cells or a missing lock-up latch (12.2 shift=hold, 4.x); and a cell whose shift clock is gated off (11.x) or whose async reset fires in shift looks like a break — so you verify clocks/resets in the shift run (12.5) before blaming the cell. Because a chain is an ordered shift register, localization is counting: the cell position where the flush breaks maps to a physical cell/net — count the good bits to the last-good cell and the break is at or after it (chain-diagnosis tools automate this). For the test/DFT engineer, the flush is step zero; for the physical engineer, the count points at the exact instance (an open, a short, a clock issue); for the STA engineer, a timing chain is a shift-mode hold problem (12.2/12.5); and for the whole program, the discipline protects schedule by ending phantom-logic-bug chases. The rule that makes it all work is the one to carry into 13.3: a good flush is the license to debug patterns — with multiple chains, flush each to isolate the failing one, then start pattern debug (13.3) from a chain you know is good, so the failures you see there are real logic/pattern issues, not a dead chain masquerading as a thousand bugs.

13. Engineering Checklist

  • Flushed every chain first — known pattern in/out; In=Out (delayed) = good.
  • Classified the signature — stuck (constant) / open (downstream-dead) / timing (fast-fail) / clock (looks-broken).
  • Localized by counting the good bits to the last-good cell; mapped to a physical cell/net.
  • Verified shift-mode clocks/resets (12.5) before blaming a cell.
  • Only debugged patterns on a good flush — the flush is the license (13.3).

14. Try Yourself

  1. Describe the flush test and what In=Out (delayed) vs a mismatch tells you.
  2. Give the flush signatures for stuck, open, timing, and clock-off chains — and how each localizes.
  3. Localize a break by counting: given the flush good for the first k bits then constant, where's the break?
  4. Explain why a gated shift clock or an async reset in shift looks like a break (12.5) — and how to check.
  5. State the rule: a good flush is the license to debug patterns — and why you flush each chain.

The flush/localization reasoning is tool-neutral; the flush runs on the ATE, chain diagnosis is a DFT tool. No paid tool required to reason about chain debug.

15. Interview Perspective

  • Weak: "If scan fails, I look at which patterns fail."
  • Good: "I flush the chain first — shift a known pattern in and out; if it doesn't match, the chain is broken before I debug patterns."
  • Senior: "The chain delivers every pattern, so a broken chain fails all of themstructure before function: I flush first. A known pattern in, observe out delayedIn=Out licenses pattern debug, a mismatch stops me. I read the signature: constant out = stuck, downstream-dead = open, fails-fast/passes-slow = a timing (hold) chain (12.2), and a gated shift clock or async reset in shift looks like a break. Then I localize by counting the good bits to the last-good cell — the chain is an ordered shift register, so the position maps to a physical cell. I verify shift-mode clocks/resets (12.5) before blaming the cell. A good flush is the license to debug patterns — and I flush each chain to isolate the failing one."

16. Interview / Review Questions

17. Key Takeaways

  • A broken chain makes every pattern miscompare — so flush first (structure before function, 13.1): shift a known pattern in, observe it out (delayed)In=Out = GOOD (license to debug patterns), mismatch = BROKEN (fix the chain first).
  • Read the signature: STUCK = constant output; OPEN = downstream dead / upstream good; TIMING = fails fast, passes slow (a hold violation / missing lock-up, 12.2/4.x); CLOCK/RESET off = looks like a break.
  • Localize by counting — the chain is an ordered shift register, so the cell position of the break maps to a physical cell/net (count the good bits to the last-good cell).
  • Verify shift-mode clocks/resets (12.5) before blaming a cell — a gated shift clock (11.x) or async reset in shift is a common chain killer that mimics a break.
  • A good flush is the license to debug patterns — with multiple chains, flush each to isolate the failing one, then move to pattern debug. Next: 13.3 — debugging pattern mismatches.

18. Quick Revision

Debugging scan-chain failures. A broken chain fails EVERY pattern → FLUSH FIRST (structure before function, 13.1): shift a KNOWN pattern IN, observe OUT (delayed by chain length). In=Out → GOOD (license to debug patterns) ; mismatch → BROKEN. Signatures: STUCK = constant out (any input) ; OPEN = upstream good, downstream dead ; TIMING = flushes SLOW, fails FAST (hold / missing lock-up, 12.2/4.x) ; CLOCK-off cell holds value / async reset in shift = looks broken. Localize by COUNTING good bits → last-good cell → map to physical cell/net (ordered shift register). Check shift-mode clocks/resets (12.5) BEFORE blaming the cell. Multiple chains → flush EACH, isolate the failing one. A good flush = the license to debug patterns. Next: 13.3 — pattern mismatches.