What is JTAG?
JTAG stands for Joint Test Action Group — the industry consortium that in 1990 published IEEE Standard 1149.1, formally titled "Standard Test Access Port and Boundary-Scan Architecture." What started as a solution to the PCB interconnect testing crisis of the 1980s has grown into the universal interface for chip testing, embedded debug, flash programming, and in-system instrumentation.
In the 1980s, through-hole PCB components could be tested with bed-of-nails fixtures that physically contacted every pin on every chip. Surface-mount technology (SMT) made this impossible — pins were too small and too densely packed. The JTAG committee's answer was elegant: add a standardized serial test port to every chip, so board-level interconnects could be tested through software by shifting test patterns through the chips themselves.
Today, JTAG is used for:
- Board interconnect testing: test solder joints and PCB traces between chips using boundary scan (EXTEST instruction)
- Chip-level scan access: access internal scan chains through the JTAG TAP for DFT without dedicated external scan pins
- Embedded debug: ARM CoreSight, RISC-V Debug, MIPS EJTAG — all use JTAG to halt CPUs, read registers, and set breakpoints
- Flash programming: FPGA configuration files and NOR flash are programmed via JTAG in the field
- Embedded instruments: IEEE 1687 (IJTAG) extends JTAG access to on-chip instruments like MBIST, PLL calibration, and temperature sensors
Instead of physically probing every chip pin, JTAG adds a one-bit-wide serial shift register (the boundary scan register) around every I/O pin of the chip. By shifting test patterns in and out serially, any combination of pin values can be driven or read — through just four or five dedicated test pins.
JTAG Signals — The 5 Pins
IEEE 1149.1 defines five signals for the Test Access Port (TAP). Only TRST is optional — the other four are mandatory on every IEEE 1149.1 compliant device.
| Pin | Direction | Active Level | Sampled On | Function |
|---|---|---|---|---|
| TCK | Input | N/A (clock) | — | Test clock — all JTAG ops sync to TCK |
| TMS | Input | Active high | TCK rising edge | Controls TAP FSM state transitions |
| TDI | Input | Active high | TCK rising edge | Serial data into selected IR or DR |
| TDO | Output | Active high | — (drives TCK falling) | Serial data out from selected IR or DR |
| TRST | Input | Active LOW | Asynchronous | Async reset of TAP to Test-Logic-Reset |
TAP Controller — 16-State FSM
The Test Access Port (TAP) controller is the heart of every JTAG implementation. It is a 16-state Moore FSM whose only input is TMS (sampled every TCK rising edge). The current state determines what the chip does with TCK, TDI, and TDO. All 16 states and their TMS=0/TMS=1 transitions are defined by IEEE 1149.1.
The states naturally split into two parallel paths: a Data Register (DR) path for accessing data registers (like the BSR), and an Instruction Register (IR) path for loading the instruction that selects which data register is active.
Key TAP States Explained
Instruction Register (IR)
The Instruction Register (IR) determines which data register is connected between TDI and TDO during the next DR-scan operation. The IR is a shift register that is updated via the Capture-IR → Shift-IR → Update-IR sequence. IEEE 1149.1 requires a minimum IR length of 2 bits — most chips implement 3 to 10 bits.
On Capture-IR, the IR shift register loads a fixed pattern (typically ...0001 with the two LSBs always 01, per IEEE 1149.1 § 7.2.1) — this allows the tester to detect the IR length and verify connectivity.
The standard mandatory IR codes are:
| Instruction | IR Code (3-bit example) | Data Register Selected | Function |
|---|---|---|---|
| EXTEST | 000 | Boundary Scan Register (BSR) | Drive test patterns on I/O pins; capture board-level responses. Tests PCB interconnects. |
| SAMPLE/PRELOAD | 010 | Boundary Scan Register (BSR) | Non-destructively sample current pin values; preload data for EXTEST transition. |
| BYPASS | 111 (all ones) | Bypass Register (1 bit) | Skip this chip in the scan chain — adds only 1 bit to chain length. |
| IDCODE | 001 | Device ID Register (32 bits) | Read the 32-bit chip identification code: manufacturer ID (JEDEC), part number, version. |
| HIGHZ | 101 (optional) | Bypass Register | Force all chip output pins to high-impedance (tri-state). Used to isolate the chip. |
| CLAMP | 100 (optional) | Bypass Register | Output pins driven from preloaded BSR values while data path uses bypass register. |
Boundary Scan Register (BSR)
The Boundary Scan Register (BSR) is a chain of individual boundary scan cells (BSCs) — one per I/O pin of the chip — connected to form a shift register that encircles the entire chip periphery. The BSR sits at the interface between the chip's core logic and its I/O pads.
Each Boundary Scan Cell (BSC) contains:
- System cell: connects the I/O pad to the chip's functional logic during normal operation
- Capture cell (shift register): a flip-flop that can capture the pad value (for SAMPLE) or be shifted to form part of the serial chain
- Update cell: a second flip-flop that holds the stable output value while the shift register is being updated
- Multiplexer: selects between the functional data path and the test data path based on the active JTAG instruction
During EXTEST: the update cells drive the output pads from preloaded BSR data, and input pad values are captured into capture cells on the rising edge of TCK when in Capture-DR state. This lets you drive arbitrary patterns onto board traces and read back what the neighboring chips' pins see — without any physical probe access.
Key JTAG Instructions in Detail
EXTEST — External Test
EXTEST is the core board-level interconnect test instruction. With EXTEST active, the output pins of the chip are driven by the BSR's update cells (not by the chip's core logic). The test engineer pre-loads the BSR with a test pattern using SAMPLE/PRELOAD, then switches to EXTEST. Now:
- Output pins drive the test pattern onto the PCB traces
- Adjacent chips (also in EXTEST) capture what arrives at their input pins
- The captured values are shifted out via the BSR scan chain and compared against expected values
- A mismatch indicates an open or shorted net on the PCB
SAMPLE/PRELOAD — Non-Destructive Snapshot
SAMPLE/PRELOAD has two roles: in sample mode, it takes a non-destructive snapshot of all I/O pin values during normal chip operation — useful for debugging. In preload mode, data shifted into the BSR via TDI is staged in the update cells, ready to be driven out when the instruction changes to EXTEST. This prevents glitches on the PCB during the instruction transition.
BYPASS — Skip in Chain
The bypass register is a single flip-flop connecting TDI to TDO with one clock cycle of latency. When a chip is set to BYPASS, it is effectively removed from the scan chain — it only adds 1 bit of delay. This is crucial in systems with many chips in the JTAG daisy chain: if you need to test only one chip, bypass all others to make the effective chain length = (target chip BSR length + N×1 bit for N bypassed chips).
IDCODE — Device Identification
The IDCODE register is a 32-bit read-only register containing the chip's identity per IEEE 1149.1 §12:
Bit 27–12: Part Number (16 bits)
Bit 11–1: Manufacturer ID (11 bits, JEDEC-encoded)
Bit 0: Always 1 (LSB, mandated)
The IDCODE instruction is typically selected automatically after reset (it is often the power-on-reset default instruction), allowing a tester to immediately identify all chips in the chain by reading their 32-bit IDs.
Verilog: Simplified TAP Controller
Below is a simplified Verilog implementation of the TAP FSM covering the key states. A real implementation would also include the IR/DR register logic, the data mux, and the TDO output register — but the FSM skeleton shows the state encoding and TMS-driven transitions.
// Simplified IEEE 1149.1 TAP Controller FSM // 16-state Moore machine driven by TMS (sampled on TCK posedge) module tap_controller ( input tck, // Test Clock input tms, // Test Mode Select input trst_n, // Test Reset (active low, optional) output reg shift_dr, // 1 in Shift-DR state output reg capture_dr, // 1 in Capture-DR state output reg update_dr, // 1 in Update-DR state output reg shift_ir, // 1 in Shift-IR state output reg capture_ir, // 1 in Capture-IR state output reg update_ir // 1 in Update-IR state ); // State encoding (4 bits for 16 states) localparam [3:0] TLR = 4'h0, // Test-Logic-Reset RTI = 4'h1, // Run-Test/Idle SEL_DR = 4'h2, // Select-DR-Scan CAP_DR = 4'h3, // Capture-DR SHIFT_DR = 4'h4, // Shift-DR EXIT1_DR = 4'h5, // Exit1-DR PAUSE_DR = 4'h6, // Pause-DR EXIT2_DR = 4'h7, // Exit2-DR UPD_DR = 4'h8, // Update-DR SEL_IR = 4'h9, // Select-IR-Scan CAP_IR = 4'hA, // Capture-IR SHIFT_IR = 4'hB, // Shift-IR EXIT1_IR = 4'hC, // Exit1-IR PAUSE_IR = 4'hD, // Pause-IR EXIT2_IR = 4'hE, // Exit2-IR UPD_IR = 4'hF; // Update-IR reg [3:0] state, next_state; // ── State register (synchronous on TCK, async reset) ──────────── always @(posedge tck or negedge trst_n) begin if (!trst_n) state <= TLR; else state <= next_state; end // ── Next-state logic (combinational) ──────────────────────────── always @(*) begin case (state) TLR: next_state = tms ? TLR : RTI; RTI: next_state = tms ? SEL_DR : RTI; SEL_DR: next_state = tms ? SEL_IR : CAP_DR; CAP_DR: next_state = tms ? EXIT1_DR : SHIFT_DR; SHIFT_DR: next_state = tms ? EXIT1_DR : SHIFT_DR; EXIT1_DR: next_state = tms ? UPD_DR : PAUSE_DR; PAUSE_DR: next_state = tms ? EXIT2_DR : PAUSE_DR; EXIT2_DR: next_state = tms ? UPD_DR : SHIFT_DR; UPD_DR: next_state = tms ? SEL_DR : RTI; SEL_IR: next_state = tms ? TLR : CAP_IR; CAP_IR: next_state = tms ? EXIT1_IR : SHIFT_IR; SHIFT_IR: next_state = tms ? EXIT1_IR : SHIFT_IR; EXIT1_IR: next_state = tms ? UPD_IR : PAUSE_IR; PAUSE_IR: next_state = tms ? EXIT2_IR : PAUSE_IR; EXIT2_IR: next_state = tms ? UPD_IR : SHIFT_IR; UPD_IR: next_state = tms ? SEL_DR : RTI; default: next_state = TLR; endcase end // ── Output decode (Moore outputs from current state) ───────────── always @(*) begin shift_dr = (state == SHIFT_DR); capture_dr = (state == CAP_DR); update_dr = (state == UPD_DR); shift_ir = (state == SHIFT_IR); capture_ir = (state == CAP_IR); update_ir = (state == UPD_IR); end endmodule
Key implementation notes:
- TDI is sampled on TCK rising edge (in Shift-DR or Shift-IR) by the shift register logic (not shown here)
- TDO is driven on TCK falling edge to give setup time at the receiving device's TDI
- TMS must have a valid setup time before TCK rising edge — typically 5–10 ns at 10 MHz TCK
- TRST_N is asynchronous — it can reset the TAP at any time, regardless of TCK
JTAG Chain on PCB
On a multi-chip PCB, all JTAG-compliant chips share a common TCK and TMS bus, but TDI and TDO form a daisy chain: the TDO output of chip N connects to the TDI input of chip N+1. The host controller's TDI connects to chip 1's TDI, and chip N's TDO connects back to the host's TDO input.
When Chip 2 is in BYPASS mode, the effective chain length is only 225 bits (128 + 1 bypass bit + 96) instead of 288 bits (128+64+96). For a 100-chip board where you're testing one chip, BYPASS reduces chain length from thousands of bits to just a few hundred — dramatically reducing test time.
JTAG Beyond Boundary Scan
ARM CoreSight Debug via JTAG
ARM's CoreSight debug architecture connects to the processor via a Debug Access Port (DAP), which is accessed through JTAG (or its two-wire successor, SWD — Serial Wire Debug). The DAP contains an AHB Access Port (AHB-AP) that gives the debugger a 32-bit master port onto the chip's AHB bus. Through this, a JTAG probe running GDB or OpenOCD can halt CPU cores, read/write all registers and memory, set hardware breakpoints, and single-step through code — all without any internal logic analyzer hardware.
FPGA Programming via JTAG
FPGA vendors (Xilinx/AMD, Intel/Altera, Lattice) implement JTAG-accessible BSCAN primitives. The FPGA's configuration memory (SRAM-based or flash-based) is loaded via JTAG using the vendor's boundary scan instructions (e.g., CFG_IN, CFG_OUT on Xilinx). At power-up or on demand, the full configuration bitstream is shifted in through TDI. In-system logic analyzers (ChipScope, SignalTap) also use the BSCAN TAP to capture internal signals without external pins.
SVF — Serial Vector Format
SVF is a standard ASCII file format for describing JTAG operations. An SVF file specifies the IR values to load, the DR data to shift, and the expected responses — making JTAG test programs portable between different ATEs and JTAG controllers. SVF is used to distribute boundary scan test programs, FPGA configuration images, and flash programming sequences.
IEEE 1149.6 — High-Speed Differential Signals
Standard boundary scan cannot directly test high-speed differential pairs (PCIe, DDR, LVDS) because the boundary scan cell operates at low frequency (TCK). IEEE 1149.6 extends the standard with AC-coupled boundary scan cells that can test differential connections by injecting and detecting AC waveforms. It is used on multi-gigabit SerDes interfaces.
IEEE 1687 — IJTAG (Embedded Instruments)
IEEE 1687 (IJTAG — Internal JTAG) extends the original 1149.1 framework to provide standardized access to embedded instruments: MBIST controllers, temperature sensors, PLL calibration engines, power management units, and on-chip oscilloscopes. The key innovation is the Instrument Connectivity Language (ICL) and Procedural Description Language (PDL), which describe the scan topology and test procedures in a machine-readable way — enabling tools to automatically generate TMS/TDI sequences to reach any instrument on the chip through the JTAG TAP.
| Standard | Year | Extends | Key Addition |
|---|---|---|---|
| IEEE 1149.1 | 1990 | (base) | TAP controller, BSR, EXTEST/SAMPLE/BYPASS/IDCODE |
| IEEE 1149.1-2013 | 2013 | 1149.1 | Minor updates, SWD alternate interface |
| IEEE 1149.4 | 1999 | 1149.1 | Mixed-signal (analog) boundary scan |
| IEEE 1149.6 | 2003 | 1149.1 | AC-coupled boundary scan for differential signals |
| IEEE 1149.7 | 2009 | 1149.1 | Reduced-pin-count JTAG (2-wire: TCK+TMSC) |
| IEEE P1500 | 2005 | 1149.1 | Core Test Language Wrapper for IP blocks |
| IEEE 1687 | 2014 | 1149.1 | IJTAG — embedded instrument access via ICL/PDL |
Frequently Asked Questions
What are the 5 JTAG signals and what does each do?
TCK (Test Clock): the reference clock for all JTAG operations. TDI is sampled on the rising edge; TDO is driven on the falling edge. Independent of the system clock. TMS (Test Mode Select): sampled on every TCK rising edge; controls the 16-state TAP FSM to move between test states. TDI (Test Data Input): serial data shifted into the chip's selected register (IR or DR). TDO (Test Data Output): serial data shifted out of the chip; tri-stated when not in Shift-DR or Shift-IR state. TRST (Test Reset, optional): active-low asynchronous reset that forces the TAP to Test-Logic-Reset regardless of TCK state. Without TRST, the TAP is reset by holding TMS=1 for 5+ TCK cycles.
Describe the TAP controller states for shifting data into the DR.
Starting from Run-Test/Idle: (1) TMS=1 → Select-DR-Scan. (2) TMS=0 → Capture-DR: the selected DR latches its current parallel value into the shift cells. (3) TMS=0 → Shift-DR: each TCK rising edge shifts one bit of TDI into the register and one bit out through TDO. Stay here for as many cycles as the register length. (4) TMS=1 → Exit1-DR. (5) TMS=1 → Update-DR: the shifted-in value is latched into the DR output register, becoming the active value (e.g., for EXTEST, the BSR output cells now drive the pins). (6) TMS=0 → back to Run-Test/Idle.
What is the difference between EXTEST and SAMPLE/PRELOAD instructions?
EXTEST is the board interconnect test instruction. With EXTEST active, the chip's output pins are driven by the BSR update cells (not core logic), and input pin values are captured into BSR capture cells. This lets you inject test patterns onto PCB traces and observe what arrives at neighboring chips' pins — detecting opens, shorts, and stuck nodes on the board. SAMPLE/PRELOAD is non-destructive: the core logic continues to control the output pins normally, but the BSR simultaneously captures a snapshot of all pin values. SAMPLE is used for non-intrusive debugging. PRELOAD is used to load the BSR with the initial data pattern before switching to EXTEST, so the pin transition at the moment of EXTEST activation is controlled and glitch-free.
What is the BYPASS instruction used for?
The BYPASS instruction (IR code = all 1s) connects a single 1-bit bypass register between TDI and TDO, skipping the chip's full BSR (which could be hundreds of bits). In a JTAG daisy chain with many chips, if you need to access one specific chip, you program all other chips to BYPASS. The total effective scan chain length becomes: (target chip's register length) + (N × 1 bit, one per bypassed chip). This dramatically reduces the number of TCK cycles needed to shift data into or out of the target, speeding up test. The IEEE standard mandates that all-1s IR always decodes to BYPASS — so unknown or reset chips are always safely bypassed.
How does JTAG enable SoC debug?
Modern SoCs expose their internal debug infrastructure through the JTAG TAP. ARM CoreSight uses JTAG (or SWD) to access the Debug Access Port (DAP), which bridges to AHB/APB access ports. Through these, a debugger can: halt CPU cores via the Debug Control Register, read/write all general-purpose and system registers, read/write any memory or peripheral address, set hardware breakpoints and watchpoints, and single-step execution — all without any dedicated external logic analyzer pins. FPGA vendors use JTAG for bitstream programming and for in-system logic capture (ChipScope/SignalTap). IEEE 1687 (IJTAG) further extends this to give JTAG-based access to any embedded instrument on the chip — MBIST, PLLs, temperature sensors — using standardized ICL/PDL descriptions.