{"id":1854,"date":"2022-03-29T17:44:12","date_gmt":"2022-03-29T17:44:12","guid":{"rendered":"http:\/\/retroramblings.net\/?p=1854"},"modified":"2025-09-30T10:26:00","modified_gmt":"2025-09-30T10:26:00","slug":"jtag-and-tcl-twin-rabbitholes","status":"publish","type":"post","link":"https:\/\/retroramblings.net\/?p=1854","title":{"rendered":"JTAG and Tcl &#8211; twin rabbitholes!"},"content":{"rendered":"\n<p><strong>2022-03-29<\/strong><\/p>\n\n\n\n<p>I&#8217;ve been experimenting with the QMTech Kintex7 board, which provides a huge FPGA for a less huge amount of money.  The one thing that prevents my existing projects from running on it without deep changes is the lack of SDRAM, but since I&#8217;ve been wanting to get more familiar with the Xilinx ecosystem for a while, this was a good opportunity to dive in.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>Firstly, it should be noted that the Kintex 7 XC7K325T part on this board is *not* supported by the free version of Vivado &#8211; which means if you want an out-of-the-box experience you need to use ISE.  If you&#8217;re willing to ride the bleeding edge, then Project X-Ray already has initial support for this chip &#8211; so the future of this board with the Open Source toolchain should be very interesting!  (See https:\/\/github.com\/kintex-chatter for a collection of works-in-progress.)<\/p>\n\n\n\n<p>For now, though, I&#8217;m going to turn my attention to ISE.  The last version released was 14.7, and the WebPack Edition also doesn&#8217;t support the XC7K325T &#8211; however, Embedded Edition does, and at the time of writing, it&#8217;s also free.<\/p>\n\n\n\n<p>It requires some finessing to make it work on a modern Linux distro &#8211; something which can also be said about the older versions of Quartus required for Cyclone II and III support &#8211; I&#8217;ve been collecting together some information on this subject here: <a href=\"https:\/\/github.com\/robinsonb5\/FPGAToolchainQuirks\">https:\/\/github.com\/robinsonb5\/FPGAToolchainQuirks<\/a><\/p>\n\n\n\n<p>The last time I had any real exposure to Xilinx devices I was using the venerable &#8220;Platform Cable USB&#8221;, and surprise no. 1 was the discovery that this device isn&#8217;t well supported outside of Xilinx&#8217;s own software: OpenOCD doesn&#8217;t support it, OpenFPGALoader doesn&#8217;t support it, URJTAG has support which it describes as &#8220;Slow, experimental &#8211; don&#8217;t use.&#8221;<\/p>\n\n\n\n<p>There&#8217;s an alternative firmware which can be uploaded into the Platform Cable to make it behave like a USB Blaster &#8211; but I haven&#8217;t yet had any success with this, using either a Platform Cable DLC9, or a Platform Cable II DLC10.<\/p>\n\n\n\n<p>XC3SProg *does* support the Platform Cable USB, however.<\/p>\n\n\n\n<p>For the EightThirtyTwo CPU I have a rudimentary Debug interface which works by transmitting 32-bit words over an Intel Virtual JTAG interface, and bridging that to TCP\/IP by way of a Tcl script.  I wanted to be able to do the same with a Xilinx chip.  Tcl isn&#8217;t a necessary part of the equation &#8211; simply bridging directly from JTAG to TCP\/IP would be sufficient to use the 832 debugger &#8211; however, Tcl does allow some interesting things to be done with Tk (for instance, I have a demo which allows the colour of an FPGA-controlled VGA screen to be set using sliders on a GUI running on the PC.)  So Tcl support is filed under &#8220;Nice to have&#8221;.<\/p>\n\n\n\n<p>Surprise no. 2 was the discovery that Tcl extensions are *ridiculously* easy to write!<\/p>\n\n\n\n<p>I started with a copy of the source to the xc3sprog executable, to create a libtcljtag.so shared library, which can be loaded using Tcl&#8217;s load command.  I set it to build with -fPIC (required to avoid relocation issues when building theshared library) and created a simple class to wrap the JTAG manipulation functions, exposing them as Tcl commands.<\/p>\n\n\n\n<p>So far the following commands are defined (all under the jtag:: namespace):<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>get_cables<\/code> &#8211; returns a Tcl list of cables supported by xc3sprog.<\/li><li><code>open_cable cablename<\/code> &#8211; opens the specified cable (for \nexample: &#8220;jtag::open_cable xpc&#8221; will open the Xilinx Platform Cable).  \nReturns the number of devices found on the JTAG chain if successful.<\/li><li><code>close_cable<\/code> &#8211; closes and releases the currently-open cable, if any.<\/li><li><code>select_device<\/code> &#8211; addresses shift_ir and shift_dr commands to the specified device in the chain.<\/li><li><code>get_device_id device<\/code> &#8211; return a 32-bit integer device ID of the specified device in the chain.<\/li><li><code>get_device_description device<\/code> &#8211; looks up the device ID of the specified device in the devlist.txt file and returns the name of the device, if found.<\/li><li><code>detect_chain<\/code> &#8211; re-scans the JTAG chain<\/li><li><code>shift_ir value<\/code> &#8211; shifts the specified value in the Instruction Register of the currently selected device in the chain, passing through the <code>Update_IR<\/code> JTAG state when done.<\/li><li><code>shift_dr value length<\/code> &#8211; Passes through the <code>Capture_DR<\/code>\n JTAG state, then shifts the specified value and number of bits into the\n Data Register of the currently selected device in the chain, passing \nthrough the <code>Update_DR<\/code> state when done.  Returns the captured value.<\/li><\/ul>\n\n\n\n<p>Using the TclJTAG extension to talk to a design on an FPGA might look something like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Load the extension\nload \"\/path\/to\/libtcljtag.so\"\n\n# Open the cable\njtag::open_cable xpc\n\n# Fetch a description of the first device in the chain...\nset desc [jtag::get_device_description 0]\n\n# Is it a Xilinx Series 7 FPGA?\nif { [string match \"XC7*\" $desc] } {\n\n\t# Select the USER3 register\n\tjtag::shift_ir 0x22\n\n\t# Shift a 32-bit value into the USER3 register, and fetch its captured contents.\n\tset d [jtag::shift_dr 0x12345678 32]\n\n\t# Print the fetched value\n\tputs [format 0x%x d]\n}\n\n# And finally close the cable\njtag::close_cable<\/code><\/pre>\n\n\n\n<p>This works from the systemwide tclsh environment, and just for fun I tried doing the same from a &#8220;quartus_stp -s&#8221; session. I had to remove the libstdc++ library from the Quartus installation, to make it use the systemwide one instead &#8211; and yes, it works!<\/p>\n\n\n\n<p>I&#8217;m sure I shall find other uses for this in future, but for now it means that that EightThirtyTwo debug interface can be used on Xilinx chips (Tested on Spartan6, Artix7 and Kintex7 &#8211; defined but not tested for Spartan 3, too.) as well as Altera\/Intel chips.<\/p>\n\n\n\n<p>It&#8217;s entirely possible I&#8217;m the only person on the planet who actually wants this &#8211; but just in case anyone else does, the TclJTAG extension can be found here: <a href=\"https:\/\/github.com\/robinsonb5\/xc3sprog\">https:\/\/github.com\/robinsonb5\/xc3sprog<\/a> !<\/p>\n\n\n\n<p>Have fun!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>2022-03-29 I&#8217;ve been experimenting with the QMTech Kintex7 board, which provides a huge FPGA for a less huge amount of money. The one thing that prevents my existing projects from running on it without deep changes is the lack of &hellip; <a href=\"https:\/\/retroramblings.net\/?p=1854\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,4,9,8,13],"tags":[],"class_list":["post-1854","post","type-post","status-publish","format-standard","hentry","category-eightthirtytwo","category-fpga","category-geekery","category-hardware","category-linux"],"_links":{"self":[{"href":"https:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts\/1854","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1854"}],"version-history":[{"count":3,"href":"https:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts\/1854\/revisions"}],"predecessor-version":[{"id":1858,"href":"https:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts\/1854\/revisions\/1858"}],"wp:attachment":[{"href":"https:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1854"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1854"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1854"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}