Blog
[measured] A note recorded 100 kHz as the only stable JTAG clock for this cable. openFPGALoader ran the same cable at 6 MHz and programmed a bitstream OpenOCD could not start.
A note in this repository, written in June and verified on hardware at the time, records 100 kHz as the only stable JTAG clock for one particular USB cable. Higher speeds, it says, produce garbage IDCODEs or hang the MPSSE engine. The configuration file carries the same warning in a comment. Today the same cable, the same board and the same host ran at 6 MHz and programmed a bitstream that OpenOCD could not deliver at all.
The recorded figure was not wrong. It was a property of the instrument that measured it, and the note attributed it to the cable.
Running the project configuration unmodified, OpenOCD identified the chain correctly at 100 kHz and then stopped. Not slowly — completely.
Info : JTAG tap: xc7.tap tap/device found: 0x13636093
Warn : Haven't made progress in mpsse_flush() for 32124ms.
Warn : Haven't made progress in mpsse_flush() for 64252ms.
Warn : Haven't made progress in mpsse_flush() for 128008ms.
The doubling intervals are the tool's own backoff: it reports at 32, 64 and 128 seconds because nothing has moved between them. An earlier attempt had been killed at ten minutes on the theory that a 9.73 MB bitstream at 100 kHz simply needs about thirteen. That arithmetic is right and it was the wrong explanation.
The obvious suspect is the pin layout, since the same note records that a neighbouring stock configuration hangs with this cable. It is not that. The project configuration declares layout_init 0x00e8 0x60eb, which is byte-identical to the stock digilent_jtag_smt2_nc.cfg it says to prefer. Same vendor and product identifiers, same channel. Nothing in the file distinguishes the working case from the failing one.
openFPGALoader --detect -c digilent_hs2
Jtag frequency : requested 6.00MHz -> real 6.00MHz
idcode 0x3636093, artix a7 200t, irlength 6
openFPGALoader -c digilent_hs2 blinky.bit
Load SRAM: [==================================================] 100.00%
ir: 1 isc_done 1 isc_ena 0 init 1 done 1
Sixty times the recorded speed, and it finished. Both tools read the same IDCODE from the same silicon; only one of them could write to it.
| OpenOCD | openFPGALoader | |
|---|---|---|
| reads the chain | yes, at 100 kHz | yes, at 6 MHz |
| programs the part | no progress in 128 s | complete, DONE asserted |
| configuration | stock SMT2-NC layout | built-in digilent_hs2 |
100 kHz belongs to OpenOCD's FTDI backend on this host, not to the cable and not to the board. The note has been amended in place rather than replaced, because a figure that was true of one instrument is still a true measurement of that instrument — it was the attribution that needed fixing. The same shape appeared twice this week in unrelated work: two synthesis tools disagreeing about area because one preserves debug logic by attribute and the other by port. Name the instrument with the number, or the number will be read as a property of the thing measured.
Earlier in the same session the place-and-route step refused a netlist:
ERROR: Failed to parse JSON file: unexpected end of input in string.
That reads as a defect in the netlist writer or the reader. It was neither. The host volume had 246 MB free of 460 GB; the synthesis step wrote a truncated file and exited zero, and the next tool in the chain reported the truncation as a parse error. The lesson is one command long: check free space before debugging a generated file.
DONE asserted means the device accepted a configuration. It is not an observation of the design running: no LED state was recorded here, and the bitstream loaded was a counter, not a datapath under test. The comparison is also one cable, one host and one session — it does not establish that OpenOCD fails on other hosts, other cables, or other transports. What it establishes is narrower and sufficient: on this configuration the recorded speed limit was not a property of the hardware, and one tool completed a job the other could not start.
Work with me
I audit RTL and build independent, bit-exact models, then take the result through synthesis and, when useful, onto an Artix-7 board. The first conformance module is free.