JTAG - Joint Test Action Group is an IEEE 1149.1 standard used in many silicon devices for programming and debugging purposes. Xilinx FPGAs support this JTAG protocol for their configuration. Here I have designed a JTAG FPGA bitstream programmer using Raspberry Pi which programs the bit file into FPGA in fraction of seconds!
JTAG physical bus has four lines:
- TMS (Test Mode Select)
- TDI (Test Data In)
- TDO (Test Data Out)
- TCK (Test Clock)
- Xilinx Spartan 3E FPGA (XC3S250E in Papilio One)
- Jumper wires
The TAP(Test Access Port) controller is a state machine inside the FPGA which changes it's state based on TMS input. For instance, let us assume that the state machine is in "Test-Logic-Reset" state. Now if I drive the TMS pin low and toggle the TCK pin, the state machine will go to "Run-Test/ Idle" state. This is how we move to different states.
Note that we don't know in which state the state machine will be once the device is switched on. But a careful observation shows that in whichever state the SM (state-machine) be, if TMS pin is held high for 5 TCK cycles, the machine goes to "Test-Logic-Reset" state. So whenever a device is switched on, if we drive TMS high for 5 cycles, it will come to Reset state.
Other important states are "SHIFT-IR" (Instruction Register) and "SHIFT-DR" (Data Register). So to do anything meaningful, we need to drive the state machine to SHIFT-IR state and send the instruction OPCODEs through TDI line. For example, in Xilinx Spartan-3 FPGAs, the device IDCODE instruction is 001001. So after shifting 001001 in TDI line while in "SHIFT-IR" state, we have to go to "SHIFT-DR" state and toggle TCK and read TDO line to receive the device IDCODE.
Now after enquiring the Device ID, we can send CFG_IN (configuration input) instruction and then program the bit stream into FPGA through TDI. The GPIO pins of Raspberry-Pi are used as TMS,TDI,TCK & TDO pins and an application written in C toggles these GPIO pins & programs the bit file into FPGA.
After programming the bit file, Raspberry-Pi shifts in JSTART instruction into IR and then executes RUN-TEST sequence which will initiate the program execution inside FPGA.