Design for Test: Scan and BIST

The wafers are back from the fab. On each one sit hundreds of copies of your chip — and, thanks to the defects we will meet in the next lesson, a good fraction of them are broken: a speck of dust shorted two wires here, a void opened a connection there. Which ones? You cannot ship them all and let customers find out. And here is the bind: a die has millions of internal wires and you can physically touch only its few hundred pads. You cannot probe internal nodes. The answer is one of the great pragmatic ideas of the industry — design for test (DFT): build the chip, from the start, so that it can be interrogated through the pins it has.

The stuck-at fault model

First, tame the question. "Is anything wrong anywhere?" is untestable; DFT replaces it with a concrete checklist: the stuck-at fault model. Assume any single internal node might be permanently stuck at 0 or stuck at 1 (as if shorted to ground or supply) — one entry per node per polarity. It is a deliberate simplification (real defects include bridges, opens, and slow transistors — richer models exist for those), but it is enumerable: a tool can list every fault, and for each one ask two things:

For deeply buried logic, both are hopeless through the functional pins alone. Which brings us to the trick.

Scan: the chip becomes its own probe

The scan idea: give every flip-flop a tiny multiplexer on its data input. One leg carries the normal functional data; the other leg connects to the previous flop's output. A single test-enable signal flips every mux at once:

In test mode the chip's million flops become one giant shift register threading the whole die. Now every test runs the same three-beat rhythm:

Every internal node is now two shift operations away from your tester. ATPG (automatic test pattern generation) exploits this: for each stuck-at fault it computes a pattern that excites the fault and steers its effect into some flop, then greedily merges patterns until a few thousand of them cover 99%+ of all faults — the quoted fault coverage.

Run a scan test

// A 4-flop circuit: next state = simple logic of current state. // n0 = q1 AND q2, n1 = q0 OR q3, n2 = NOT q3, n3 = q0 XOR q1 // Fault to hunt: the wire from q1 into the AND gate, stuck at 0. type Bits = number[]; const step = (q: Bits, q1Stuck0: boolean): Bits => { const q1 = q1Stuck0 ? 0 : q[1]; // the injected defect return [q1 & q[2], q[0] | q[3], 1 - q[3], q[0] ^ q[1]]; }; // Scan test: shift a pattern in, capture once, shift the response out. const scanTest = (pattern: Bits, faulty: boolean): Bits => { let q: Bits = [0, 0, 0, 0]; for (const bit of pattern) q = [bit, q[0], q[1], q[2]]; // shift in (4 clocks) q = step(q, faulty); // capture (1 functional clock) return q; // (shifted out, 4 clocks) }; // ATPG's chosen pattern: q1=1, q2=1 excites the fault (AND should see 1,1). const pattern: Bits = [0, 1, 1, 0]; // → q = [q0,q1,q2,q3] = [0,1,1,0] after shifting const good = scanTest(pattern, false); const bad = scanTest(pattern, true); console.log("pattern shifted in : " + pattern.join("")); console.log("good die shifts out: " + good.join("")); console.log("this die shifts out: " + bad.join("")); const diff = good.map((b, i) => (b !== bad[i] ? "^" : " ")).join(""); console.log(" " + diff + " ← the tell-tale diff"); console.log(bad.join("") === good.join("") ? "Responses match: die passes this pattern." : "Mismatch: q0 captured 0 where a good die captures 1 — stuck-at-0 caught. Reject the die.");

Notice how surgical it is: the pattern was designed so that a healthy AND gate outputs 1 and a stuck-at-0 outputs 0, and that difference lands in a flop we can read. Multiply by a few thousand patterns and every enumerable fault gets its moment in the spotlight.

Test time is money, memories test themselves, boards get scanned too

A tester (a multi-million-dollar machine) charges by the second, and a naive scan regime is slow: each pattern costs roughly a full chain-length of shifting. With p patterns, chain length n, and shift clock f, test time is about p \cdot n / f. The levers follow directly:

A chicken-and-egg puzzle: scan finds manufacturing defects by comparing a die's responses against the correct ones — but correct according to what? The answer is that ATPG simulates the golden netlist to predict every expected response; the tester is really comparing silicon against simulation. That works beautifully for fabrication defects, but notice what it can never catch: a design bug, faithfully manufactured, passes every scan pattern with flying colours — the silicon matches the netlist, bug included. That is why manufacturing test and functional verification are entirely separate disciplines: verification asks "did we design the right machine?"; test asks "did the fab build the machine we designed?". Mixing up the two questions has embarrassed more than one project review.

To a designer squeezing timing, the scan mux on every single flop looks like pure vandalism: extra delay on every data path, ~5–10% extra area, whole routing tracks spent threading chains. The temptation to "skip DFT just for this block" is real — and giving in to it is how you end up with a warehouse of chips you cannot sell. Without scan there is no way to tell good dice from bad ones at the tester; without that, you either ship defects to customers or discard entire wafers on suspicion. An untestable chip is unsellable regardless of how correct the design is. Every serious team pays the scan tax gladly, plans it from day one, and treats "scan coverage 99%+" as a tape-out gate as hard as timing closure itself.