Using UrJTAG and OpenOCD to Write to a BSCAN Primitive on Xilinx Spatan 3 FPGAs

There are no tutorials explaining the use of BSCAN_SPARTAN3 primitive on Xilinx FPGAs. It's a very useful feature, which allows to literally establish a PC-to-FPGA link over a JTAG adapter. This primitive is already used in projects such as xc3sprog and Papilio-Loader to program SPI flash memory over JTAG.

BSCAN_SPARTAN3 is actually not a good name for this primitive. According to the JTAG standard, the Boundary Scan register must exist and control the input/output pins of the circuit. BSCAN_SPARTAN3 should have been named as "USER1" or "USER2" register since the corresponding instructions select this register.

Anyways, below is the VHDL code which allows accessing BSCAN_SPARTAN3 primitive. The primitive is invoked as a "component" in VHDL. Its outputs are mapped to the top architecture. USER1 register is called SHIFT_REGISTER in this design. The length of this register can be arbitrarily large, but in our code it is 8, so that register can hold only one byte of information. TDI is mapped to the most significant bit of the register, and TDO is mapped to the least significant bit of the register. So when one byte of information is shifted in through TDI, the old content of the register is shifted out.

Every bit of the shift register is mapped to a LED. Here is the user constraints file for the Prometheus board:

Writing data using UrJTAG

Writing data into SHIFT_REGISTER:

  1. Shift opcode 0x02 into the instruction register. Execute it. USER1 register ("SHIFT_REGISTER" in VHDL) will be selected as data register.
  2. Shift a sequence of bits into the data register. We defined it to be 8-bit long.

Firstly, we need to select the cable driver. The Promethus FPGA board has a FT232H chip which is used as a JTAG adapter. For this purpose, we use "ft2232" driver which uses MPSSE capabilities of the FTDI chip. Then we detect the device in the chain in order to load corresponding description file. It contains instruction length information which is needed to define new instructions. UrJTAG's description file is incomplete so we have to refer to $XILINX_ISE/14.7/ISE_DS/ISE/spartan3a/data/xc3s50a.bsd to look USER1 instruction up. Its opcode is 0b000010 or 0x02.

After executing USER1 instruction, TDI will be connected to USER1 register which we've defined in the VHDL file above as "SHIFT_REGISTER". UrJTAG has to know its length before shifting anything throughout the TDI line. Our shift register is 8-bit long. Specifying bit-stream, which will be written to the selected data register, is done by using the "dr" command.

Another end of the USER1 register is connected to TDO, so shifting the bit-stream by using "shift dr" command will return another bit-stream, which is the old content of the USER1 register:

Writing data using OpenOCD

OpenOCD has low-level JTAG commands as well. Exactly same operations done with UrJTAG can be rewritten as a procedure in a configuration script. Here is the content of the Prometheus_BScan.cfg file with all necessary definitions:

Content of the FT232H.cfg file, which describes JTAG adapter:

Start OpenOCD server in terminal:

In another terminal connect to the running OpenOCD server and run send_byte script:

Here is the state of the Prometheus board after writing 0x93 to the USER1 register:

Here is the state of the Prometheus board after writing 0xA1 to the USER1 register: