{"id":19976,"date":"2026-06-18T09:14:28","date_gmt":"2026-06-18T13:14:28","guid":{"rendered":"https:\/\/fpganow.com\/?p=19976"},"modified":"2026-06-18T09:14:30","modified_gmt":"2026-06-18T13:14:30","slug":"building-a-project-that-exercises-the-gpios-fifos-and-dma-on-the-arty-z7-20","status":"publish","type":"post","link":"https:\/\/fpganow.com\/index.php\/2026\/06\/18\/building-a-project-that-exercises-the-gpios-fifos-and-dma-on-the-arty-z7-20\/","title":{"rendered":"Building a Project That Exercises the GPIOs, FIFOs, and DMA, on the Arty Z7-20"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">I wanted to create a project suitable for beginners that does more than your average hello world sample out there on the internet. The project I created that will be described on this page and will show you how to run an augmented hello world that includes:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A GPIO example that is wired up to an accumulator implemented using RTL (Verilog)<\/li>\n\n\n\n<li>A FIFO loopback test<\/li>\n\n\n\n<li>A DMA FIFO loopback test<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Additionally, this example can be run in multiple ways, all from the command line or by using the Vitis User Interface:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Bare-Metal<\/li>\n\n\n\n<li>FreeRTOS\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.freertos.org\/\" target=\"_blank\" rel=\"noopener\">https:\/\/www.freertos.org\/<\/a><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">If you are a beginner, I hope this saves you a lot of time.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Getting Started<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1 &#8211; Download and Install:<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Vivado 2024.1\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.xilinx.com\/support\/download\/index.html\/content\/xilinx\/en\/downloadNav\/vivado-design-tools\/2024-1.html\" target=\"_blank\" rel=\"noopener\">https:\/\/www.xilinx.com\/support\/download\/index.html\/content\/xilinx\/en\/downloadNav\/vivado-design-tools\/2024-1.html<\/a><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Vitis 2024.1\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.xilinx.com\/support\/download\/index.html\/content\/xilinx\/en\/downloadNav\/vitis\/2024-1.html\" target=\"_blank\" rel=\"noopener\">https:\/\/www.xilinx.com\/support\/download\/index.html\/content\/xilinx\/en\/downloadNav\/vitis\/2024-1.html<\/a><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">2 &#8211; Connect your Arty Z7-20 to your machine via USB<\/h3>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"758\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-36.png\" alt=\"\" class=\"wp-image-20052\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-36.png 600w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-36-237x300.png 237w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">3 &#8211; Clone the Git Repository<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir -p ~\/work\/artyz7\ncd ~\/work\/artyz7\ngit clone git@github.com:FpgaJohn\/arty_hw.git<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Manual Recreation of Project<\/h2>\n\n\n\n<p><span style=\"color: #ff0000;\"><em><strong>NOTE:<\/strong><\/em> You must set the Arty Z7-20 jumper to JTAG, otherwise the commands will not work out-of-the box:<\/span><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"714\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-35.png\" alt=\"\" class=\"wp-image-20050\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-35.png 600w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-35-252x300.png 252w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">1 &#8211; Open Vivado and Recreate Block Design<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code># Source Vivado Tools\n&nbsp;. \/tools\/Xilinx\/Vivado\/2024.1\/settings64.sh\n\n# Launch Vivado\nvivado &amp;<\/code><\/pre>\n\n\n\n<p>Find the TCL Console at the bottom of Vivado, and navigate to the arty_hw\/vivado directory and source the arty_hw.tcl TCL script.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd .\/arty_hw\/vivado\nsource .\/arty_hw.tcl<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"430\" height=\"323\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-2.png\" alt=\"\" class=\"wp-image-20000\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-2.png 430w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-2-300x225.png 300w\" sizes=\"auto, (max-width: 430px) 100vw, 430px\" \/><\/figure>\n\n\n\n<p>Inspect the block design and you will see:<\/p>\n<ul>\n<li>A Dual channel GPIO with all Outputs set and connected to a custom IP Block named &#8220;my_state&#8221;<\/li>\n<li>A Dual channel GPIO with all Inputs set and connected to the output of the same custom IP Block named &#8220;my_state&#8221;<\/li>\n<li>An AXI-Stream FIFO (4.3) configured to use AXI4-Lite as its interface and whose TXD is connected to its RXD port<\/li>\n<li>An AXI Direct Memory Access (7.1) IP Block configured with all vanilla options, that is without scatter gather mode that does not allow unaligned writes\n<ul>\n<li>If you follow the S_AXIS_S2MM and the M_AXIS_MM2S ports you will see that they are both connected to the same AXI4-Stream Data FIFO (2.0).\u00a0 This too is also configured to be 32-bits wide, see the TDATA width value which is set to 4 bytes.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">2 &#8211; Synthesize, implement and generate the bitstream<\/h3>\n\n\n\n<p>In the bottom left of the Vivado window click on the &#8220;Generate Bitstream&#8221; and wait for it to complete.\u00a0 You can always check the TCL Console to see it progress through its various stages.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"313\" height=\"345\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-3.png\" alt=\"\" class=\"wp-image-20002\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-3.png 313w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-3-272x300.png 272w\" sizes=\"auto, (max-width: 313px) 100vw, 313px\" \/><\/figure>\n\n\n\n<p>When the bitstream has been generated you will see the following window, just click cancel.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"384\" height=\"335\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-5.png\" alt=\"\" class=\"wp-image-20004\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-5.png 384w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-5-300x262.png 300w\" sizes=\"auto, (max-width: 384px) 100vw, 384px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">3 &#8211; Export the XSA file<\/h3>\n\n\n\n<p>Now export the bitstream:<\/p>\n<ul>\n<li>Clicking &#8220;File-&gt;Export-&gt;Export Hardware&#8221;.<\/li>\n<li>Select &#8220;Include bitstream&#8221;<\/li>\n<li>Update the file name to <strong>arty_hw<\/strong>, and the directory to be the parent directory <strong>~\/work\/arty_z7\/arty_hw\/vivado<\/strong> (see screenshot below)\n<ul>\n<li>This will allow the Makefile to be able to find the xsa file in case you want to run the apps via the Makefile in the future.<\/li>\n<\/ul>\n<\/li>\n<li>vivado\/arty_hw.xsa<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"454\" height=\"499\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-6.png\" alt=\"\" class=\"wp-image-20006\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-6.png 454w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-6-273x300.png 273w\" sizes=\"auto, (max-width: 454px) 100vw, 454px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"811\" height=\"333\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-8.png\" alt=\"\" class=\"wp-image-20008\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-8.png 811w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-8-300x123.png 300w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-8-768x315.png 768w\" sizes=\"auto, (max-width: 811px) 100vw, 811px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"820\" height=\"335\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-9.png\" alt=\"\" class=\"wp-image-20009\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-9.png 820w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-9-300x123.png 300w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-9-768x314.png 768w\" sizes=\"auto, (max-width: 820px) 100vw, 820px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">4 &#8211; Start Vitis<\/h3>\n\n\n\n<p>You can exit from Vivado if you wish. Regardless, you will have to source the Vitis tools and then start Vitis in classic mode from inside the apps \/vitis directory.&nbsp; You will have to create the vitis directory and set that directory to be your workspace path.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Source the Vitis Tools\n. \/tools\/Xilinx\/Vitis\/2024.1\/settings64.sh\n\n# Create a workspace directory named vitis\ncd ~\/work\/artyz7_arty_hw\/apps\nmkdir vitis\n\n# Start Vitis 2024.1 in Classic Mode\nvitis --classic &amp;<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"893\" height=\"528\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-10.png\" alt=\"\" class=\"wp-image-20012\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-10.png 893w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-10-300x177.png 300w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-10-768x454.png 768w\" sizes=\"auto, (max-width: 893px) 100vw, 893px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">5 &#8211; Create Platform Project<\/h3>\n\n\n\n<ul>\n<li>Click &#8220;File-&gt;New-&gt;Platform Project&#8221;<\/li>\n<li>Name the project plat_bm<\/li>\n<li>Browse to and select the XSA file from the previous step<\/li>\n<li>No need to change anything else, click Finish<\/li>\n<li>Right click on the project and select Build<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"686\" height=\"610\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-11.png\" alt=\"\" class=\"wp-image-20015\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-11.png 686w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-11-300x267.png 300w\" sizes=\"auto, (max-width: 686px) 100vw, 686px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">6 &#8211; Create C Application with Board Support Project<\/h3>\n\n\n\n<p>Create a C Application:<\/p>\n<ul>\n<li>Click <strong>File-&gt;New-&gt;New Application<\/strong><\/li>\n<li>Make sure <strong>plat_bm<\/strong> is selected as the Platform<\/li>\n<li>Name the project <strong>c_hw<\/strong><\/li>\n<li>The defaults should be fine until you reach the Templates window\n<ul>\n<li>Select <strong>&#8220;Empty C Application&#8221;<\/strong>&nbsp;<\/li>\n<\/ul>\n<\/li>\n<li>Click Finish<\/li>\n<\/ul>\n<p>Now import the sources:<\/p>\n<ul>\n<li>Right click on src and select &#8220;Import Sources&#8221;<\/li>\n<li><span style=\"font-size: inherit;\">Browse to the ~\/work\/artyz7\/arty_hw\/app\/arty_hw_bm directory and select <\/span><strong style=\"font-size: inherit;\">Open<\/strong><\/li>\n<li>Check the following files:\n<ul>\n<li>main.c<\/li>\n<li>mmio.c<\/li>\n<li>mmio.h<\/li>\n<\/ul>\n<\/li>\n<li>Right click on the c_hw application and select Build<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"515\" height=\"587\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-12.png\" alt=\"\" class=\"wp-image-20017\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-12.png 515w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-12-263x300.png 263w\" sizes=\"auto, (max-width: 515px) 100vw, 515px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">7 &#8211; Run Bare-Metal Application in Debug Mode<\/h3>\n\n\n\n<p>Right click on the project &#8220;c_hw&#8221; and select &#8220;Debug As-&gt; Debug Configurations&#8230;&#8221;<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"653\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-20-1024x653.png\" alt=\"\" class=\"wp-image-20025\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-20-1024x653.png 1024w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-20-300x191.png 300w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-20-768x490.png 768w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-20.png 1178w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Click on the left most icon to add a new configuration under &#8220;Single Application Debug&#8221;<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"917\" height=\"479\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-21.png\" alt=\"\" class=\"wp-image-20026\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-21.png 917w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-21-300x157.png 300w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-21-768x401.png 768w\" sizes=\"auto, (max-width: 917px) 100vw, 917px\" \/><\/figure>\n\n\n\n<p>This should not be an issue for most users, but it is in my case since I have multiple FPGA boards plugged in.&nbsp; Go to &#8220;Target Setup&#8221; And make sure that the PL Device and PS Device options are both pointing to the Digilent Arty Z7.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"531\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-22-1024x531.png\" alt=\"\" class=\"wp-image-20027\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-22-1024x531.png 1024w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-22-300x156.png 300w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-22-768x398.png 768w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-22.png 1161w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"589\" height=\"378\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-13.png\" alt=\"\" class=\"wp-image-20018\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-13.png 589w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-13-300x193.png 300w\" sizes=\"auto, (max-width: 589px) 100vw, 589px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"592\" height=\"712\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-24.png\" alt=\"\" class=\"wp-image-20029\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-24.png 592w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-24-249x300.png 249w\" sizes=\"auto, (max-width: 592px) 100vw, 592px\" \/><\/figure>\n\n\n\n<p>Hit Debug and monitor the console<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"532\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-25-1024x532.png\" alt=\"\" class=\"wp-image-20030\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-25-1024x532.png 1024w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-25-300x156.png 300w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-25-768x399.png 768w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-25.png 1413w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Then connect the Vitis Serial Terminal to the appropriate port and view the output:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"558\" height=\"412\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-26.png\" alt=\"\" class=\"wp-image-20032\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-26.png 558w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-26-300x222.png 300w\" sizes=\"auto, (max-width: 558px) 100vw, 558px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"537\" height=\"252\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-27.png\" alt=\"\" class=\"wp-image-20033\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-27.png 537w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-27-300x141.png 300w\" sizes=\"auto, (max-width: 537px) 100vw, 537px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">8 &#8211; Create FreeRTOS App<\/h3>\n\n\n\n<p>Now you are going to have to create another Application Project with a new Domain that supports FreeRTOS.<\/p>\n\n\n\n<p>Click &#8220;File-&gt;New-&gt;Application Project&#8221;<\/p>\n<p>Select your existing Platform project (plat_bm)<\/p>\n<p>Name the project c_hw_rtos<\/p>\n<p>Create a new domain and set the Operating System to &#8220;freertos10_xilinx&#8221;<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"967\" height=\"803\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-29.png\" alt=\"\" class=\"wp-image-20036\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-29.png 967w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-29-300x249.png 300w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-29-768x638.png 768w\" sizes=\"auto, (max-width: 967px) 100vw, 967px\" \/><\/figure>\n\n\n\n<p>Select FreeRTOS Hello World<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"974\" height=\"804\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-30.png\" alt=\"\" class=\"wp-image-20037\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-30.png 974w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-30-300x248.png 300w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-30-768x634.png 768w\" sizes=\"auto, (max-width: 974px) 100vw, 974px\" \/><\/figure>\n\n\n\n<p>Import the same 3 files as before:<\/p>\n<ul>\n<li>main.c<\/li>\n<li>mmio.c<\/li>\n<li>mmio.h<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">9 &#8211; Run FreeRTOS App<\/h3>\n\n\n\n<p>Create a Debug Configuration like before and run the application<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"664\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-31-1024x664.png\" alt=\"\" class=\"wp-image-20038\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-31-1024x664.png 1024w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-31-300x194.png 300w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-31-768x498.png 768w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-31.png 1480w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>The output should be different, notice the &#8220;xTaskCreate&#8221; and &#8220;vTaskStartScheduler&#8221; function calls:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"865\" height=\"595\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-32.png\" alt=\"\" class=\"wp-image-20040\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-32.png 865w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-32-300x206.png 300w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-32-768x528.png 768w\" sizes=\"auto, (max-width: 865px) 100vw, 865px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"852\" height=\"470\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-33.png\" alt=\"\" class=\"wp-image-20041\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-33.png 852w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-33-300x165.png 300w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-33-768x424.png 768w\" sizes=\"auto, (max-width: 852px) 100vw, 852px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Automated &#8211; Linux Only<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1 &#8211; Build the Bitstream and XSA<\/h3>\n\n\n\n<p>Now for the fun part.&nbsp; With the help of Claude I wrote a bunch of Makefile rules\/recipes that will automate everything done in the Manual mode.&nbsp; Simple, just run make and check the help menu.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>john@asus:~\/work\/artyz7\/arty_hw$ make\narty_hw \u2014 Arty Z7-20 hardware test suite\n\nVivado:\n  make xsa               Build Vivado project and export XSA (25-35 min)\n  make xsa-clean         Remove Vivado project and build artifacts\n\nBare-metal (JTAG):\n  make bare-metal-build  Build standalone ELF (ps7_cortexa9_0, via xsct)\n  make bare-metal-run    Program PL + run ELF via JTAG, capture UART\n  make bare-metal-clean  Remove bare-metal Vitis workspace\n\nFreeRTOS (JTAG):\n  make rtos-build        Build FreeRTOS ELF (ps7_cortexa9_0, via xsct)\n  make rtos-run          Program PL + run ELF via JTAG, capture UART\n  make rtos-clean        Remove FreeRTOS Vitis workspace\n\nLinux (PetaLinux board via SSH):\n  make deploy            Cross-compile and scp test app to board\n  make deploy-run        Deploy + run test app on board via SSH\n\nSetup:\n  make fetch-board-parts Fetch Digilent board files into Vivado 2024.1 xhub\n\nUtilities:\n  make tty               Open Arty Z7 PS-UART in screen (115200 8N1)\n  make tty-list          List screen sessions and processes holding any \/dev\/ttyUSB*\n  make tty-kill          Kill any screen\/process holding the Arty Z7 PS-UART\n  make board-reset       System-reset the Arty Z7 PS+PL via JTAG (xsct rst -system)\n  make help              Show this help\n\nVariables:\n  ARTY_HOST=arty          Board hostname\/IP for SSH deploy\n  ARTY_USER=petalinux      Board username\n  ARTY_UART=\/dev\/ttyUSB4  PS-UART device (auto-detected)<\/code><\/pre>\n\n\n\n<p>You can tinker and see what boards are connected to your system. In my case I have the <strong>Arty Z7-20<\/strong> and the <strong>Kria KR260<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>john@asus:~\/work\/artyz7\/arty_hw$ make list-all\n==&gt; USB serial ports:\n  \/dev\/ttyUSB1   usb=3-2        if=01  Xilinx KR Carrier Card  serial=XFL1GRCZBY0R\n  \/dev\/ttyUSB2   usb=3-2        if=02  Xilinx KR Carrier Card  serial=XFL1GRCZBY0R\n  \/dev\/ttyUSB3   usb=3-2        if=03  Xilinx KR Carrier Card  serial=XFL1GRCZBY0R\n  \/dev\/ttyUSB4   usb=3-3        if=01  Digilent Digilent Adept USB Device  serial=003017B7EAFD\n==&gt; JTAG scan chains (xsct):\n  cable: Digilent Arty Z7 003017B7EAFDA\n    device: arm_dap\n    device: xc7z020\n  cable: Xilinx SCK-KR XFL1GRCZBY0RA\n    device: xck26\n    device: arm_dap<\/code><\/pre>\n\n\n\n<p>And you can see which one is for your board. In this case we know it it \/dev\/ttyUSB4, but we can be more explicit by calling &#8220;make tty-list&#8221;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>john@asus:~\/work\/artyz7\/arty_hw$ make tty-list\n==&gt; screen sessions:\n  (none)\n==&gt; \/dev\/ttyUSB* holders:\n  (none)\n==&gt; Arty Z7 PS-UART (auto-detected): \/dev\/ttyUSB4<\/code><\/pre>\n\n\n\n<h3>2 &#8211; Prerequisite &#8211; Build the XSA<\/h3>\n\n\n\n<p>Just run make xsa. It took 13 minutes on my ASUS ExpertCenter PN65<\/p>\n<ul>\n<li><a href=\"https:\/\/www.asus.com\/us\/displays-desktops\/mini-pcs\/pn-series\/asus-expertcenter-pn65\/\" target=\"_blank\" rel=\"noopener\">https:\/\/www.asus.com\/us\/displays-desktops\/mini-pcs\/pn-series\/asus-expertcenter-pn65\/<\/a><\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>john@asus:~\/work\/artyz7\/arty_hw$ time make xsa\nmake -C vivado xsa\n. \/tools\/Xilinx\/Vivado\/2024.1\/settings64.sh &amp;&amp; JOBS=1 vivado -mode batch -nojournal -log build.log -source build.tcl\n\n****** Vivado v2024.1 (64-bit)\n  **** SW Build 5076996 on Wed May 22 18:36:09 MDT 2024\n  **** IP Build 5075265 on Wed May 22 21:45:21 MDT 2024\n  **** SharedData Build 5076995 on Wed May 22 18:29:18 MDT 2024\n  **** Start of session at: Thu Jun  4 14:44:27 2026\n    ** Copyright 1986-2022 Xilinx, Inc. All Rights Reserved.\n    ** Copyright 2022-2024 Advanced Micro Devices, Inc. All Rights Reserved.\n...\n----\n# puts \"Wrote XSA: &#91;file normalize arty_hw.xsa]\"\nWrote XSA: \/home\/john\/work\/artyz7\/arty_hw\/vivado\/arty_hw.xsa\nINFO: &#91;Common 17-206] Exiting Vivado at Thu Jun  4 14:59:46 2026...\n\nreal    13m11.710s\nuser    9m9.382s\nsys     0m26.627s<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">3 &#8211; Build and Run the Bare-Metal Application<\/h3>\n\n\n\n<p>Now run &#8220;make bare-metal-build&#8221; and then &#8220;make bare-metal-run&#8221;, all output (for 10 seconds) will be captured and printed to the console<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>john@asus:~\/work\/artyz7\/arty_hw$ make bare-metal-run\nmake -C apps\/arty_hw_bm run\n==&gt; Configuring \/dev\/ttyUSB4 (115200 8N1)\n==&gt; Programming PL + downloading ELF via xsct load.tcl\nattempting to launch hw_server\n\n****** Xilinx hw_server v2024.1\n  **** Build date : May 16 2024 at 12:16:21\n    ** Copyright 1986-2022 Xilinx, Inc. All Rights Reserved.\n    ** Copyright 2022-2024 Advanced Micro Devices, Inc. All Rights Reserved.\n\nINFO: hw_server application started\nINFO: Use Ctrl-C to exit hw_server application\n\nINFO: To connect to this hw_server instance use url: TCP:127.0.0.1:3121\n\nload.tcl: ELF running. UART output on ttyUSB at 115200 8N1.\n==&gt; ELF running -- capturing UART for 10s\n\n==&gt; Captured output (saved to bm.log):\n------------------------------------------------\n...\n----- &#91;mmio] AXI DMA echo (mem-&gt;MM2S-&gt;S2MM-&gt;mem) -----\n  tx PA=0x00112880  rx PA=0x00113880  size=4096 B\n  after reset:  MM2S SR=0x00000001  S2MM SR=0x00000001\n  MM2S done after 37 polls, SR=0x00001002\n  S2MM done after 0 polls, SR=0x00001002\n  tx&#91;0,1]=0xA0000000,0xA0000001  tx&#91;1022,1023]=0xA00003FE,0xA00003FF\n  rx&#91;0,1]=0xA0000000,0xA0000001  rx&#91;1022,1023]=0xA00003FE,0xA00003FF\n  DMA echo: PASS (4096 bytes round-tripped)\n\n=========================================\nRESULT: ALL PASS -- 0 failures\n=========================================\n------------------------------------------------<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">4 &#8211; Build and Run the FreeRTOS Application<\/h3>\n\n\n\n<p>There are similar commands for the rtos version.&nbsp; Run &#8220;make rtos-build&#8221; and &#8220;make rtos-run&#8221;:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>john@asus:~\/work\/artyz7\/arty_hw$ make rtos-run\nmake -C apps\/arty_hw_rtos run\n==&gt; Configuring \/dev\/ttyUSB4 (115200 8N1)\n==&gt; Programming PL + downloading ELF via xsct load.tcl\nattempting to launch hw_server\n\n****** Xilinx hw_server v2024.1\n  **** Build date : May 16 2024 at 12:16:21\n    ** Copyright 1986-2022 Xilinx, Inc. All Rights Reserved.\n    ** Copyright 2022-2024 Advanced Micro Devices, Inc. All Rights Reserved.\n\nINFO: hw_server application started\nINFO: Use Ctrl-C to exit hw_server application\n\nINFO: To connect to this hw_server instance use url: TCP:127.0.0.1:3121\n...\n----- &#91;mmio] AXI Stream FIFO loopback (PG080) -----\n  post-reset: TX vacancy=508 words\n  writing 4 words to TX FIFO...\n    tx&#91;0] = 0xDEADBEEF\n    tx&#91;1] = 0xCAFEBABE\n    tx&#91;2] = 0x12345678\n    tx&#91;3] = 0xAABBCCDD\n  RX occupancy=4 words, RLR=16 bytes (4 words)\n  received 4 words:\n    rx&#91;0] = 0xDEADBEEF OK\n    rx&#91;1] = 0xCAFEBABE OK\n    rx&#91;2] = 0x12345678 OK\n    rx&#91;3] = 0xAABBCCDD OK\n  FIFO echo: PASS\n\n----- &#91;mmio] AXI DMA echo (mem-&gt;MM2S-&gt;S2MM-&gt;mem) -----\n  tx PA=0x0011E880  rx PA=0x0011F880  size=4096 B\n  MM2S done after 37 polls, SR=0x00001002\n  S2MM done after 0 polls, SR=0x00001002\n  tx&#91;0,1]=0xA0000000,0xA0000001  tx&#91;1022,1023]=0xA00003FE,0xA00003FF\n  rx&#91;0,1]=0xA0000000,0xA0000001  rx&#91;1022,1023]=0xA00003FE,0xA00003FF\n  DMA echo: PASS (4096 bytes round-tripped)\n\n=========================================\nRESULT: ALL PASS -- 0 failures\n=========================================\n------------------------------------------------<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Miscellaneous<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Enumerate all connected boards<\/h3>\n\n\n\n<p>I added a utility recipe \/ rule to list all connected FPGA boards. For this portion of this article, I connected 3 total boards:<\/p>\n<ul>\n<li>Kria KR260<\/li>\n<li>ArtyZ7-20<\/li>\n<li>Arty A7-100T<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>john@asus:~\/work\/artyz7\/arty_hw$ make list-all\n==&gt; USB serial ports:\n  \/dev\/ttyUSB0   usb=3-4        if=00  Digilent Digilent USB Device  serial=210319AFEEC7\n  \/dev\/ttyUSB1   usb=3-2        if=01  Xilinx KR Carrier Card  serial=XFL1GRCZBY0R\n  \/dev\/ttyUSB2   usb=3-2        if=02  Xilinx KR Carrier Card  serial=XFL1GRCZBY0R\n  \/dev\/ttyUSB3   usb=3-2        if=03  Xilinx KR Carrier Card  serial=XFL1GRCZBY0R\n  \/dev\/ttyUSB4   usb=3-3        if=01  Digilent Digilent Adept USB Device  serial=003017B7EAFD\n  \/dev\/ttyUSB5   usb=3-4        if=01  Digilent Digilent USB Device  serial=210319AFEEC7\n==&gt; JTAG scan chains (xsct):\n  cable: Digilent Arty A7-100T 210319AFEEC7A\n    device: xc7a100t\n  cable: Digilent Arty Z7 003017B7EAFDA\n    device: arm_dap\n    device: xc7z020\n  cable: Xilinx SCK-KR XFL1GRCZBY0RA\n    device: xck26\n    device: arm_dap<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Reboot the Board<\/h3>\n\n\n\n<p>When playing around with Linux (Ubuntu) or PetaLinux, I sometimes want to reboot the boad without having to unplug it and plug it back in (or by pressing the reset button).<\/p>\n<p>What I do is (using tmux) I run &#8220;make tty&#8221; to listen to the serial port interface from one window, and then from another I run &#8220;make board-reset&#8221; and I can watch the tty window reset.&nbsp; In my case I switched by Dip switch back to SD card and can watch it boot up to Ubuntu:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"644\" src=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-34-1024x644.png\" alt=\"\" class=\"wp-image-20048\" srcset=\"https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-34-1024x644.png 1024w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-34-300x189.png 300w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-34-768x483.png 768w, https:\/\/fpganow.com\/wp-content\/uploads\/2026\/06\/image-34.png 1123w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I wanted to create a project suitable for beginners that does more than your average hello world sample out there on the internet. The project I created that will be described on this page and will show you how to run an augmented hello world that includes: Additionally, this example can be run in multiple &#8230; <a title=\"Building a Project That Exercises the GPIOs, FIFOs, and DMA, on the Arty Z7-20\" class=\"read-more\" href=\"https:\/\/fpganow.com\/index.php\/2026\/06\/18\/building-a-project-that-exercises-the-gpios-fifos-and-dma-on-the-arty-z7-20\/\" aria-label=\"Read more about Building a Project That Exercises the GPIOs, FIFOs, and DMA, on the Arty Z7-20\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","footnotes":""},"categories":[1],"tags":[],"class_list":["post-19976","post","type-post","status-publish","format-standard","hentry","category-uncategorized","masonry-post","generate-columns","tablet-grid-50","mobile-grid-100","grid-parent","grid-50"],"_links":{"self":[{"href":"https:\/\/fpganow.com\/index.php\/wp-json\/wp\/v2\/posts\/19976","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fpganow.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fpganow.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fpganow.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fpganow.com\/index.php\/wp-json\/wp\/v2\/comments?post=19976"}],"version-history":[{"count":41,"href":"https:\/\/fpganow.com\/index.php\/wp-json\/wp\/v2\/posts\/19976\/revisions"}],"predecessor-version":[{"id":20057,"href":"https:\/\/fpganow.com\/index.php\/wp-json\/wp\/v2\/posts\/19976\/revisions\/20057"}],"wp:attachment":[{"href":"https:\/\/fpganow.com\/index.php\/wp-json\/wp\/v2\/media?parent=19976"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fpganow.com\/index.php\/wp-json\/wp\/v2\/categories?post=19976"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fpganow.com\/index.php\/wp-json\/wp\/v2\/tags?post=19976"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}