{"id":489265,"date":"2016-11-21T23:12:00","date_gmt":"2016-11-21T22:12:00","guid":{"rendered":"http:\/\/antonpotocnik.com\/?p=489265"},"modified":"2017-12-14T03:39:47","modified_gmt":"2017-12-14T02:39:47","slug":"redpitaya-fpga-project-3-timing-knight-rider","status":"publish","type":"post","link":"https:\/\/antonpotocnik.com\/?p=489265","title":{"rendered":"Red Pitaya FPGA Project 3 &#8211; Stopwatch"},"content":{"rendered":"<p style=\"text-align: justify;\">In this Red Pitaya FPGA project we will learn about communication between the Linux processing system and the programmable logic. We will demonstrate the basic functionality with a simple FPGA project &#8211; Stopwatch.<\/p>\n<p style=\"text-align: justify;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-509211\" src=\"https:\/\/antonpotocnik.com\/wp-content\/uploads\/2016\/10\/stopwatch-300x200.jpg\" alt=\"stopwatch\" width=\"300\" height=\"200\" srcset=\"https:\/\/antonpotocnik.com\/wp-content\/uploads\/2016\/10\/stopwatch-300x200.jpg 300w, https:\/\/antonpotocnik.com\/wp-content\/uploads\/2016\/10\/stopwatch-768x511.jpg 768w, https:\/\/antonpotocnik.com\/wp-content\/uploads\/2016\/10\/stopwatch.jpg 900w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p style=\"text-align: justify;\">The FPGA algorithm will be based on a 32-bit binary counter with Clock Enable (CE) and Synchronous Clear (SCLR) inputs which we will control from the Linux side. The counter&#8217;s output value we will be read with a Linux program and partially displayed with the on-board LEDs. In order to do this we will use standard <a href=\"http:\/\/\" target=\"_blank\">AXI communication protocol<\/a> that connects different parts on the Zynq device such as processing system, programmable logic, DDR memory, external peripherals and more.<\/p>\n<p style=\"text-align: justify;\">To build Stopwatch project in Vivado you can either download the project&#8217;s tcl script from the <a href=\"https:\/\/github.com\/apotocnik\/redpitaya_guide.git\" target=\"_blank\">github<\/a> as described in <a href=\"https:\/\/antonpotocnik.com\/?p=487360\" target=\"_blank\">the first post<\/a> or simply go through the following steps. This guide assumes that you are familiar with the concepts introduced in the previous two posts.<\/p>\n<p style=\"text-align: justify;\">Open one of the previous Vivado projects to get a basic block diagram. Next, insert the binary counter, if it is not already present, and add CE and SCLR ports. This can be done by double-clicking on the binary counter IP core in our block design and select CE and SCLR under the Control tab. Then add <em>xlslice<\/em> IP block with <em>Din Width<\/em>: 32, <em>Din From<\/em>: 31, <em>Din Down To<\/em>: 24. Connect CLK pin of the binary counter to PS&#8217;s <em>FCLK_CLK0<\/em>, output of the binary counter to the input of the <em>xlslice<\/em> and output of the <em>xlslice<\/em> to <em>led_o<\/em> external port. This last part will display 8 MSBs of the 32-bit counter on Red Pitaya&#8217;s LED bar. If you started from Project 1 change the LEFT property of <em>led_o<\/em> port from 0 to 7.<\/p>\n<p style=\"text-align: justify;\">We are ready to insert AXI General Purpose IO IP core (<em>AXI GPIO<\/em>) to our block design. When the core is added, double-click on the block, check <em>Enable Dual Channel<\/em> and set <em>All Inputs<\/em> for the GPIO 2. To connect the AXI GPIO to the processing system click on <em>Run Connection Automation<\/em> on top of the block design. Select <em>S_AXI<\/em> and click OK. This will automatically create <em>AXI Interconnect<\/em> and <em>Processor System Reset<\/em> blocks. Next, add two xlslice IP cores with 32-bit Din. <em>xls_CE<\/em> should have <em>Din From<\/em> and <em>Din Down To<\/em> both set to 0 and <em>xls_SCLR<\/em> should have them both set to 1. Connect all the blocks as shown in the figure below.<\/p>\n<p style=\"text-align: justify;\"><a href=\"https:\/\/antonpotocnik.com\/wp-content\/uploads\/2016\/11\/stopwatch_diagram.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/antonpotocnik.com\/wp-content\/uploads\/2016\/11\/stopwatch_diagram.png\" alt=\"stopwatch_diagram\" width=\"1743\" height=\"585\" class=\"alignleft size-full wp-image-510820\" srcset=\"https:\/\/antonpotocnik.com\/wp-content\/uploads\/2016\/11\/stopwatch_diagram.png 1743w, https:\/\/antonpotocnik.com\/wp-content\/uploads\/2016\/11\/stopwatch_diagram-300x101.png 300w, https:\/\/antonpotocnik.com\/wp-content\/uploads\/2016\/11\/stopwatch_diagram-768x258.png 768w, https:\/\/antonpotocnik.com\/wp-content\/uploads\/2016\/11\/stopwatch_diagram-1024x344.png 1024w\" sizes=\"auto, (max-width: 1743px) 100vw, 1743px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Next, we need to set the AXI GPIO core&#8217;s memory address and range. We will use this address later to access the IP core from the Linux side. On top of the window choose Address Editor tab and set all the values as shown below. Remember the address of our GPIO block is 0x4200_0000.<\/p>\n<p style=\"text-align: justify;\"><a href=\"https:\/\/antonpotocnik.com\/wp-content\/uploads\/2016\/10\/3_stopwatch_Addresses.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-509210\" src=\"https:\/\/antonpotocnik.com\/wp-content\/uploads\/2016\/10\/3_stopwatch_Addresses.png\" alt=\"3_stopwatch_addresses\" width=\"1196\" height=\"201\" srcset=\"https:\/\/antonpotocnik.com\/wp-content\/uploads\/2016\/10\/3_stopwatch_Addresses.png 1196w, https:\/\/antonpotocnik.com\/wp-content\/uploads\/2016\/10\/3_stopwatch_Addresses-300x50.png 300w, https:\/\/antonpotocnik.com\/wp-content\/uploads\/2016\/10\/3_stopwatch_Addresses-768x129.png 768w, https:\/\/antonpotocnik.com\/wp-content\/uploads\/2016\/10\/3_stopwatch_Addresses-1024x172.png 1024w\" sizes=\"auto, (max-width: 1196px) 100vw, 1196px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">The FPGA program is ready. Proceed with synthesis, implementation and generate the bitstream file. When the file is generated and copied to a folder on Red Pitaya&#8217;s Linux write the bitstream file to programmable logic with the following command<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\ncat system_wrapper.bit &gt; \/dev\/xdevcfg\r\n<\/pre>\n<p style=\"text-align: justify;\">To write or read from our FPGA program we will use Red Pitaya&#8217;s <a href=\"http:\/\/redpitaya.readthedocs.io\/en\/latest\/doc\/developerGuide\/software\/clt.html\" target=\"_blank\">monitor<\/a> tool available in the Red Pitaya&#8217;s Linux. Try the following commands.<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nmonitor 0x42000000 1  # write: start, SCLR = 0, CE = 1\r\nmonitor 0x42000000 0  # write: stop,  SCLR = 0, CE = 0\r\nmonitor 0x42000000 2  # write: clear, SCLR = 1, CE = 0\r\n\r\nmonitor 0x42000000    # read: cfg  on GPIO1\r\nmonitor 0x42000008    # read: data on GPIO2\r\n<\/pre>\n<p style=\"text-align: justify;\">Great, we have created a stopwatch with a resolution of 8 ns! Using AXI communication protocol we can easily access our GPIO IP core. More details about the GPIO core can be found in the references part of this post.<\/p>\n<p style=\"text-align: justify;\">If you would like to know how much time has passed between start and stop in seconds and not in the number of clock cycles, you can use the following program on Linux to write, read and convert data. This program, based on <a href=\"http:\/\/pavel-demin.github.io\/red-pitaya-notes\/\" target=\"_blank\">Pavel Demin&#8217;s code<\/a>, can also be a useful template for more advanced applications where you need to set several parameters and read large amount of data generated on FPGA.<\/p>\n<p style=\"text-align: justify;\">stopwatch.c:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdint.h&gt;\r\n#include &lt;unistd.h&gt;\r\n#include &lt;sys\/mman.h&gt;\r\n#include &lt;fcntl.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n\r\nint main(int argc, char **argv)\r\n{\r\n  int fd;\r\n  float wait_time;\r\n  uint32_t count;\r\n  void *cfg;\r\n  char *name = &quot;\/dev\/mem&quot;;\r\n  const int freq = 124998750; \/\/ Hz\r\n\r\n  if (argc == 2) wait_time = atof(argv&#x5B;1]);\r\n  else wait_time = 1.0;\r\n\r\n  if((fd = open(name, O_RDWR)) &lt; 0) {\r\n    perror(&quot;open&quot;);\r\n    return 1;\r\n  }\r\n  cfg = mmap(NULL, sysconf(_SC_PAGESIZE), \/* map the memory *\/\r\n             PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x42000000);\r\n\r\n  *((uint32_t *)(cfg + 0)) = 2;   \/\/ clear timer\r\n  *((uint32_t *)(cfg + 0)) = 1;   \/\/ start timer\r\n\r\n  sleep(wait_time);   \/\/ wait for &#x5B;wait_time] seconds\r\n\r\n  *((uint32_t *)(cfg + 0)) = 0;   \/\/ stop timer\r\n\r\n  count = *((uint32_t *)(cfg + 8)); \/\/ get binary counter output\r\n\r\n  printf(&quot;Clock count: %5d, calculated time: %5f s\\n&quot;, \r\n         count, (double)count\/freq);\r\n\r\n  munmap(cfg, sysconf(_SC_PAGESIZE));\r\n  return 0;\r\n}\r\n<\/pre>\n<p style=\"text-align: justify;\">stopwatch.c program maps the memory at a given address to <em>cfg<\/em> pointer. By writing an appropriate 32-bit value to this pointer the code first clears the counter by setting SCLR (2nd bit), then starts the count by setting CE (1st bit). After <em>wait_time<\/em> in seconds the program stops the counter by clearing the CE bit. To read counter&#8217;s output value we need to access the second port of the GPIO IP core. According to <a href=\"https:\/\/www.xilinx.com\/support\/documentation\/ip_documentation\/axi_gpio\/v2_0\/pg144-axi-gpio.pdfhttps:\/\/www.xilinx.com\/support\/documentation\/ip_documentation\/axi_gpio\/v2_0\/pg144-axi-gpio.pdf\" target=\"_blank\">GPIO documentation<\/a> the address of the second port is shifted by 8 (0x4200_0008). At the end the counter output value is scaled by the FCLK_CLK0 frequency and printed on the screen.<\/p>\n<p style=\"text-align: justify;\">Compile and execute the program as shown here.<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\ngcc -o stopwatch stopwatch.c\r\n.\/stopwatch 5   # wait for 5 s\r\n<\/pre>\n<p style=\"text-align: justify;\">Interestingly, <em>FCLK_CLK0<\/em> has a frequency of 124.99875 MHz (= 3.75*33.333 MHz). This is a default Red Pitaya frequency generated by IO <a href=\"https:\/\/www.altera.com\/support\/support-resources\/operation-and-testing\/pll-and-clock-management\/pll-basics.html\" target=\"_blank\">PLL<\/a> using 33.333 MHz external clock (<a href=\"https:\/\/dl.dropboxusercontent.com\/s\/jkdy0p05a2vfcba\/Red_Pitaya_Schematics_v1.0.1.pdf\" target=\"_blank\">PS_CLK<\/a>). To increase the frequency to, for example, 143 MHz use the bash script mentioned by Jean in the comments.<\/p>\n<p style=\"text-align: justify;\">In conclusion, we have created another simple project where we learned how to communicate between our FPGA program and Linux running on Red Pitaya&#8217;s Zynq7 ARM processor. Armed with this knowledge we can now move to more serious projects such as high-speed ADC averager for heterodyne detection or lock-in amplification. Coming soon.<\/p>\n<table width=\"100%\">\n<tbody>\n<tr>\n<td><a href=\"https:\/\/antonpotocnik.com\/?p=488784\">&lt;&lt; Red Pitaya Project 2 &#8211; Knight Rider<\/a><\/td>\n<td align=\"right\"><a href=\"https:\/\/antonpotocnik.com\/?p=519284\">Red Pitaya Project 4 &#8211; Frequency Counter &gt;&gt;<\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h1 style=\"text-align: justify;\">References<\/h1>\n<ul>\n<li style=\"text-align: justify;\"><a href=\"https:\/\/www.xilinx.com\/support\/documentation\/ip_documentation\/axi_ref_guide\/latest\/ug1037-vivado-axi-reference-guide.pdf\" target=\"_blank\">Vivado&#8217;s AXI Reference Guide<\/a><\/li>\n<li style=\"text-align: justify;\"><a href=\"https:\/\/www.xilinx.com\/support\/documentation\/ip_documentation\/axi_gpio\/v2_0\/pg144-axi-gpio.pdf\" target=\"_blank\">Vivado AXI GPIO LogiCORE IP Product Guide<\/a><\/li>\n<li style=\"text-align: justify;\"><a href=\"https:\/\/www.youtube.com\/watch?v=8i8GLF-Md3U\" target=\"_blank\">Xilinx Vivado Gpio LED Hello World Example (Youtube)<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>In this Red Pitaya FPGA project we will learn about communication between the Linux processing system and the programmable logic. We will demonstrate the basic functionality with a simple FPGA project &#8211; Stopwatch. The FPGA algorithm will be based on a 32-bit binary counter with Clock Enable (CE) and Synchronous Clear (SCLR) inputs which we&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":true,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[29],"tags":[],"class_list":["post-489265","post","type-post","status-publish","format-standard","hentry","category-fpga"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p3Hjcy-23hn","_links":{"self":[{"href":"https:\/\/antonpotocnik.com\/index.php?rest_route=\/wp\/v2\/posts\/489265","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/antonpotocnik.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/antonpotocnik.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/antonpotocnik.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/antonpotocnik.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=489265"}],"version-history":[{"count":26,"href":"https:\/\/antonpotocnik.com\/index.php?rest_route=\/wp\/v2\/posts\/489265\/revisions"}],"predecessor-version":[{"id":566550,"href":"https:\/\/antonpotocnik.com\/index.php?rest_route=\/wp\/v2\/posts\/489265\/revisions\/566550"}],"wp:attachment":[{"href":"https:\/\/antonpotocnik.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=489265"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/antonpotocnik.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=489265"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/antonpotocnik.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=489265"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}