Reading Device DNA on Spartan 3A chip

Among Spartan-3 generation of FPGAs only families 3A and 3AN have unique device identifier (device DNAs). DNA is a factory programmed unique 57-bit long number, whose the most significant bit is "1" and the second most significant bit is "0":

The Spartan 3A chip (xc3s50a) should be unconfigured (not loaded with any bit-stream either from SPI or JTAG), otherwise attempts to read the DNA will results in getting zeros.

I've tried reading DNA using:

  • Impact (from Xilinx ISE) with Digilent HS-3 cable
  • UrJTAG with FT232H adapter
  • OpenOCD with FT232H adapter
  • fireprog (my version of fpgaprog and Papilio-Loader) with FT232H adapter
  • A custom VHDL code with displaying on actual hardware (7-segment displays)

Reading DNA using Impact and Digilent HS-3 Programming Cable

Suppose that Xilinx ISE is located at "/media/Windows" folder, so in order to be able to use Xilinx commands such as "impact" we need to run "settings64.sh" script in BASH. Other shells won't work. This script updates $PATH variable, making "impact" callable from the terminal. Reading DNA of a device can be done only in batch mode, GUI mode does not have this feature. When auto-identification of the programming cable is on ("setcable -port auto"), impact finds my Digilent HS-3 cable connected to the Prometheus FPGA board via JTAG port.

which is 0x15598B2C3ED7DBF in hexadecimal.

Reading DNA using UrJTAG and FT232H-based JTAG Adapter

My custom Prometheus FPGA board has FTDI's FT232H chip with vendor ID 0x0403 and product ID 0x6014 which is used as a JTAG adapter and programmer. This chip requires either libftdi or libftd2xx driver to communicate with a PC. Reading DNA is easy, but the Spartan 3A chip should be set into a blank mode first:

Note that, DNA is displayed in the reverse order, so the actual value is:

which is the same as the one read in Impact.

DATAREG is defined in "/usr/share/urjtag/xilinx/xc3s50a/xc3s50a" as a 57-bit long register:

Unfortunately, the device description file is incomplete, so I had to look into the official BSDL file in my Xilinx ISE distribution:

and define these instructions in the UrJTAG's command line. Every instruction should be associated with a data register which it affects.

Reading DNA using OpenOCD and FT232H-based JTAG Adapter

OpenOCD has a nice scripting support. Let's define a cable driver in a separate file FT232H.cfg:

Test access point (XC3S50A chip) and DNA reader can be defined in another file called Prometheus.cfg

Start OpenOCD server in terminal:

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

A DNA read is exactly same as the DNA read by Impact.

Reading DNA using fireprog

Papilio-Loader and fpgaprog have a bug in the DNA reader code. The bit order of the DNA should be reversed. My version of these programs called "fireprog" was adapted for the Prometheus board and has this bug fixed:

A VHDL code for Reading and Displaying DNA on Prometheus FPGA

Based on documentation of the DNA register ("Spartan-3 Generation Configuration User Guide" (UG332)) I wrote a VHDL code to read and display device DNA on Prometheus FPGA board. It uses DNA_PORT primitive to access the DNA register. The source code resides in: https://github.com/isabekov/DNA_Reader_Prometheus

Here are the photos of the board displaying the device DNA:

References

"Spartan-3 Generation Configuration User Guide" (UG332)
OpenOCD configuration for Xilinx XC6S