JTAG nonfunctional after configuration (how to use KEY_VERIFY jtag command?) - Page 1
Forum section: electronics / general

author: mtwieg
author_rank: Frequent Contributor
timestamp: April 13, 2025, 01:14:06 pm
content: Hi all, we've been debugging a bizarre issue with a Intel FPGA. I am not an FPGA specialist, and our problem is likely pretty deep, but I'm only looking for help with one narrow facet of the issue:The TLDR version of my question is: how can I use the KEY_VERIFY jtag command on a Intel FPGA using a USB-blaster?Here's the background for those with the time to read:The basic setup is the FPGA (an Arria V) uses a micron flash memory (MT25QL256) to store the configuration. MSEL pins are set up for active serial x1.What we are experiencing is that randomly after a power cycle the configuration seems to be corrupted. Often this results in the FPGA getting stuck in its configuration loop (CONF_DONE and nSTATUS held low). In this state, JTAG still works so we can use a USB blaster or jrunner from an external MCU to bring it back. I'll call this case 1.But in some occasions we get a much more baffling result, I'll call this case 2. The FPGA apparently finishes its configuration (CONF_DONE and nSTATUS both high). But the FPGA clearly isn't working as expected (not producing or responding to IO). Strangest of all, it cannot be detected by the USB blaster via JTAG. The JTAG Chain debugger tool reports "JTAG chain problem detected" and "No device detected". I have verified all supply rails, pullup resistors, and other connections are good though. I get the same result with multiple USB blasters (both from Terasic and Altera).In case 2, I've found that if I manually pull nCONFIG low, JTAG can once again see the device normally. If I change the MSEL pins to default to passive serial, then power cycle, then the FPGA will behave much like case 1, and I can reconfigure things via JTAG.Obviously the question of how the flash got corrupted in the first place is the million dollar question, butright now I'm focusing on figuring out why the JTAG stops workingin case 2. After a lot of googling, the only mechanism I can find which can explain the JTAG issue is theDesign Security Feature. I foundthis page from Intelsuggesting to use the KEY_VERIFY jtag command as a means to determine whether this feature is enabled. I've tried using the "JAM File for 28-nm FPGAs" suggested in that article with the command "quartus_jli.exe -aVERIFY -c 1 verifykey_av.jam", but it simply reports a syntax error.And at that point I don't know what else to do. Can't find any guidance on why Intel's own suggested JAM file doesn't work, or alternative ways to use the KEY_VERIFY command. I'm guessing such a thing is trivial for someone more familiar with JTAG, but that's not me.Thanks in advance!

author: mtwieg
author_rank: Frequent Contributor
timestamp: April 16, 2025, 12:03:19 pm
content: Ok maybe I'll have more luck if I focus on a different aspect of our issue....We dumped the contents of the flash on one of the boards suffering from case #2, the attached image shows the diffs. Basically just ~20 bytes cleared, all near the start of the image. If we start with a good flash, then manually erase a few of these bytes, then that board will also behave like in case #2.Based on my reading of the device handbook, during AS configuration the entire bitstream is checked via CRC automatically, and that any CRC mismatch should result in a configuration error which will prevent CONF_DONE and from asserting, the FPGA will repeatedly try to configure itself forever:QuoteWe've done exactly as suggested in that last line, and it doesn't seem to actually work.I suspect that the little section of the image with non-FF contents shown in the attachment is actually some sort of lookup table or header, and maybe it's not checked by the crc...Another question that occurs to me regarding the crc checking: There's an optional CRC_ERROR pin which is meant to indicate the result of the CRC checking. But unlike CONF_DONE, nSTATUS, etc, this function is not enabled by default, it has to be enabled by the configuration itself (unfortunately the board designer allocated this pin to another signal, so we can't really use it...). So this means the pin won't actually function until after the device enters user mode. But shouldn't a bad CRC prevent user mode in the first place, meaning the CRC_ERROR signal would never be useful???