Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • RTL Foundations36
  • Combinational Design25
  • Sequential Design27
  • FSM & Control27
  • Timing & Clocking39
  • Reset & CDC34
  • Memory & Buses57
  • Advanced RTL28
  • Senior & Interview76
    • Low-Power RTL Hub
    • DFT and Scan Hub
      • Why scan exists
      • The scan chain at RTL abstraction
      • Test-mode integration checklist
      • Controllability and observability in practice
      • Fault Coverage by Hand
    • Physical Awareness Hub
    • Waveform Debug Hub
    • STA and ECO Hub
    • RTL-to-Implementation Closure
    • DFT-Ready RTL
    • Capstone: Resilient Streaming Peripheral
    • Principal Design Review
    • Senior RTL Interview Questions & Model Answers
  • Glossary and Notation
Loading lesson

‹DFT and Scan Hub
  1. Topics
  2. RTL Design
  3. Senior & Interview
  4. DFT and Scan Hub
  5. The scan chain at RTL abstraction

Part 9 · Senior · Senior

The scan chain at RTL abstraction

One muxed-D flop repeated four times, with shift, capture, and shift-out proven in simulation.

On this page

    Why this matters

    Sample the scan output after the shift edge instead of before it and you read the next bit. Every scan operation is the same three steps, and the cycle count comes from the chain length.

    After this lesson you can: build a scan flop and a four-flop chain, follow shift, capture and shift-out, and estimate the time of a scan operation.

    One scan flop

    A scan flop is a D flop with a 2:1 mux on its input. When scan_en is high the flop shifts; when low it captures functional data.

    The scan-out so follows q combinationally so the next flop in the chain sees it within the same cycle.

    scan_ff.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    `timescale 1ns/1ps
    module scan_ff (
      input  logic clk,
      input  logic rst_n,
      input  logic scan_en,
      input  logic d,
      input  logic si,
      output logic q,
      output logic so
    );
      logic d_mux;
      assign d_mux = scan_en ? si : d;
      assign so    = q;
    
      always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n)
          q <= 1'b0;
        else
          q <= d_mux;
      end
    endmodule

    Four flops, one chain

    Four flops stitch so to si down the row. The first flop shifts in from the pin; the last shifts out to the pin.

    Watch so: it stays 0 while the chain fills, then shows the first bit shifted in.

    • Slot 1: rst_n is 0, so the chain is in reset and so is 0.

    • Slot 2: reset is released and the first bit 1 shifts into bit 0; so is still 0.

    • Slot 3: the second bit 0 shifts in; so is still 0.

    • Slot 4: the third bit 1 shifts in; so is still 0.

    • Slot 5: the fourth bit 1 shifts in, the chain holds 1011, and the first bit reaches so.

    • Slot 6: scan_en is 0, so functional data 0100 is captured and so is 0.

    • Slot 7: scan_en is 1 again, the captured word shifts out, and so is 1.

    Shift, capture, shift out

    A full round on the four-flop chain: shift in 0,0,1,1, capture the logic once, then shift the answer out. The capture cone is n = q1 & q0, wired into q3, so the fault-free answer is 1000.

    Each slot is one clock cycle, numbered from 0, sampled just after the rising edge; q is shown as q3 q2 q1 q0 in hex.

    • Slots 1 to 4 (shift in): scan_en is 1 and each edge moves si one place up the chain. After slot 4, q is 3 (0011): the first bit shifted in has reached q3.

    • Slot 5 (capture): scan_en is 0 for one edge, so every flop loads its functional input. q1 & q0 = 1 lands in q3, so q is 8 (1000) and so shows the first answer bit, 1.

    • Slots 6 to 8 (shift out): scan_en is 1 again and so reads 0, 0, 0. The serial answer is 1,0,0,0, q3 first.

    • The fault: with n stuck at 0, the capture in slot 5 would load 0000 and so would stay 0 in slot 5. That first bit is where the tester sees the defect.

    Fault experiment (illustrative)

    Good circuit

    n stuck at 0

    Shift 0,0,1,1 into q0-to-q3 chain

    q=0011

    q=0011

    Activate: n=q[1]&q[0]

    n=1

    n=0

    Propagate: d={n,3'b000}

    d=1000

    d=0000

    Capture with scan_en=0

    q=1000

    q=0000

    Sample so before each of four shift edges

    1,0,0,0

    0,0,0,0: first serial bit mismatches

    The bench injects this one stuck-at defect at the capture input. A zero activation pattern would not distinguish these circuits.

    Every scan operation is the same three steps. The testbench below performs one full round.

    Step

    scan_en

    What happens

    Cycles for 4 flops

    Shift in

    1

    Each edge moves one bit down the chain

    4

    Capture

    0

    One edge loads functional data into every flop

    1

    Shift out

    1

    Each edge presents the next answer bit on so

    4

    Try it: step a scan round

    The stepper starts on the first waveform's pattern: shift in 1,0,1,1, capture once with every flop's functional input set to NOT q, then shift the answer out while zeros shift in.

    Scan chain stepper

    Loading scan chain stepper…

    si enters q0 and so is q3. Four shift edges load the pattern, one edge with scan_en = 0 captures, and four shift edges unload the answer, q3 first.
    • Step four times: the chain holds 1011 (q3 q2 q1 q0) and so is already 1. One more step captures 0100, the bitwise NOT.

    • Run to the end: sampled before each unload edge, so reads 0, 1, 0, 0, which is the captured word with q3 first.

    • Set the fault to q2's d stuck at 0: the capture loads 0000 and the second bit out mismatches. Switch the logic to and-pair and the same fault goes unseen, because q2 AND q3 is 0 for this pattern.

    Common mistakes

    Production stitching order comes from scan insertion; the explicit RTL chain below fixes q0 to q3. The first serial bit in reaches q3 first and is therefore first out when a loaded vector is shifted out without capture. Sample so before each shift edge, or immediately before that edge's register updates; sampling after the shift sees the next bit. Functional capture replaces the loaded vector, so its response has its own ordering.

    Common pitfall

    A glitchy scan_en corrupts the whole vector, because every flop samples the wrong source for one edge. For stuck-at and launch-off-capture tests, scan_en can be treated as quasi-static. Launch-off-shift needs at-speed scan-enable timing, often with pipelined scan enables. In either case do not derive it through glitch-prone combinational logic.

    Interview

    Likely question: “how long does a scan operation take”. Roughly (longest chain length + capture cycles) × patterns, plus one final unload of the chain. Each response shifts out while the next pattern shifts in.

    Check yourself Four flops need a new vector. How many shift edges precede the capture edge?

    Four, one per flop. The first bit shifted in lands in the last flop just as capture arrives.

    Check yourself so stays 0 through slots 2 to 4 and rises in slot 5. Why?

    The chain is four deep, so the first bit shifted in needs four edges to reach the last flop. The waveform shows that delay directly.

    Testbench

    The chain of reused scan flops plus a testbench that shifts a vector in, captures, and shifts the answer out.

    scan_ff.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    `timescale 1ns/1ps
    module scan_ff (
      input  logic clk,
      input  logic rst_n,
      input  logic scan_en,
      input  logic d,
      input  logic si,
      output logic q,
      output logic so
    );
      logic d_mux;
      assign d_mux = scan_en ? si : d;
      assign so    = q;
    
      always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n)
          q <= 1'b0;
        else
          q <= d_mux;
      end
    endmodule
    
    module scan_chain4 (
      input  logic       clk,
      input  logic       rst_n,
      input  logic       scan_en,
      input  logic [3:0] d,
      input  logic       si,
      output logic [3:0] q,
      output logic       so
    );
      logic [3:0] qq;
      scan_ff f0 (.clk(clk), .rst_n(rst_n), .scan_en(scan_en), .d(d[0]), .si(si),    .q(qq[0]), .so());
      scan_ff f1 (.clk(clk), .rst_n(rst_n), .scan_en(scan_en), .d(d[1]), .si(qq[0]), .q(qq[1]), .so());
      scan_ff f2 (.clk(clk), .rst_n(rst_n), .scan_en(scan_en), .d(d[2]), .si(qq[1]), .q(qq[2]), .so());
      scan_ff f3 (.clk(clk), .rst_n(rst_n), .scan_en(scan_en), .d(d[3]), .si(qq[2]), .q(qq[3]), .so());
      assign q  = qq;
      assign so = qq[3];
    endmodule
    

    Remember

    • A scan flop is a D flop with a 2:1 mux; the first bit shifted in ends in the last flop, and is the first bit out.

    • A scan operation costs about (longest chain + capture cycles) x patterns, plus one final unload.

    • scan_en must be quasi-static for stuck-at and launch-off-capture tests; a glitch corrupts the vector.

    How this was checked

    The bench injects one modelled combinational stuck-at defect at the capture input. It checks detection, not ATPG coverage, physical defect behaviour or at-speed timing.

    Keep going

    • Code lab: Scan chain stub

    • Interview: run a mock interview on this topic

    Related topics

    • Test-mode integration checklist

    Previous

    279 / 350

    Next: Test-mode integration checklist

    Up next

    Up nextTest-mode integration checklist

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Controllability and observability in practice
    • Fault Coverage by Hand
    clkrst_nscan_ensiso
    Shift four bits in, capture once, and shift the answer out
    clkrst_nscan_ensiq01380so
    One scan round: four shift edges load 0011, one capture edge loads 1000, and the answer leaves on so with q3 first