{"id":3862,"date":"2012-10-25T03:23:50","date_gmt":"2012-10-25T03:23:50","guid":{"rendered":"https:\/\/www.techdesignforums.com\/eda\/?p=3862"},"modified":"2014-06-27T17:24:48","modified_gmt":"2014-06-27T17:24:48","slug":"vivado-hls-agilent","status":"publish","type":"post","link":"https:\/\/www.techdesignforums.com\/practice\/technique\/vivado-hls-agilent\/","title":{"rendered":"Vivado HLS\/AutoESL: Agilent packet engine case study"},"content":{"rendered":"<p>Gigabit Ethernet is one of the most common interconnect options available to link a workstation or laptop to an FPGA-based embedded platform. This is because of the availability of the hardened tri-Ethernet MAC (TEMAC) primitive. The main obstacle to developing Ethernet-based FPGA designs is the processor requirement thought necessary to handle the Internet Protocol (IP) stack. Agilent Technologies approached the problem by using the Vivado HLS\/AutoESL high-level synthesis tool to develop a high-performance IPv4 User-Datagram Protocol (UDP) packet transfer engine.<\/p>\n<p>Agilent&#8217;s Measurement Research Lab wrote original C source code based on Internet Engineering Task Force requests for comments (RFCs) detailing packet exchanges among several protocols. These were specifically UDP, the Address Resolution Protocol (ARP) and the Dynamic Host Configuration Protocol (DHCP). The design implements a hardware packet-processing engine without any need for a CPU. The architecture is capable of handling traffic at line rate with minimum latency and is compact in logic-resource area. Vivado HLS\/AutoESL made it easy to modify the user interface to adapt to one or more FIFO streams or to multiple RAM interface ports. AutoESL is a new addition to the Xilinx <a title=\"Xilinx ISE Design Suite home page\" href=\"http:\/\/www.xilinx.com\/products\/design-tools\/ise-design-suite\/\" target=\"_blank\">ISE Design Suite<\/a> and is called Vivado HLS in the new <a title=\"Xilinx Vivado home page\" href=\"http:\/\/www.xilinx.com\/products\/design-tools\/vivado\/index.htm\" target=\"_blank\">Vivado Design Suite<\/a>.<\/p>\n<p><em>NB: For consistency with <a title=\"Vivado in focus at Tech Design Forum\" href=\"https:\/\/www.techdesignforums.com\/eda\/technique\/vivado-xilinx-overview\/\" target=\"_blank\">our general overview of the Vivado tool suite<\/a> this month and to avoid confusion, this article adopts the convention of referring to the software as Vivado HLS\/AutoESL. It was called AutoESL when used by Agilent. As the project described here used series-5 Xilinx FPGAs, it would still normally be undertaken using ISE and known as AutoESL. The Vivado suite, where the Vivado HLS name is now used, covers series-7 and future devices.<br \/>\n<\/em><\/p>\n<h2>IPv4 user datagram protocol<\/h2>\n<p>Internet Protocol version 4 (IPv4) dominates the Internet, with version 6 (IPv6) growing steadily in popularity. When most developers discuss IP, they commonly refer to the Transmission Control Protocol (TCP), the connection-based protocol that provides reliability and congestion management. But for many applications, increased bandwidth and minimal latency trump reliability. So, applications such as video streaming, telephony, gaming and distributed sensor networks typically use UDP instead.<\/p>\n<p>UDP is connectionless and provides no inherent reliability. If packets are lost, duplicated or sent out of order, the sender has no way of knowing and it is the responsibility of the user\u2019s application to perform packet inspection to handle these errors. UDP has therefore been nicknamed the \u2018unreliable\u2019 protocol. But in comparison to TCP, it offers higher performance. UDP support is available in nearly every major operating system. High-level software programming languages refer to network streams as \u2018sockets\u2019 and UDP as a datagram socket.<\/p>\n<h2>Sensor network architecture<\/h2>\n<p>Agilent has developed a LAN-based sensor network that interfaces an analog-to-digital converter (ADC) with a Xilinx Virtex-5 FPGA. The FPGA performs data aggregation and then streams a requested number of samples to a predetermined IP address \u2014 that is, a host PC.<\/p>\n<p>Because the block RAM of the FPGA was almost completely devoted to signal processing, there was not enough memory to contain the firmware for a soft processor. Instead, Agilent opted to implement a minimal set of networking functions to transfer sensor data via UDP back to a host. Because of the need for high bandwidth and low latency, UDP packet streaming was the preferred network mode.<\/p>\n<p>Given the time-sensitive nature of the data, a new sample set is more pertinent than any retransmission of lost samples. One of the two more challenging issues the designers faced was to avoid overloading the host device. They had to find a way of efficiently handling the large number of inbound samples. The second major challenge was quickly formatting the UDP packet, and then calculating the required IP header fields and the optional, but necessary, UDP payload checksum, before the next set of samples overflowed internal buffers.<\/p>\n<h2>Initial HDL design<\/h2>\n<p>An HDL implementation of the packet engine was straightforward given preexisting pseudocode, but not the best option for the FPGA hardware. C and pseudocode from various sources simplified verification. In addition, tools such as <a title=\"Wireshark home page\" href=\"http:\/\/www.wireshark.org\/\" target=\"_blank\">Wireshark<\/a>, the open-source packet analyzer, and high-level languages such as Java simplified the process of simulation and in-lab verification.<\/p>\n<p>Using the pseudocode, the task of developing Verilog to generate the packet headers involved coding a state machine, reading the sample FIFO and assembling the packet into a RAM-based buffer. The team broke the design into three main modules: RX Flow, TX Flow and LAN MCU (Figure 1).<\/p>\n<div class=\"article_figure\"><a class=\"figure\" title=\"Figure 1. The UDP packet engine design consisted of three main modules. (Source: Agilent\/Xilinx)\" href=\"https:\/\/www.techdesignforums.com\/practicefiles\/2012\/10\/tdf-agilviv-oct12-fig1lrg.jpg\"><img decoding=\"async\" src=\"https:\/\/www.techdesignforums.com\/practicefiles\/2012\/10\/tdf-agilviv-oct12-fig1med.jpg\" alt=\"Vivado HLS - The UDP packet engine design consisted of three main modules\" \/><\/a><\/div>\n<div class=\"article_figure\">\n<p class=\"figure_wrapper\"><span class=\"figure_title\">Figure 1<\/span><br \/>\nThe UDP packet engine design consisted of three main modules. (Source: Agilent\/Xilinx \u2013 click image to enlarge)<\/p>\n<\/div>\n<p>As packets arrive from the LAN, the RX Flow inspects them and passes them either to the instrument core or to the LAN MCU for processing, such as when handling ARP or DHCP packets.<\/p>\n<p>The TX Flow packet engine reads N ADC samples from a TX FIFO and computes a running payload checksum for calculating the UDP checksum. The TX FIFO buffers new samples as they arrive, while the LAN MCU prepares the payload of a yet-to-be-transmitted packet.<\/p>\n<p>After fetching the last requested sample, the LAN MCU computes the remaining header fields of the IP\/UDP packet. In network terminology, this procedure is a TX checksum offload.<\/p>\n<p>Once the packet fields are generated, the LAN MCU sends the packet to the TEMAC for transmission but retains it until the TEMAC acknowledges successful transmission \u2014 not reception &#8211; by the destination device. As this first packet awaits transmission by the TEMAC, new sensor samples are coming into the TX FIFO. When the first packet is finished, the packet engine releases the buffer to prepare for the next packet. The process continues in a double-buffered fashion.<\/p>\n<p>If the TEMAC signals an error and the next transmit buffer overflow is imminent, then the packet is lost to allow the next sample set to continue, and an exception is noted. Due to time-stamping of the sample set incorporated into the packet format, the host will realize a discontinuity in the set and accommodate it.<\/p>\n<p>The latency to transmit a packet is the number of cycles it takes to read in N ADC samples plus the cycles to generate the packet header fields. The fields include the IPv4 flags, source and destination address fields, UDP pseudo-header, and both the IP and UDP checksums. The checksum computations are problematic as they require reading the entire packet, yet they lie before the payload bytes.<\/p>\n<h2>Coding HDL in the dark<\/h2>\n<p>To support the high-bandwidth and low-latency requirements of the sensor network, Agilent needed an optimal hardware design to keep up with the required sample rate. The straightforward approach implemented first in Verilog failed to meet a target 125MHz clock rate without floorplanning, and took 17 clock cycles to generate the IP\/UDP packet header fields.<\/p>\n<p>As the team developed the initial HDL design, ChipScope was vital to understanding the nuances of the TEMAC interface, but it also impeded the goal of achieving a 125MHz clock. Additional logic-capture circuits altered the critical path and required manual floorplanning for timing closure.<\/p>\n<p>The critical path was calculating the IP and UDP header checksums because the straightforward design used a four-operand adder to sum multiple header fields together in various states. The HDL design attempted a \u2018greedy\u2019 scheduling algorithm that tried to do as much work as possible per state machine cycle. By removing ChipScope on these operations and by floorplanning, the team closed timing.<\/p>\n<p>The HDL design also used only one port of a 32bit-wide block RAM that acted as the transmit packet buffer. Agilent chose a 32bit-wide memory because it is the native width of the BRAM primitive and allowed for byte-enable write accesses that would avoid the need for read-modify-write access to the transmit buffer.<\/p>\n<p>Using byte enables, the finite state machine (FSM) writes directly to the header field bytes needing modification at a RAM address. However, what seemed like good design choices based on knowledge of the underlying Xilinx fabric and algorithm yielded a design that failed to meet timing without manual placement of the four-input adders.<\/p>\n<p>Because the UDP algorithms were already available in various forms in C code or written as pseudocode in IP-related RFC documentation, recoding the UDP packet engine in C was not a major task and proved to yield a better insight into the packet header processing. Just taking the pseudocode and starting to write Verilog may have made for quicker coding, but this methodology would have sacrificed performance without fully studying the data and control flows involved.<\/p>\n<h2>Running Vivado HLS\/AutoESL<\/h2>\n<p>Vivado HLS\/AutoESL\u2019s ability to abstract the FIFO and RAM interfaces offered one of the best opportunities to optimize performance. Being able to code directly in C, the Agilent team could now easily include both ARP and DCHP routines in the packet engine. Figure 2 shows a flowchart of the design. The HDL design used a byte-wide FIFO interface that connected to the aggregation and sensor interface of the design, which remained in Verilog. Also, the Verilog design utilized a 32bit memory interface that collected 4byte of sample data and then saved that in the transmit buffer RAM as a 32bit word.<\/p>\n<div class=\"article_figure\"><a class=\"figure\" title=\"Figure 2. The packet engine flowchart shows the inclusion of ARP and DHCP. (Source: Agilent\/Xilinx)\" href=\"https:\/\/www.techdesignforums.com\/practicefiles\/2012\/10\/tdf-agilviv-oct12-fig2lrg.jpg\"><img decoding=\"async\" src=\"https:\/\/www.techdesignforums.com\/practicefiles\/2012\/10\/tdf-agilviv-oct12-fig2med.jpg\" alt=\"Vivado HLS - The packet engine flowchart shows the inclusion of ARP and DHCP\" \/><\/a><\/div>\n<div class=\"article_figure\">\n<p class=\"figure_wrapper\"><span class=\"figure_title\">Figure 2<\/span><br \/>\nThe packet engine flowchart shows the inclusion of ARP and DHCP. (Source: Agilent\/Xilinx \u2013 click image to enlarge)<\/p>\n<\/div>\n<p>Through its \u2018array reshape\u2019 directive,\u00a0Vivado HLS\/AutoESL optimized the memory interface so that the transmit buffers, while written in C code as an 8bit memory, became a 32-bit memory. This meant the C code could avoid having to do many bit manipulations of the header fields, as they would require bit shifting to place into a 32bit word. It also alleviated little-endian vs. big-endian byte-ordering issues.<\/p>\n<p>This optimization reduced the latency of the TX offload function that computes the packet checksums and generates header fields from 17 clocks, as originally written in Verilog, to just seven clock cycles while easily meeting timing.\u00a0Vivado HLS\/AutoESL could do better in the future. The version used did not have the ability to manipulate byte enables on RAM writes. Byte-enabled memory support is on the tool\u2019s long-term roadmap.<\/p>\n<p>Another optimization\u00a0Vivado HLS\/AutoESL performed, which was found by serendipity, was to access both ports of the memory, since Xilinx block RAM is inherently dual-port. The Verilog design reserved the second port of the transmit buffer so that its interface to the TEMAC would be able to access the buffer without any need for arbitration. By allowing\u00a0Vivado HLS\/AutoESL to optimize for our true dual-port RAM, the design became capable of performing reads or writes from two different locations of the buffer. In effect, this halved the cycles necessary to generate the header. The reduction in latency was well worth the effort in creating a simple arbiter in Verilog for the second port of the memory so that the TEMAC interface could access the memory port that\u00a0Vivado HLS\/AutoESL usurped.<\/p>\n<p>Agilent controlled the bit widths of the transmit buffer and the sample FIFO interfaces via directives.\u00a0Vivado HLS\/AutoESL does not automatically optimize a design. You have to experiment with a variety of directives and determine through trial and error which delivers an improvement. For this design, reducing the number of clock cycles to process the packet fields while operating at 125MHz was the goal.<\/p>\n<p>The \u2018array reshape\u2019 and loop \u2018pipeline\u2019 directives were important for optimizing the design. The reshape directive alters the bit width of the RAM and FIFO interfaces, which ultimately led to processing multiple header fields in parallel per clock cycle and writeback to memory. The best combination that yielded the least cycles was a transmit buffer bit width of 32. The width of the FIFO feeding ADC samples was not a factor in reducing the overall latency because it is impossible to force samples to arrive faster.<\/p>\n<p>The loop-pipelining directive is extremely important too because it indicates to the compiler that loops that push and pop from FIFO interfaces can operate back-to-back. Without the pipeline directive,\u00a0Vivado HLS\/AutoESL spent three to 20 clock cycles between pops of the FIFO due to scheduling reasons. It is therefore vital to use pipelining as much as possible to attain low latency when streaming data between memories.<\/p>\n<p>Xilinx block RAM also has a programmable data output latency of one to three clock cycles. Allowing three cycles of read latency enables the minimum \u2018clock to Q\u2019 timing. To experiment with different read latencies was only a matter of changing the \u2018latency\u2019 directive for the RAM primitive or \u2018core\u2019 resource. Because of the scheduling algorithms that\u00a0Vivado HLS\/AutoESL performed, adding a read latency of three cycles to access the RAM only tacked on one additional cycle of latency to the overall packet header generation. The extra cycle of memory latency allowed for more slack in the design, and that aided the place-and-route effort.<\/p>\n<p>Agilent also implemented ARP and DHCP routines in the\u00a0Vivado HLS\/AutoESL design. It had avoided doing so before because the routines are extremely cumbersome to write in Verilog and require a great number of states to perform. For instance, the ARP request\/response exchange would require more than 70 states. One coding error in the Verilog FSM would likely take days to undo. For this reason, many designers prefer to use a CPU to run these network routines.<\/p>\n<p>Overall,\u00a0Vivado HLS\/AutoESL excelled at generating a synthesizable netlist for the UDP packet engine. The module it generated fit between two preexisting ADC and TEMAC interface modules and performed the necessary packet header generation and additional tasks. The team was able to integrate the design\u00a0Vivado HLS\/AutoESL created into the core design and simulate it with Mentor Graphics\u2019 ModelSim to perform functional verification. With the streamlined design, timing closure was reached with less synthesis, map and place-and-route effort than for the original HDL design. Yet the result had significantly more functionality, such as ARP and DHCP.<\/p>\n<p>Comparing the original Verilog design with the hybrid design that used\u00a0Vivado HLS\/AutoESL to craft LAN MCU and TX Flow modules yielded impressive results. Table 1 shows a comparison of lookup table (LUT) usage.<\/p>\n<div class=\"article_figure\"><a class=\"figure\" title=\"Table 1. The Vivado HLS design used more lookup tables but incorporated more functionality. (Source: Agilent\/Xilinx)\" href=\"https:\/\/www.techdesignforums.com\/practicefiles\/2012\/10\/tdf-agilviv-oct12-tab1lrg.jpg\"><img decoding=\"async\" src=\"https:\/\/www.techdesignforums.com\/practicefiles\/2012\/10\/tdf-agilviv-oct12-tab1med.jpg\" alt=\"The Vivado HLS design used more lookup tables but incorporated more functionality\" \/><\/a><\/div>\n<div class=\"article_figure\">\n<p class=\"figure_wrapper\"><span class=\"figure_title\">Table 1<\/span><br \/>\nThe\u00a0Vivado HLS\/AutoESL design used more lookup tables but incorporated more functionality. (Source: Agilent\/Xilinx \u2013 click image to enlarge)<\/p>\n<\/div>\n<p>The HDL version of TX Flow was smaller by more than 37 percent, but the\u00a0Vivado HLS\/AutoESL design incorporated more functionality. Most impressive is that\u00a0Vivado HLS\/AutoESL reduced the number of cycles to perform our packet header generation by 59 percent.<\/p>\n<p>Table 2 shows the latency of the TX Offload algorithm.<\/p>\n<div class=\"article_figure\"><a class=\"figure\" title=\"Table 1. Vivado HLS improved the latency of the TX Offload algorithm. (Source: Agilent\/Xilinx)\" href=\"https:\/\/www.techdesignforums.com\/practicefiles\/2012\/10\/tdf-agilviv-oct12-tab2lrg.jpg\"><img decoding=\"async\" src=\"https:\/\/www.techdesignforums.com\/practicefiles\/2012\/10\/tdf-agilviv-oct12-tab2med.jpg\" alt=\"Vivado HLS improved the latency of the TX Offload algorithm\" \/><\/a><\/div>\n<div class=\"article_figure\">\n<p class=\"figure_wrapper\"><span class=\"figure_title\">Table 2<\/span><br \/>\nVivado HLS\/AutoESL improved the latency of the TX Offload algorithm. (Source: Agilent\/Xilinx \u2013 click image to enlarge)<\/p>\n<\/div>\n<p>The critical path of the HDL design was computing the UDP checksum. Comparing this with the\u00a0Vivado HLS\/AutoESL design showed that the HDL design suffered from 10 levels of logic and a total path delay of 6.4ns, whereas\u00a0Vivado HLS\/AutoESL optimized this to only three levels of logic and a path delay of 3.5ns. Development time for the HDL design was about a month. It took about the same amount of time with Vivado HLS\/AutoESL, but the results incorporated more functionality while increasing familiarity with the nuances of the tool.<\/p>\n<h2>Latency and throughput<\/h2>\n<p>Vivado HLS\/AutoESL\u00a0has a significant advantage over HDL design in that it performs control and data-flow analyses. It can then use the results to reorder operations to minimize latency and increase throughput. In this case, a greedy algorithm tried to do too many arithmetic operations per clock cycle. The tool rescheduled checksum calculations so as to use only two input adders, but scheduled them in such a way as to avoid increasing overall execution latency.<\/p>\n<p>Software compilers intrinsically perform these types of exercises. As state machines become more complex, the HDL designer is at a disadvantage compared to the omniscience of the compiler. An HDL designer would typically not have the opportunity to explore the effect of more than two architectural choices because of time constraints to deliver a design, but this may be a vital task to deliver a low-power design.<\/p>\n<p>The most important benefit of\u00a0Vivado HLS\/AutoESL was its ability to try a variety of scenarios, which would be tedious in Verilog. These included changing bit widths of FIFOs and RAMs, partitioning a large RAM into smaller memories, reordering arithmetic operations and using dual-port instead of single-port RAM. In an HDL design, each scenario would likely cost an additional day of coding followed by then testbench modification to verify correct functionality. With\u00a0Vivado HLS\/AutoESL these changes took minutes, were seamless and did not entail any major modification of the source code.<\/p>\n<p>Modifying large state machines is extremely cumbersome in Verilog. The advent of tools like\u00a0Vivado HLS\/AutoESL recalls the days when processor designers began to employ microprogramming instead of the hand-constructed state machines of early microprocessors such as the 8086 and 68000. With the arrival of RISC architectures and hardware description languages, microprogramming is mostly a lost artform, but its lesson is well learned in that abstraction is necessary to manage complexity. As microprogramming offered a higher layer of abstraction of state machine design, so do\u00a0Vivado HLS\/AutoESL and high-level synthesis tools in general. Tools of this caliber allow a designer to focus more on the algorithms themselves rather than the low-level implementation, which is error prone, difficult to modify and inflexible with future requirements.<\/p>\n<h2>About the authors<\/h2>\n<p><strong>Dr. Nathan Jachimiec<\/strong> <em>is an R&amp;D Engineer in the Technology Leadership Organization of Agilent Technologies.<\/em><\/p>\n<p><strong>Dr. Fernando Martinez Vallina\u00a0<\/strong> <em>is a Software Applications Engineer at Xilinx<\/em>.<\/p>\n<p><em>This article originally appeared in Issue 79 of <\/em>Xcell Journal<em>. Many thanks to them and Xilinx for permission to reproduce this version. To read the extended original, download the issue <a title=\"Xcell Journal Issue 79\" href=\"http:\/\/www.xilinx.com\/publications\/archives\/xcell\/Xcell79.pdf\" target=\"_blank\">here<\/a>. For more on the magazine itself and to download other issues, click <a title=\"Xcell Journal online\" href=\"http:\/\/www.xilinx.com\/publications\/xcellonline\/\" target=\"_blank\">here<\/a>.<\/em><\/p>\n<h2><em><\/em>Contact<\/h2>\n<p>Xilinx, Inc.<br \/>\n2100 Logic Drive<br \/>\nSan Jose<br \/>\nCA 95124-3400<br \/>\nUSA<\/p>\n<p>T: +1 408 559 7778<br \/>\nW: <a title=\"Xilinx home page\" href=\"http:\/\/www.xilinx.com\" target=\"_blank\">www.xilinx.com<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>How Xilinx&#8217; Vivado HLS enabled the creation of an in-fabric, processor-free UDP network packet engine<\/p>\n","protected":false},"author":138,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[934,41],"tags":[1147,1153,1152,771,1146,1150,1138,1149,1145],"coauthors":[51],"class_list":["post-3862","post","type-post","status-publish","format-standard","hentry","category-eda-topics","category-esl-codesign","tag-autoesl","tag-communications","tag-dhcp","tag-fpga","tag-high-level-synthesis","tag-internet-protocol","tag-ise-design-suite","tag-udp","tag-vivado","workflow-case-study","organization-agilent-technologies","organization-xilinx"],"_links":{"self":[{"href":"https:\/\/www.techdesignforums.com\/practice\/wp-json\/wp\/v2\/posts\/3862","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.techdesignforums.com\/practice\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.techdesignforums.com\/practice\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.techdesignforums.com\/practice\/wp-json\/wp\/v2\/users\/138"}],"replies":[{"embeddable":true,"href":"https:\/\/www.techdesignforums.com\/practice\/wp-json\/wp\/v2\/comments?post=3862"}],"version-history":[{"count":0,"href":"https:\/\/www.techdesignforums.com\/practice\/wp-json\/wp\/v2\/posts\/3862\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.techdesignforums.com\/practice\/wp-json\/wp\/v2\/media?parent=3862"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.techdesignforums.com\/practice\/wp-json\/wp\/v2\/categories?post=3862"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.techdesignforums.com\/practice\/wp-json\/wp\/v2\/tags?post=3862"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.techdesignforums.com\/practice\/wp-json\/wp\/v2\/coauthors?post=3862"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}