The test logic consists of a Boundary-Scan register and other building blocks. The test logic is accessed through what is commonly referred to as the Test Access Port or TAP. The TAP consists of 6 pins
| Name | Type | Description |
|---|---|---|
| TCK | Input | JTAG Clock |
| TDO | Output | JTAG Serial Data Out |
| TDI | Input | JTAG Serial Data In |
| TMS | Input | JTAG Mode Select |
| TRST | Input | JTAG Reset |
| EMU | Output | Emulation Output |
The JTAG controller is a synchronous, 16-state, finite-state machine controlled by the TCK and TMS pins. Transitions to the various states in the diagram occur on the rising edge of TCK and are defined by the state of the TMS pin, here denoted by either a logic 1 or logic 0 state.
Here we can see what things look like from a logic analyzer. (when the JTAG clock is clocking things at 10MHz, and the Logic Analyzer is sampling at 200MHz).
The way this works is that the above state diagram is followed, decoding the TMS (mode select) pin. The TDI and TDO pins are used to shift data in and out of the JTAG registers, (JTAG Instruction Registers, and JTAG data registers). For example, 13 TCK rising edges occur while TMS is zero. This will loop things in the RUN-TEST/IDLE state. Then it clocks in two ones. This will move things to the Select-IR-Scan state. A zero moves it to the capture-IR, and 5 more clocks, shift the TDI into the JTAG Instruction register (in time, it shifts 1100100 into the IR).
The Instruction register is five bits wide and accommodates up to 32 boundary-scan instructions. The Instruction register holds both public and private instructions. The JTAG standard requires some of the public instructions; other public instructions are optional. Private instructions are reserved for the manufacturer’s use.
Since the IR is only 5 bits long, it keeps 00100.. The JTAG Instruction Register (IR) is just a pointer into which JTAG data register data should be passed. These are defined for the Blackfin as:
| JTAG Instruction | Bits 43210 | Register Name | Length of Chain | Last Bit Scanned | R/W |
|---|---|---|---|---|---|
| bypass | 11111 | BYPASS | |||
| extest | 00000 | BOUNDARY | |||
| sample/Preload | 00001 | BOUNDARY | |||
| emuIr | 00010 | EMUIR | 32/48/64 | LSB | W |
| emctl | 00100 | EMUCTL | 16 | LSB | W |
| emudat | 00101 | EMUDAT | 32/40/48 | LSB | W |
| emustat | 00110 | EMUSTAT | 16 | LSB | W |
| idcode | 01000 | IDCODE | 32 | MSB | RO |
| Membist | 01010 | MEMBIST | 64 | LSB | |
| tmkey | 01100 | TMKEY | |||
| cskey | 01101 | CSKEY | |||
| samplepc | 01111 | EMUPC | 32 | LSB | RO |
We can see that 00100 is EMUCTL. The remaining transactions write something into the Debug Control Register.
The bitstream below is the communication between and emulator, and a BF533 during a reset instruction. You can see that this is rather complex, and decoding of the serial bit stream would be a little tedious to do by hand – making the effort of a small piece of software to decode things worthwhile. Luckily, a many logic analyzers have the ability to capture and post process data, which be used to follow the JTAG states.
For example, with VDSP, scanning the ID code looks something like (data is captured on the rising edge of TCLK, and each “cycle” is a full cycle of TCLK:
0 : TMS: 0 RST: 0 TDI: 0 TDO: 0 ~EMU: 0 Test Logic Reset - 28
29 : TMS: 0 RST: 1 TDI: 0 TDO: 0 ~EMU: 1 Run Test Idle - 12
42 : TMS: 1 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 Select DR SCAN
43 : TMS: 1 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 Select IR SCAN
44 : TMS: 0 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 IR - Capture
45 : TMS: 0 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 IR - Shift 5 IN:08 OUT:10
51 : TMS: 1 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 IR - Update IR = 08 Id Code
52 : TMS: 1 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 Select DR SCAN
53 : TMS: 0 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 DR - Capture
54 : TMS: 0 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 DR - Shift 32 IN:0000005a OUT:327a50cb
87 : TMS: 1 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 DR - Update Id Code = 0000005a
88 : TMS: 0 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 Run Test Idle - 32
121 : TMS: 1 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 Select DR SCAN
122 : TMS: 1 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 Select IR SCAN
123 : TMS: 0 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 IR - Capture
124 : TMS: 0 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 IR - Shift 5 IN:08 OUT:10
130 : TMS: 1 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 IR - Update IR = 08 Id Code
131 : TMS: 1 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 Select DR SCAN
132 : TMS: 0 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 DR - Capture
133 : TMS: 0 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 DR - Shift 32 IN:0000005a OUT:327a50cb
166 : TMS: 1 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 DR - Update Id Code = 0000005a
167 : TMS: 0 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 Run Test Idle - 32
200 : TMS: 1 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 Select DR SCAN
201 : TMS: 1 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 Select IR SCAN
202 : TMS: 0 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 IR - Capture
203 : TMS: 0 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 IR - Shift 5 IN:08 OUT:10
209 : TMS: 1 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 IR - Update IR = 08 Id Code
210 : TMS: 1 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 Select DR SCAN
211 : TMS: 0 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 DR - Capture
212 : TMS: 0 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 DR - Shift 32 IN:0000005a OUT:327a50cb
245 : TMS: 1 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 DR - Update Id Code = 0000005a
246 : TMS: 0 RST: 1 TDI: 1 TDO: 0 ~EMU: 1 Run Test Idle - 32
For many of the scan chains (or JTAG Instruction Registers), what comes in will be written to the register, and what comes out is the status. For example, you can not just read the EMUSTAT, because it is a pseudo read-only status register – that includes two sticky bits (EMUDIOVF and EMUDOOVF) which are cleared by writing 1s to the corresponding bits. If a specific routine does not want to clear these bits, they must ensure zeros are shifted in for these bit positions during a read.
Many low level routines available for various low cost cables to not have this capabilities, and have separate routines for sampling tdo, and shifting out tdi. For some of the JTAG scan chains, this is acceptable, but not for the ones marked R/W.
For example, in the jtag project , in the file
file: /trunk/jtag/src/tap/cable/byteblaster.c:byteblaster_clock()
byteblaster_clock( cable_t *cable, int tms, int tdi ) { tms = tms ? 1 : 0; tdi = tdi ? 1 : 0; parport_set_data( cable->port, (0 << TCK) | (tms << TMS) | (tdi << TDI) ); cable_wait(); parport_set_data( cable->port, (1 << TCK) | (tms << TMS) | (tdi << TDI) ); cable_wait(); }
file: /trunk/jtag/src/tap/cable/byteblaster.c:byteblaster_get_tdo()
byteblaster_get_tdo( cable_t *cable ) { parport_set_data( cable->port, 0 << TCK ); cable_wait(); return (parport_get_status( cable->port ) >> TDO) & 1; }
Here you can see that the function only shifts things into the TAP, without returning the state of TDO.
When the jtag project is run on a Linux host (as root), controlled as the following:
pinky: # ./jtag JTAG Tools 0.5.1 Copyright (C) 2002, 2003 ETC s.r.o. JTAG Tools is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. There is absolutely no warranty for JTAG Tools. Warning: JTAG Tools may damage your hardware! Type "quit" to exit! Type "help" for help. jtag> cable parallel 0x378 ByteBlaster Initializing Altera ByteBlaster/ByteBlaster II/ByteBlasterMV Parallel Port Download Cable on parallel port at 0x378 jtag> detect IR length: 5 Chain length: 1 Device Id: 00110010011110100101000011001011 Manufacturer: Analog Devices Part: BF533 Stepping: 10 Filename: /usr/local/share/jtag/analog/bf533/bf533
Generates the following JTAG information:
0 : TMS: 0 RST: 0 TDI: 0 TDO: 0 ~EMU: 0 Test Logic Reset - 42
43 : TMS: 0 RST: 1 TDI: 1 TDO: 0 ~EMU: 0 Run Test Idle
44 : TMS: 1 RST: 1 TDI: 0 TDO: 1 ~EMU: 0 Select DR SCAN
45 : TMS: 1 RST: 1 TDI: 0 TDO: 1 ~EMU: 0 Select IR SCAN
46 : TMS: 1 RST: 1 TDI: 0 TDO: 1 ~EMU: 0 Test Logic Reset - 2
49 : TMS: 0 RST: 1 TDI: 0 TDO: 1 ~EMU: 0 Run Test Idle
50 : TMS: 1 RST: 1 TDI: 0 TDO: 0 ~EMU: 0 Select DR SCAN
51 : TMS: 1 RST: 1 TDI: 0 TDO: 0 ~EMU: 0 Select IR SCAN
52 : TMS: 1 RST: 1 TDI: 0 TDO: 0 ~EMU: 0 Test Logic Reset - 2
55 : TMS: 0 RST: 1 TDI: 0 TDO: 0 ~EMU: 0 Run Test Idle
56 : TMS: 1 RST: 1 TDI: 0 TDO: 0 ~EMU: 0 Select DR SCAN
57 : TMS: 1 RST: 1 TDI: 0 TDO: 0 ~EMU: 0 Select IR SCAN
58 : TMS: 0 RST: 1 TDI: 0 TDO: 0 ~EMU: 0 IR - Capture
59 : TMS: 0 RST: 1 TDI: 0 TDO: 0 ~EMU: 0 IR - Shift 4647 IN:1f OUT:00
4707 : TMS: 1 RST: 1 TDI: 0 TDO: 0 ~EMU: 0 IR - Update IR = 1f Bypass
4708 : TMS: 0 RST: 1 TDI: 0 TDO: 0 ~EMU: 0 Run Test Idle
4709 : TMS: 1 RST: 1 TDI: 0 TDO: 0 ~EMU: 0 Select DR SCAN
4710 : TMS: 0 RST: 1 TDI: 0 TDO: 0 ~EMU: 0 DR - Capture
4711 : TMS: 1 RST: 1 TDI: 0 TDO: 0 ~EMU: 0 DR - Exit1
4712 : TMS: 1 RST: 1 TDI: 0 TDO: 0 ~EMU: 0 DR - Update Bypass = 00000000
4713 : TMS: 1 RST: 1 TDI: 0 TDO: 0 ~EMU: 0 Select DR SCAN
4714 : TMS: 1 RST: 1 TDI: 0 TDO: 0 ~EMU: 0 Select IR SCAN
4715 : TMS: 1 RST: 1 TDI: 0 TDO: 0 ~EMU: 0 Test Logic Reset
4716 : TMS: 0 RST: 1 TDI: 0 TDO: 0 ~EMU: 0 Run Test Idle
4717 : TMS: 1 RST: 1 TDI: 0 TDO: 0 ~EMU: 0 Select DR SCAN
4718 : TMS: 0 RST: 1 TDI: 0 TDO: 0 ~EMU: 0 DR - Capture
4719 : TMS: 0 RST: 1 TDI: 0 TDO: 0 ~EMU: 0 DR - Shift 65 IN:ffffffffffffffff OUT:a614bc99ffffffff
4785 : TMS: 1 RST: 1 TDI: 0 TDO: 1 ~EMU: 0 DR - Update Extest = ffffffff
4786 : TMS: 0 RST: 1 TDI: 0 TDO: 1 ~EMU: 0 Run Test Idle
According to the JTAG specification (Table 7-1 —Instruction register operation in each controller state), during the Test-Logic Reset state, the IR is set to give the IDCODE or BYPASS instruction. This means that the above is not guaranteed to work on all devices, because it does not set the IDCODE Instruction before shifting out the information. Since the Blackfin does in fact set the IDCODE to be shifted out on a Test-Logic Reset state, this does work properly on this device.
The data that is shifted out is 0xa614bc99ffffffff, which is
0b1 1010 0110 0001 0100 1011 1100 1001 1001 1111 1111 1111 1111 1111 1111 1111 1111 when bit reversed is 0b1 1111 1111 1111 1111 1111 1111 1111 1111 0011 0010 0111 1010 0101 0000 1100 1011
Which, when the leading ones are removed, is 0x327a50cb or the value that is specified in the Hardware reference manual.