DFT · Chapter 10 · Boundary Scan & JTAG
The JTAG TAP Controller
This lesson builds the JTAG test access port and its TAP controller. The interface is deliberately tiny: four mandatory signals, a test clock, a mode select, test data in, and test data out, plus an optional test reset. The brain is the TAP controller, a sixteen-state finite state machine driven entirely by the mode select sampled on the rising edge of the clock, so a sequence of mode-select values navigates the machine. Its structure is standard across every JTAG device: a reset and idle state, then two parallel columns for the data register and the instruction register, each doing capture, shift, and update. From this fall two operations: load an instruction, which selects which data register is active, then shift data through it. Holding mode select high for five clocks always returns the machine to a known reset state.
Intermediate13 min readDFTTAP ControllerJTAGTMSFinite State Machine
Chapter 10 · Section 10.2 · Boundary Scan & JTAG
Project thread — the mini-SoC's TAP is the serial engine that drives its boundary scan (10.3) and BIST access (10.5); 10.6 walks a full TAP sequence.
1. Why Should I Learn This?
The TAP controller is the serial engine of all of JTAG — every boundary-scan or BIST-access operation is a TMS walk through its 16 states.
- 4 signals: TCK (clock), TMS (mode select), TDI (in), TDO (out); optional TRST.
- 16-state FSM driven by TMS on TCK — two columns: IR (instruction) and DR (data).
- Two operations: load an instruction (IR → selects the data register), then shift data (DR).
- Each column: Capture → Shift → Update; 5 TMS-high clocks → Test-Logic-Reset (guaranteed reset).
2. Real Silicon Story — the chain stuck in an unknown state
A bring-up team connected their JTAG probe to a board and got nothing — the chain wouldn't respond, TDO was garbage. They suspected a broken TAP, a wiring fault, or a dead chip.
The real issue was state. The TAP controller is a 16-state FSM, and on connection (or after a glitch) it can be in any state — not necessarily the known Test-Logic-Reset. Their software started shifting data assuming a known starting point, but the FSM was somewhere else, so the TMS sequence navigated to the wrong states and the operations were meaningless.
The fix is the guaranteed reset: hold TMS = 1 for five TCK clocks, which drives the FSM to Test-Logic-Reset from any state (or assert TRST if present). From that known state, the standard navigation worked and the chain responded. Lesson: the TAP is a stateful FSM — always reset it to a known state first (5 TMS-high clocks → Test-Logic-Reset), because a chain in an unknown state looks broken but is just lost.
3. Factory Perspective — the TAP through each lens
- What the board-test engineer sees: the TMS sequences that navigate the FSM to Shift-IR (load instruction) and Shift-DR (shift data) — and the 5-TMS-high reset to recover a known state.
- What the DFT engineer sees: the standard 16-state TAP to implement per 1149.1 — a fixed FSM every device shares.
- What the software/tools engineer sees: that all JTAG operations are TMS walks + TDI/TDO shifts — a uniform driver across devices (given BSDL, 10.3).
- What the system engineer sees: the TAP as the in-system access engine — the same FSM used for BIST/ISP/debug (10.5), always reset to a known state first.
4. Concept — the signals, the FSM, and the two operations
The TAP signals:
- TCK — test clock (all TAP activity is synchronous to it).
- TMS — test mode select — sampled on the rising edge of TCK; its sequence navigates the FSM.
- TDI — test data in (serial input); TDO — test data out (serial output).
- TRST (optional) — asynchronous test reset to Test-Logic-Reset. It is optional precisely because the five-TMS-high sequence already guarantees a reset from any state; TRST exists for boards that need reset without a running TCK. The registers this FSM shifts are covered in boundary-scan cells and why boundary scan exists.
The 16-state FSM (standard, shared by every device):
- Home states: Test-Logic-Reset (reset), Run-Test/Idle (idle / run a self-test).
- Two parallel columns, selected by TMS:
- DR column (data): Select-DR → Capture-DR → Shift-DR → Exit1-DR → (Pause-DR → Exit2-DR) → Update-DR.
- IR column (instruction): Select-IR → Capture-IR → Shift-IR → Exit1-IR → (Pause-IR → Exit2-IR) → Update-IR.
- TMS on each TCK moves between states. From Run-Test/Idle, TMS = 1,0,0 → Shift-DR (Select-DR-Scan → Capture-DR → Shift-DR). Adding a second
1at the start diverts through Select-IR-Scan, so TMS = 1,1,0,0 lands in Shift-IR instead — one extra1is the difference between shifting data and shifting an instruction.
The three-beat operation in each column (Capture → Shift → Update):
- Capture: load the register (IR or the selected DR) from its source (e.g. capture the pin values, or a fixed instruction pattern).
- Shift: serially shift data TDI → register → TDO (this is where you read out the old contents and shift in new ones).
- Update: latch the shifted-in value to the register's output (parallel latch) — so it takes effect.
The two fundamental operations:
- Load an instruction (IR column): navigate to Shift-IR, shift the instruction in, Update-IR → the instruction selects which data register sits between TDI and TDO (JTAG instructions, 10.4).
- Shift data (DR column): navigate to Shift-DR, shift data through the selected register, Update-DR → the operation (e.g. drive/observe pins) takes effect.
The guaranteed reset:
- TMS = 1 for 5 TCK clocks → Test-Logic-Reset from any state — always start here to reach a known state.
The FSM sits between the pins and the registers:
5. Mental Model — a vending machine with one button
The TAP controller is like a vending machine navigated with a single button (TMS), stepped by a clock (TCK).
- The machine has a map of states (the 16-state FSM). Each button press (a TMS value on a TCK tick) moves you one step along the map — so a sequence of presses walks you to where you want to go.
- There are two aisles: the instruction aisle (IR) where you tell the machine what you want to do, and the data aisle (DR) where you actually move product (shift data). You first visit the instruction aisle to pick the operation (which selects which product bin is in the data aisle), then the data aisle to collect/deposit.
- Each aisle works the same way: grab what's there (Capture), swap it in/out (Shift), commit (Update).
- And there's a panic button: hold the button (TMS=1) for five ticks and you're always returned to the entrance (Test-Logic-Reset) — no matter where you were lost.
One button, a clock, a map: press your way to the instruction aisle, pick the operation, then the data aisle to move data — and five held presses always take you home.
6. Working Example — a TMS walk to shift a register
Trace the TMS navigation for the two operations:
# TAP navigation (TMS sampled on rising TCK) - REPRESENTATIVE, SIMPLIFIED, tool-neutral:
RESET first (known state): TMS = 1,1,1,1,1 -> TEST-LOGIC-RESET (from ANY state) [+ TMS=0 -> Run-Test/Idle]
LOAD AN INSTRUCTION (IR):
from Run-Test/Idle: TMS = 1,1 -> Select-IR ; TMS=0 -> Capture-IR ; TMS=0 -> SHIFT-IR
in SHIFT-IR: shift the instruction bits in on TDI (old IR out on TDO), TMS=0 each bit; last bit TMS=1 -> Exit1-IR
TMS=1 -> UPDATE-IR -> the instruction now SELECTS the data register (e.g. boundary-scan register)
SHIFT DATA (DR):
from Run-Test/Idle: TMS = 1 -> Select-DR ; TMS=0 -> Capture-DR ; TMS=0 -> SHIFT-DR
in SHIFT-DR: shift data through the SELECTED register (TDI->reg->TDO); last bit TMS=1 -> Exit1-DR
TMS=1 -> UPDATE-DR -> the shifted value takes effect (e.g. drives the boundary cells onto pins)
# Every JTAG operation = navigate (TMS) to Shift-IR/Shift-DR, shift (TDI/TDO), Update. The FSM is identical everywhere.6b. The TAP Controller, Written Out
The FSM is fixed by IEEE 1149.1, which means it is the same sixteen states in
every compliant device ever built — and it means you can write it down exactly.
Below is a synthesizable TAP that a bind-free testbench can drive directly.
module jtag_tap #(
parameter int IR_WIDTH = 4,
parameter logic [IR_WIDTH-1:0] IDCODE_INSTR = 4'b0001,
parameter logic [IR_WIDTH-1:0] BYPASS_INSTR = '1, // all-ones = BYPASS
parameter logic [31:0] IDCODE_VALUE = 32'h1234_5678
) (
input logic TCK,
input logic TMS,
input logic TDI,
input logic TRSTn, // optional async reset; tie high if unused
output logic TDO,
output logic TDO_oe, // TDO must be tri-stated outside the shift states
// Boundary-scan / user data register interface
output logic [IR_WIDTH-1:0] ir_out,
output logic dr_capture,
output logic dr_shift,
output logic dr_update,
input logic user_tdo
);
// ── The sixteen states. The encoding is arbitrary (unlike the state
// graph, which is not), so a plain enum is fine.
typedef enum logic [3:0] {
TEST_LOGIC_RESET, RUN_TEST_IDLE,
SELECT_DR, CAPTURE_DR, SHIFT_DR, EXIT1_DR, PAUSE_DR, EXIT2_DR, UPDATE_DR,
SELECT_IR, CAPTURE_IR, SHIFT_IR, EXIT1_IR, PAUSE_IR, EXIT2_IR, UPDATE_IR
} tap_state_e;
tap_state_e state, next;
// ── Next-state logic. Every arc is a function of TMS alone; this table IS
// the standard's state diagram, and it is worth reading against Figure 1.
always_comb begin
unique case (state)
TEST_LOGIC_RESET: next = TMS ? TEST_LOGIC_RESET : RUN_TEST_IDLE;
RUN_TEST_IDLE: next = TMS ? SELECT_DR : RUN_TEST_IDLE;
// Note the two Select states chain: TMS high in SELECT_DR moves on to
// SELECT_IR rather than doing anything DR-related. That chaining is why
// Run-Test/Idle -> Shift-DR is 1,0,0 while -> Shift-IR is 1,1,0,0.
SELECT_DR: next = TMS ? SELECT_IR : CAPTURE_DR;
CAPTURE_DR: next = TMS ? EXIT1_DR : SHIFT_DR;
SHIFT_DR: next = TMS ? EXIT1_DR : SHIFT_DR;
EXIT1_DR: next = TMS ? UPDATE_DR : PAUSE_DR;
PAUSE_DR: next = TMS ? EXIT2_DR : PAUSE_DR;
EXIT2_DR: next = TMS ? UPDATE_DR : SHIFT_DR;
UPDATE_DR: next = TMS ? SELECT_DR : RUN_TEST_IDLE;
SELECT_IR: next = TMS ? TEST_LOGIC_RESET : CAPTURE_IR;
CAPTURE_IR: next = TMS ? EXIT1_IR : SHIFT_IR;
SHIFT_IR: next = TMS ? EXIT1_IR : SHIFT_IR;
EXIT1_IR: next = TMS ? UPDATE_IR : PAUSE_IR;
PAUSE_IR: next = TMS ? EXIT2_IR : PAUSE_IR;
EXIT2_IR: next = TMS ? UPDATE_IR : SHIFT_IR;
UPDATE_IR: next = TMS ? SELECT_DR : RUN_TEST_IDLE;
endcase
end
// TMS is sampled on the RISING edge of TCK, so the state register is
// rising-edge triggered. This is the one timing fact that makes the rest
// of the block make sense.
always_ff @(posedge TCK or negedge TRSTn)
if (!TRSTn) state <= TEST_LOGIC_RESET;
else state <= next;
// ── Instruction register: a shift stage plus a parallel Update latch.
logic [IR_WIDTH-1:0] ir_shift;
always_ff @(posedge TCK or negedge TRSTn) begin
if (!TRSTn) begin
ir_shift <= '0;
end else if (state == CAPTURE_IR) begin
// 1149.1 mandates that the two LSBs captured into the IR are 2'b01.
// Board-test software relies on it to detect chain integrity.
ir_shift <= {{(IR_WIDTH-2){1'b0}}, 2'b01};
end else if (state == SHIFT_IR) begin
ir_shift <= {TDI, ir_shift[IR_WIDTH-1:1]}; // LSB first, toward TDO
end
end
// Update-IR latches on the FALLING edge, which is what keeps the newly
// selected data register stable for the whole of the next TCK period.
always_ff @(negedge TCK or negedge TRSTn)
if (!TRSTn) ir_out <= IDCODE_INSTR; // reset selects IDCODE
else if (state == UPDATE_IR) ir_out <= ir_shift;
else if (state == TEST_LOGIC_RESET) ir_out <= IDCODE_INSTR;
// ── The two mandatory data registers.
logic bypass_reg;
logic [31:0] idcode_reg;
always_ff @(posedge TCK) begin
// BYPASS is a single stage, and it must CLEAR on capture - a stuck 1 here
// would corrupt every downstream device's data in a multi-device chain.
if (state == CAPTURE_DR) bypass_reg <= 1'b0;
else if (state == SHIFT_DR) bypass_reg <= TDI;
if (state == CAPTURE_DR) idcode_reg <= IDCODE_VALUE;
else if (state == SHIFT_DR) idcode_reg <= {TDI, idcode_reg[31:1]};
end
// ── DR control strobes, exported to boundary-scan / user registers.
assign dr_capture = (state == CAPTURE_DR);
assign dr_shift = (state == SHIFT_DR);
assign dr_update = (state == UPDATE_DR);
// ── TDO. Two rules the standard is strict about:
// 1. TDO changes on the FALLING edge of TCK, so it is stable when the
// next device in the chain samples it on the rising edge.
// 2. TDO is only driven during Shift-DR and Shift-IR; elsewhere it is
// high-impedance, which is what allows chain devices to share the pin.
logic tdo_mux;
always_comb begin
unique case (ir_out)
IDCODE_INSTR: tdo_mux = idcode_reg[0];
BYPASS_INSTR: tdo_mux = bypass_reg;
default: tdo_mux = user_tdo;
endcase
if (state == SHIFT_IR) tdo_mux = ir_shift[0];
end
always_ff @(negedge TCK or negedge TRSTn)
if (!TRSTn) begin TDO <= 1'b0; TDO_oe <= 1'b0; end
else begin
TDO <= tdo_mux;
TDO_oe <= (next == SHIFT_DR) || (next == SHIFT_IR);
end
endmoduleThree details in that file are the ones hand-written TAPs get wrong, and all three are silent in a single-device bring-up.
The Select states chain. SELECT_DR with TMS high goes to SELECT_IR, not
back to idle. This is the mechanism behind the navigation arithmetic: reaching
Shift-DR from Run-Test/Idle is 1,0,0, and reaching Shift-IR is 1,1,0,0,
because the extra 1 walks one further along the Select chain. Writing the arc
wrong produces a TAP that can load instructions but never shift data, or the
reverse.
Falling-edge output. The state register and TDI sample on the rising edge; TDO and the Update latches change on the falling edge. That half-cycle offset is what makes a multi-device chain work at all — each device's TDO is stable well before the next device samples it. Register TDO on the rising edge instead and a single device still passes every test, while a two-device chain fails intermittently as soon as the board's TCK routing has any real skew.
BYPASS clears on capture. A single-stage register that captures 1 instead of 0 injects a spurious bit into the chain, corrupting the data of every device downstream of it. It is one line, and it is invisible until someone builds a chain.
Driving it
module tap_tb;
logic TCK = 0, TMS = 1, TDI = 0, TRSTn = 0, TDO, TDO_oe;
localparam logic [31:0] EXPECT_ID = 32'h1234_5678;
jtag_tap u_tap (.TCK, .TMS, .TDI, .TRSTn, .TDO, .TDO_oe,
.ir_out(), .dr_capture(), .dr_shift(), .dr_update(),
.user_tdo(1'b0));
always #5 TCK = ~TCK;
// One TCK period with a given TMS. TMS is driven off the falling edge so it
// is stable across the rising edge that samples it - the same discipline a
// real JTAG controller uses.
task automatic tick(input logic tms_val);
@(negedge TCK); TMS = tms_val;
@(posedge TCK);
endtask
initial begin
TRSTn = 0; repeat (2) @(negedge TCK); TRSTn = 1;
// Five TMS=1 clocks reach Test-Logic-Reset from ANY state. Five is not a
// safety margin - it is the length of the longest path to TLR in the
// state graph, so it is the minimum that is guaranteed.
repeat (5) tick(1'b1);
tick(1'b0); // -> Run-Test/Idle
// Reset selects IDCODE, so we can read it without loading an instruction.
// Run-Test/Idle -> Select-DR -> Capture-DR -> Shift-DR is 1,0,0.
tick(1'b1); tick(1'b0); tick(1'b0);
begin
logic [31:0] id;
// In Shift-DR, TDO presents the LSB first. Sample on the rising edge,
// where TDO (updated on the previous falling edge) is stable.
for (int i = 0; i < 32; i++) begin
id[i] = TDO;
if (i < 31) tick(1'b0); // stay in Shift-DR
end
tick(1'b1); // -> Exit1-DR
tick(1'b1); // -> Update-DR
assert (id === EXPECT_ID)
else $fatal(1, "IDCODE mismatch: read %h, expected %h", id, EXPECT_ID);
$display("PASS: IDCODE = %h", id);
end
$finish;
end
endmoduleThe testbench is worth more than the pass message it prints. Change the
SELECT_DR arc to return to RUN_TEST_IDLE instead of chaining to SELECT_IR
and this test still passes, because a 1,0,0 walk never visits SELECT_IR —
you need an instruction-load test to catch that one. That asymmetry is the
practical argument for exercising both columns during TAP bring-up rather than
declaring victory on a successful IDCODE read.
A second device joined the JTAG chain and IDCODE reads returned garbage
CHAIN-SHIFT-ORDERINGA TAP that had worked for months on a single-device board failed as soon as a second device was added to the chain. Reading the two IDCODEs back returned the first device's value shifted by one bit position and the second device's value corrupted entirely. Removing either device and testing it alone worked perfectly, which is what made the board team suspect the new device rather than the TAP.
// BYPASS did not clear on capture:
always_ff @(posedge TCK)
if (state == SHIFT_DR) bypass_reg <= TDI; // no CAPTURE_DR branch
// ...and TDO was registered on the RISING edge:
always_ff @(posedge TCK)
TDO <= tdo_mux;A scope on TCK, TDI and TDO between the two devices settled it. Two things were visible. The upstream device's TDO transitioned on the rising edge of TCK — the same edge the downstream device uses to sample TDI — so the downstream device was sampling a signal in the middle of its transition. And the total number of bits shifted out of the chain was one greater than the sum of the two devices' register lengths.
The bit-count discrepancy is the sharper clue, because it is exact rather than marginal. An off-by-one in the chain length always means a register in the chain is contributing a stage that is not accounted for, or contributing the wrong value into an accounted-for stage.
Two independent single-device-invisible bugs, both exposed by the same board change.
The bypass_reg never cleared, so when the first device was placed in BYPASS to
read the second device's IDCODE, its one-bit register shifted out whatever it
happened to hold rather than the mandated 0. Every bit read from the second
device was therefore preceded by a spurious bit and appeared shifted by one
position. With a single device, BYPASS was never used, so the register's content
never reached anyone.
The rising-edge TDO removed the half-cycle of setup margin that the standard's falling-edge rule exists to provide. With one device, TDO went straight to the board connector and the tester sampled it with plenty of margin, so the violation never mattered. With two devices in series, the upstream TDO fed the downstream TDI directly and the sampling margin was whatever the board routing happened to leave — sometimes enough, sometimes not.
// 1. BYPASS clears on capture, as 1149.1 requires.
always_ff @(posedge TCK)
if (state == CAPTURE_DR) bypass_reg <= 1'b0;
else if (state == SHIFT_DR) bypass_reg <= TDI;
// 2. TDO changes on the falling edge, giving the next device in the chain a
// half TCK period of setup before it samples on the rising edge.
always_ff @(negedge TCK or negedge TRSTn)
if (!TRSTn) begin TDO <= 1'b0; TDO_oe <= 1'b0; end
else begin
TDO <= tdo_mux;
TDO_oe <= (next == SHIFT_DR) || (next == SHIFT_IR);
endVerifying the fix needs a chain, not a device. The check that catches both bugs is a two-device shift test: put device A in BYPASS, read device B's IDCODE, and assert both that the value matches and that the total shift length equals one plus device B's register length. Length is the assertion that matters — a value check alone passes on a chain that is accidentally one bit long if the extra bit happens to be zero.
The broader lesson for TAP bring-up is that single-device testing cannot exercise the parts of 1149.1 that exist specifically to make chains work. BYPASS content, TDO edge timing, and TDO tri-state behaviour are all unobservable until there is a second device to observe them with, so a chain test belongs in the block-level plan rather than being deferred to the board.
7. Industry Flow — reset, load instruction, shift data
Every JTAG operation follows the same FSM sequence:
8. Debugging Session — the JTAG chain won't respond
A JTAG chain won't respond and TDO is garbage, and the team suspects broken wiring or a dead TAP; the TAP controller is a stateful FSM that can be in any state on connection, and software that starts shifting assumes a known state -- the fix is to reset the TAP to a known state first by holding TMS high for five TCK clocks (or asserting TRST), which reaches Test-Logic-Reset from any state, and then navigate normally
A STATEFUL FSM IN AN UNKNOWN STATE LOOKS BROKEN — RESET WITH 5 TMS-HIGH CLOCKS FIRSTA JTAG chain won't respond — TDO is garbage, operations do nothing. The team suspects broken wiring, a dead TAP, or a bad chip.
The TAP controller is a stateful 16-state FSM that can be in any state when you connect (or after a glitch), and software that begins shifting data assumes a known starting state — so its TMS sequence navigates from the wrong state and every operation is meaningless. The entire JTAG protocol is relative to the FSM's current state: a given TMS sequence means 'go to Shift-DR' only if you start from a known state (e.g. Run-Test/Idle). On connection, the TAP could be anywhere — mid-shift, in a Pause state, in an IR column — because nothing has reset it. If the driver assumes it's at, say, Run-Test/Idle and issues the navigate-to-Shift-DR TMS pattern, but the FSM is actually somewhere else, the pattern lands in the wrong states, so the shifts read/write the wrong register (or none) and TDO looks like garbage. This looks identical to a hardware failure (no valid response), which is why teams chase wiring/chip faults — but the TAP hardware is fine; it's simply lost, and the protocol has no way to recover without an explicit reset to a known state.
Reset the TAP to a known state first — hold TMS high for five TCK clocks (which reaches Test-Logic-Reset from any state), or assert TRST — then navigate normally. Begin every JTAG session (and after any suspected glitch) with the guaranteed reset: drive TMS = 1 for at least 5 TCK rising edges, which the FSM is designed to interpret as 'go to Test-Logic-Reset' regardless of the current state (the 5 covers the longest path back). If the device has TRST, asserting it does the same asynchronously. From Test-Logic-Reset, the known navigation works: TMS=0 → Run-Test/Idle, then the standard Shift-IR / Shift-DR sequences (Section 6) behave as expected and TDO becomes valid. Make the 5-TMS-high reset the first step of the JTAG driver so a lost chain always recovers. The principle to lock in: the TAP controller is a standard 16-state FSM driven by TMS sampled on TCK, with parallel instruction-register and data-register columns each doing capture, shift, and update — so every JTAG operation is a TMS walk to Shift-IR (load an instruction that selects a data register) then Shift-DR (shift that register) then Update; and because the FSM is stateful and can power up or glitch into any state, a chain that won't respond is usually simply in an unknown state, recovered by the guaranteed reset of holding TMS high for five TCK clocks to reach Test-Logic-Reset from anywhere, after which normal navigation works — a lost TAP looks broken but only needs a reset. (Boundary cells the DR shifts are 10.3; instructions the IR loads are 10.4; board/in-system use is 10.5.)
9. Common Mistakes
- Not resetting the TAP first. It can be in any state — 5 TMS-high clocks → Test-Logic-Reset (known state).
- Assuming a starting state. All navigation is relative — always start from a reset (known) state.
- Confusing the IR and DR columns. Load an instruction (IR) to select a register, then shift data (DR).
- Forgetting Update. Capture/Shift aren't enough — Update latches the value to the register's output (takes effect).
- Sampling TMS on the wrong edge. TMS is sampled on the rising edge of TCK — get the timing right.
10. Industry Best Practices
- Start every session with the 5-TMS-high reset (or TRST) — a known state first.
- Model the FSM navigation in the driver — reset → Shift-IR → Shift-DR → Update.
- Use Run-Test/Idle to run self-tests (BIST) between operations (10.5).
- Implement a compliant 16-state TAP per 1149.1 — the standard every tool expects.
- Treat a non-responding chain as 'lost' (reset it) before suspecting hardware.
11. Senior Engineer Thinking
- Beginner: "The JTAG chain is dead — must be a wiring or chip fault."
- Senior: "The TAP is a stateful FSM — on connect it can be anywhere. If my software assumes a known state and it isn't, every shift lands in the wrong state and TDO is garbage — looks broken, isn't. I reset first: TMS=1 for 5 TCKs → Test-Logic-Reset from any state, then navigate. A lost TAP needs a reset, not a repair."
The senior resets the TAP to a known state first and reads a non-responding chain as lost, not broken.
12. Silicon Impact
The TAP controller is the universal serial engine that makes all of JTAG work — boundary scan (10.3), the instruction set (10.4), and in-system BIST/ISP/debug access (10.5, the 9.5 bridge) are all just TMS walks through this one standard 16-state FSM plus TDI/TDO shifts. Its genius is uniformity: every compliant device implements the identical FSM, so a single driver model — reset → load instruction (Shift-IR) → shift data (Shift-DR) → Update — controls any JTAG chip, which is exactly why JTAG became a universal, tool-portable standard. Two properties are worth internalizing for real work. First, the two-operation structure: you always load an instruction first (the IR column) to select which data register is in the path, then shift that register (the DR column) — and each column's Capture → Shift → Update three-beat is what reads out old contents while shifting in new ones and then commits them. Second — and the single most common bring-up bug — the FSM is stateful, so a chain that won't respond is almost always not broken but lost (in an unknown state), recovered by the guaranteed reset: hold TMS high for 5 TCK clocks → Test-Logic-Reset from anywhere. For the DFT engineer, the TAP is a standard block to instantiate for 1149.1 compliance (a board-testability and access requirement, 10.1); for the board/software engineer, it's a fixed navigation model to encode; and for bring-up, the discipline of always resetting to a known state first turns a mysterious 'dead chain' into a one-step recovery. This standard FSM is the foundation on which the rest of the chapter — the boundary cells it shifts (10.3), the instructions it loads (10.4), and the board/in-system operations it drives (10.5/10.6) — all rest.
13. Engineering Checklist
- Implemented a compliant 16-state TAP per 1149.1 (TCK/TMS/TDI/TDO; optional TRST).
- Driver resets to a known state first (5 TMS-high clocks → Test-Logic-Reset, or TRST).
- Modeled the two operations: Shift-IR (load instruction → selects DR) then Shift-DR (shift data).
- Included Update (latch to output) — not just Capture/Shift.
- Used Run-Test/Idle for self-tests (BIST); treated a non-responding chain as lost (reset it).
14. Try Yourself
- List the 4 mandatory TAP signals (+ optional TRST) and what each does.
- Draw the FSM skeleton: Test-Logic-Reset, Run-Test/Idle, and the IR and DR columns (Capture/Shift/Update).
- Write the TMS sequence from Run-Test/Idle to Shift-DR, and from Run-Test/Idle to Shift-IR.
- Explain the two operations: load an instruction (selects a register), then shift data.
- Give the guaranteed reset (5 TMS-high clocks → Test-Logic-Reset) and why bring-up should reset first.
The FSM is fixed by IEEE 1149.1; navigation is tool-neutral. No paid tool required to trace the TAP.
15. Interview Perspective
- Weak: "The TAP controller runs the JTAG interface."
- Good: "It's a state machine driven by TMS on TCK that shifts the instruction and data registers via TDI/TDO."
- Senior: "The TAP has 4 signals — TCK, TMS, TDI, TDO (+ optional TRST) — and the TAP controller is a standard 16-state FSM driven by TMS sampled on TCK. It has two 'home' states (Test-Logic-Reset, Run-Test/Idle) and two parallel columns — IR (instruction) and DR (data) — each doing Capture → Shift → Update. Every operation is: load an instruction via Shift-IR (which selects the data register between TDI/TDO), then shift that register via Shift-DR, then Update to take effect. It's the same FSM in every device, so one driver controls anything. And the key bring-up rule: the FSM is stateful, so hold TMS=1 for 5 TCKs to reach Test-Logic-Reset from any state — a non-responding chain is usually just lost, not broken; reset it first."
16. Interview / Review Questions
16b. Where This Is Specified
- IEEE 1149.1-2013 — Standard for Test Access Port and Boundary-Scan Architecture. The sixteen-state TAP controller state diagram and every arc in it, the mandatory TCK/TMS/TDI/TDO signals and optional TRST, the guarantee that five TMS-high clocks reach Test-Logic-Reset from any state, the mandated
2'b01capture into the two IR LSBs, the requirement that BYPASS captures 0, and the rule that TDO changes on the falling edge of TCK and is driven only during the Shift states. - IEEE 1149.1-2013 clause 7 — Instruction register. BYPASS, IDCODE and SAMPLE/PRELOAD, and the requirement that reset selects IDCODE where an IDCODE register is present (BYPASS otherwise).
- IEEE 1149.6-2015. The AC-coupled extension for high-speed differential I/O, which reuses this same TAP unchanged.
- IEEE 1687-2014 (IJTAG). Reconfigurable instrument networks layered on this TAP, where the selected data register becomes a dynamically-scanned network.
17. Key Takeaways
- The TAP (Test Access Port) has four mandatory signals — TCK (clock), TMS (mode select), TDI (in), TDO (out) — plus an optional TRST (reset); all of JTAG flows over these few wires.
- The TAP controller is a standard 16-state FSM driven by TMS sampled on TCK, with two 'home' states (Test-Logic-Reset, Run-Test/Idle) and two parallel columns — IR (instruction) and DR (data) — each doing Capture → Shift → Update.
- JTAG's two fundamental operations: load an instruction via Shift-IR (which selects which data register sits between TDI/TDO), then shift data through that register via Shift-DR — Update latches each to take effect.
- The FSM is identical in every compliant device, so one driver model (reset → Shift-IR → Shift-DR → Update) controls any JTAG chip — the reason JTAG is a universal, portable standard.
- The FSM is stateful, so hold TMS high for 5 TCK clocks → Test-Logic-Reset from any state (guaranteed reset) — a non-responding chain is usually just lost, not broken; always reset to a known state first. Next: 10.3 — boundary-scan cells & the register.
18. Quick Revision
The JTAG TAP controller. TAP = 4 signals: TCK (clock), TMS (mode select), TDI (in), TDO (out); optional TRST. The TAP controller = a standard 16-state FSM driven by TMS sampled on rising TCK. Home states: Test-Logic-Reset, Run-Test/Idle; two parallel columns — IR (instruction) + DR (data) — each: Capture → Shift → Update. Two operations: load an INSTRUCTION (Shift-IR → selects which data register is between TDI/TDO) then SHIFT DATA (Shift-DR through the selected register), Update = take effect. Same FSM in EVERY device → one driver model. Guaranteed reset: TMS=1 for 5 TCKs → Test-Logic-Reset from ANY state → a non-responding chain is usually just LOST (reset first, not broken). Next: 10.3 — boundary-scan cells & the register.