Wednesday, March 27, 2013JTAG Configuration by JavaTo drive the nail home, now let’s try configuration (rewriting the circuit) of FPGA by JTAG. Firstly, please have a try to download the Jar file (jtag_demo.jar) and execute while keeping DE0-Nano in connection with USB cable. This is supposed to be compatible to 64-bit environment, which is not tested yet though. The above image shows the result of executing 4 commands of “Reset FPGA,” “IDCODE,” “Config FPGA” and “Start Demo” one after another, for example. “Reset FPGA” is a command to forcefully configure FPGA, and, in case of DE0-Nano, loads the circuit in the EPCS64 on the board. “IDCODE” is a command to read 32-bit IDCODE of the device “EP4CE22.” “Config FPGA” is to execute a SVF file and configure FPGA. The SVF player has only crucial minimal capabilities, while many other functions such as checking TDO are left out. The last “Start Demo” enables observing I/O data via JTAG communication demonstration (except changing speed and halting by pushing buttons) which appeared in the previous article. To tell you the truth, this command can work with no error even before configuration, but then the output data cast no impact on LED. As this operation requires complicated processing such as execution of SVF and GUI, it would be all the less readable to combine all processes into single Java code. Therefore, I split it into three parts, JTAG library and basic GUI (JTAG.java) as a relatively generic part, execution of SVF (SVFPlayer.java) and demo application (JTAG_Demo.java). With a split library, the demo application part has a very simple design. A button appears in display upon the creation of a JTAG.GUI class instance. While having to describe what you’d like to run in onClick() method, you have little need to write down raw data by write() method thanks to additional methods: state() method to transit JTAG state for SVF execution and shift() method for SHIFT_DR/SHIFT_IR. SVFPlayer class is a derived class of JTAG.GUI, which requires appointing button name and resource name of SVF as generation parameters.
import info.relm.JTAG; import info.relm.SVFPlayer; public class JTAG_Demo extends JTAG { public static void main(String[] args) { GUI.title("JTAG Demo for DE0-Nano"); new GUI("Reset FPGA") { public void onClick() { reset(); state("RESET", "IRSHIFT"); shift(10, 0x1); state("IREXIT1", "IRUPDATE"); text.append("Reconfiguration done.n"); } }; new GUI("IDCODE") { public void onClick() { reset(); state("RESET", "IRSHIFT"); shift(10, 0x6); state("IREXIT1", "DRSHIFT"); readBytes(4, 0); text.append("IDCODE: " + Long.toBinaryString(0xffffffff00000000L | read(4)[0]).substring(32) + 'n'); } }; new SVFPlayer("Config FPGA", "jtag_led.svf"); new GUI("Start Demo", "Stop Demo") { public void onClick() { reset(); state("RESET", "IRSHIFT"); shift(10, 0xe); state("IREXIT1", "DRSHIFT"); shift(9, 0x100); state("DREXIT1", "DRSHIFT"); flush(); try { for (int lfsr = 1; ; Thread.sleep(10)) { readBytes(1, lfsr); shift(1, 1); state("DREXIT1", "DRSHIFT"); text.append("out: " + Integer.toBinaryString(lfsr | 256).substring(1) + "tin: " + Integer.toBinaryString(read(1)[0] | 256).substring(1) + 'n'); if (((lfsr <<= 1) & 256) != 0) lfsr ^= 0x171; } } catch (InterruptedException e) {} shift(9, 0x100); state("DREXIT1", "DRUPDATE"); } }; } } It enables FPGA configuration without setting up Quartus II. |
Tuesday, March 19, 2013JTAG Communication by JavaThe new target board DE0-Nano enables JTAG communication using download cable to communicate with host PC only by its embedded functions. DE0-Nano has a USB Blaster-compatible circuit in its body, and so allows host PC to access the board itself simply using the driver of USB Blaster. As this compatible circuit uses FT245BL produced by Future Technology Devices International Ltd. (FTDI), the driver of USB Blaster must be FTDI’s D2XX driver actually. As proof of this, it is possible to access the board just using a DLL file (ftd2xx.dll) attached to D2XX driver. The next point to be discussed is what type of data should be exchanged. Regarding this, details are available in a document relating to UrJTAG. In short, data are clammed in USB packets no longer than 64 bytes and sent out in two kinds of formats, either bit banging mode, which enables controlling all JTAG signals, or byte shift mode capable of high-speed data communication. Then, the next question is how to establish communication with host PC by JTAG. The simplest way is probably to use Virtual JTAG Megafunction for on-chip debugging. This figure shows connecting input and output pins to sld_virtual_jtag megafunction by schematic editor of Quartus II software. For here, we input and output 8-bit data, and so set the parameter sld_ir_width to 8 and sld_auto_instance_index to “YES” just in case. Connect the input pins key[7..0] to ir_out, and the output pins led[7..0] to ir_in. If you don’t want such a hassle to input codes, here you can have the block design file (jtag_led.bdf) and the sof file (jtag_led.sof) finished with logic synthesis. However, you need to specify the pin numbers and the device (EP4CE22F17C6) in case of the block design file. Write the above-shown circuit into the DE0-Nano beforehand, and execute the below-mentioned Java program on the JNA pre-installed environment. I confirmed the working only in the Windows XP environment, but probably it will work in any Win32 environment. Though it isn’t tested yet in a 64-bit environment, I expect it to work just by changing the DLL file name: “usbblstr32” –> “usbblstr64”.
import com.sun.jna.*; import com.sun.jna.ptr.*; public class JTAG_LED { static native int FT_OpenEx(String pArg1, int flags, PointerByReference pHandle); static native int FT_Close(Pointer ftHandle); static native int FT_Write(Pointer ftHandle, Pointer lpBuffer, int dwBytesToWrite, IntByReference lpdwBytesWritten); static native int FT_Read(Pointer ftHandle, Pointer lpBuffer, int dwBytesToRead, IntByReference lpdwBytesReturned); static { Native.register("usbblstr32"); } Pointer ftHandle = null; public JTAG_LED(String description) { PointerByReference pHandle = new PointerByReference(); if (FT_OpenEx(description, 2, pHandle) != 0) { throw new RuntimeException("FT_OpenEx failed."); } ftHandle = pHandle.getValue(); } public void close() { FT_Close(ftHandle); } Memory memory = new Memory(64); IntByReference ref = new IntByReference(); public static final short L = 0x2D2C; public static final short H = L | 0x1010; public static final short TMS = L | 0x0202; public static final short TMS_H = TMS | H; public static final short OFF = 0x0D0C; public void write(short... data) { memory.write(0, data, 0, data.length); FT_Write(ftHandle, memory, data.length << 1, ref); } public static final int WR = 0x81; public static final int RD = 0xC1; public static short byteshift(int data, int mode) { return (short) ((data << 8) | mode); } public byte read() { FT_Read(ftHandle, memory, 1, ref); return memory.getByte(0); } public static void main(String[] args) throws InterruptedException { JTAG_LED jtag = new JTAG_LED("USB-Blaster"); jtag.write(TMS, TMS, TMS, TMS, TMS); // TEST_LOGIC/RESET jtag.write(L, TMS, TMS, L, L); // SHIFT_IR jtag.write(byteshift(0x0e, WR), L, TMS); // USER1 instruction jtag.write(TMS, TMS, L, L); // SHIFT_DR jtag.write(byteshift(0, WR), TMS_H, TMS, TMS, L, L); // Dummy write int lfsr = 1; for (int b = 1; (b & 1) != 0;) { jtag.write(byteshift(lfsr, RD), TMS_H, TMS, TMS, L, L); if (((lfsr <<= 1) & 256) != 0) lfsr ^= 0x171; b = jtag.read() & 255; System.out.println(Integer.toBinaryString(b)); Thread.sleep(((b & 2) != 0) ? 10 : 100); } jtag.write(byteshift(0, WR), TMS_H, TMS, OFF); jtag.close(); } } Once the circuit works successfully, though this picture may not show it well, LED will start flickering rapidly. The flickering is patterned by LFSR, and so not totally randomized. It sometimes looks as if flowing to the left. The flickering gets slower by pushing the left push-button. The program stops and LED goes off by pushing the right push-button. When Java program is executed on the console, it displays the condition of input pins in binary to let us check the conditions of push-buttons and DIP switches. All these operations are regulated by host PC. As a proof, you will see LOAD LED (D4) on during operation, while the light is off at other times. This sample program is to apply the virtual instruction register (VIR) of sld_virtual_jtag megafunction for data communication, which is, indeed, a very extraordinary use. The actual processes of writing VIR are setting USER1 (0000001110) to instruction register (IR) of JTAG and then setting data for transmission and instance ID to data register (DR). As instance ID surely becomes one-bit-long “1” upon generating only one instance of megafunction, data plus “1” needs to be sent. Though JTAG-related circuit have individual clock domain and therefore require care to metastability, DCFIFO is just a “twofer” to clear the requirement and to mount FIFO. |
Saturday, March 16, 2013Target Board DE0-NanoNow I’d rather stop carrying logics on and on, and go for making a real circuit. The few but crucial shortcomings of this board are that it has only on-board 8 LEDs for displaying and that it allows access from the JTAG configuration cable as the basically only way to communicate with host PC. Compare to Arduino enabling serial communication just with a download cable…. As logic synthesis for multi-core processor takes a certain amount of time, it makes no sense if we have to do it again from the beginning every time we renew a software — the free Web Edition doesn’t support incremental compilation yet. If the board can communicate with host PC, it enables downloading software without logic synthesis, greatly enhancing efficiency in development work. Furthermore, if the board can communicate with custom application software in real-time, it will expand the sphere of what we can apply this technology to. Once I was almost disappointed at finding only such desperate efforts as to forcefully redirect console I/O of the integrated environment through the web. I’m going to upload this kind of information from time to time…. |