{"id":555,"date":"2016-03-23T15:14:42","date_gmt":"2016-03-23T15:14:42","guid":{"rendered":"http:\/\/panda.dei.polimi.it\/?page_id=555"},"modified":"2020-10-07T12:27:47","modified_gmt":"2020-10-07T12:27:47","slug":"tutorial","status":"publish","type":"page","link":"https:\/\/panda.deib.polimi.it\/?page_id=555","title":{"rendered":"<em>bambu<\/em> Tutorial"},"content":{"rendered":"<h2>1) Introduction<\/h2>\n<p>This tutorial is intended to guide new users with no previous experience using <em>bambu<\/em>. It will guide through all the necessary steps, starting from a C source application, explaining the different ways to use <em>bambu<\/em>, and showing how to generate and synthesize a working Verilog design.<\/p>\n<h2>2) Preliminaries<\/h2>\n<p>For this tutorial it will be assumed that you the <em>bambu<\/em> sources have already been downloaded from <a href=\"http:\/\/panda.dei.polimi.it\/?page_id=81\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a> and successfully configured and installed it, following the procedure described <a href=\"http:\/\/panda.dei.polimi.it\/?page_id=88\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a>. It is also assumed that the installed binaries are in the search path, so that it is possible to run <em>bambu<\/em> from the command line without specifying the full path. This can be checked by running the following command in a terminal.<\/p>\n<pre>$ bambu --version<\/pre>\n<p>If everything is fine, the output is the following (the last couple of lines may change depending on the version):<\/p>\n<pre>*******************************************************************\r\n                 ____                  _\r\n                | __ )  __ _ _ __ ___ | |_   _   _\r\n                |  _ \\ \/ _` | '_ ` _ \\| '_ \\| | | |\r\n                | |_) | (_| | | | | | | |_) | |_| |\r\n                |____\/ \\__,_|_| |_| |_|_.__\/ \\__,_|\r\n*******************************************************************\r\n                     High-Level Synthesis Tool\r\n\r\n                    Politecnico di Milano - DEIB\r\n                     System Architectures Group\r\n*******************************************************************\r\n            Copyright (c) 2004-2020 Politecnico di Milano\r\nVersion: PandA 0.9.6<\/pre>\n<p>In the rest of the tutorial, some examples that are already included in the <em>bambu<\/em> sources that you have downloaded will be used. Most of the tutorial does not require any vendor tool to be installed and configured along with <em>bambu<\/em>. However, to execute some common scenarios, some extra tools have to be installed. In particular:<\/p>\n<ul>\n<li>Section 4) shows how the generated design can be simulated and validated within the <em>bambu<\/em> HLS flow. This section assumes that at least one of the supported simulators is available that <em>bambu<\/em> was correctly configured to use the simulator. The configuration options for the simulators are explained <a href=\"http:\/\/panda.dei.polimi.it\/?page_id=88\">here<\/a>.<br \/>\nIf commercial simulators are not available, one of the supported Open Source simulators can be used: Icarus Verilog and Verilator. They are usually distributed as standard packages in the most common Linux distributions, with the names <code>iverilog<\/code> and <code>verilator<\/code> respectively. Since they do not support mixed simulation and since the generated testbenches are written in Verilog, this will be used as the target language in the examples of this tutorial. However, <em>bambu<\/em> is also able to generate VHDL as it will be shown in Section 9 of the tutorial.<\/li>\n<li>Section 5) shows how to use <em>bambu<\/em> for a complete synthesis flow. The tool starts from a C source code application, it generates the Verilog, and then it automatically invokes the synthesis tool for logic synthesis, technology mapping, place, and route. The synthesis tools are strictly dependent on vendors and target devices and <em>bambu<\/em> has to be properly configured to use them. The supported synthesis tools are <a href=\"http:\/\/panda.dei.polimi.it\/?page_id=88\">described in the installation instructions<\/a>, along with the configuration options to enable them.<\/li>\n<\/ul>\n<p>All the other examples presented in the tutorial do not require any additional tools. If some of the described procedures does not work out as expected, please report it to <a href=\"https:\/\/groups.google.com\/forum\/#!forum\/panda-project-discussions-questions\" target=\"_blank\" rel=\"noopener noreferrer\">this google group<\/a> or send an email to panda-info@polimi.it.<\/p>\n<h2>3) Basic Usage &#8211; Generation of a Verilog design from C sources<\/h2>\n<p>The first example that will be presented is based on the CRC code. Initially enter the directory containing the example files.<\/p>\n<pre>$ cd BAMBU_SOURCE_ROOT_DIR\/examples\/crc<\/pre>\n<p>The directory contains the C source file for our example <code>spec.c<\/code>, along with a number of shell scripts and other auxiliary files.<br \/>\nNow create your own <code>tutorial<\/code> directory (where you will work from now on), and enter into it.<\/p>\n<pre>$ mkdir tutorial\r\n$ cd tutorial<\/pre>\n<p>Working in a separate directory is not required, but it is advised for this tutorial because <em>bambu<\/em> generates a bunch of files during its execution. Keeping them in a separate place will help us to get acquainted with <em>bambu<\/em>&#8216;s output, without mixing it with other stuff.<\/p>\n<p><em>bambu<\/em> can be now run for the first time.<\/p>\n<pre>$ bambu ..\/spec.c<\/pre>\n<p>This operation launches the default High-Level Synthesis (HLS) flow: a Verilog design will be generated from the <code>..\/spec.c<\/code> source file.<br \/>\nAfter the execution, the <code>tutorial<\/code> directory will contain some files.<\/p>\n<pre>$ ls\r\n0_array_ref_22490.mem\r\n0_array_ref_23102.mem\r\narray_ref_22490.mem\r\narray_ref_22670.mem\r\narray_ref_22695.mem\r\narray_ref_22746.mem\r\narray_ref_22775.mem\r\narray_ref_23102.mem\r\nHLS_output\/\r\nsynthesize_Synthesis_main_minimal_interface.sh\r\ntop.v<\/pre>\n<p>Note that the indices contained in the names of the .mem files produced by <em>bambu<\/em> can be different on different systems.<br \/>\n<code>top.v<\/code> contains the Verilog design generated by <em>bambu<\/em> for the C program. It is not very straightforward to read, because it&#8217;s machine-generated and it is not intended to be human-readable.<br \/>\nWith default options <em>bambu<\/em> does not trigger any kind of simulation, nor it invokes vendor tools for the synthesis. Nevertheless, it generates <code>synthesize_Synthesis_main_minimal_interface.sh<\/code> shell script which can be used from the command line to launch the vendor tools for the synthesis. Since the target FPGA was not specified, <em>bambu<\/em> generated scripts targeting the default device (xc7z020,-1,clg48). The details on how to select the target device will be later provided in the tutorial.<br \/>\n<code>HLS_output<\/code> is a directory where <em>bambu<\/em> places different results. It contains a <code>Synthesis<\/code> subdirectory with some empty subdirectories (<code>input<\/code> and <code>output<\/code>), a <code>.tcl<\/code> script to launch the synthesis and a <code>.sdc<\/code> file containing the design constraints. They will be used when the synthesis is executed, and the <code>input<\/code> and <code>output<\/code> directories will be filled with the necessary stuff by the <code>synthesize_Synthesis_main_minimal_interface.sh<\/code> script.<br \/>\nFinally, all the <code>*.mem<\/code> files contain data for the initialization of the memories.<\/p>\n<p>In this example, a single C file is used, but the same command can be used to synthesize multiple source files at the same time to generate a single design. Most of the typical C compiler options can be used with <em>bambu<\/em>.<br \/>\nFor example optimizations can be enabled by using <code>-O0<\/code>, <code>-O1<\/code>, <code>-O2<\/code>, <code>-O3<\/code>, <code>-Os<\/code> or you can specify include directories with <code>-I&lt;include_directory_name&gt;<\/code>, so that all the necessary headers are correctly found.<\/p>\n<p>The High-Level Synthesis flow can be limited to a subset of functions present in the C file. For example, in <code>spec.c<\/code> file, the <code>main()<\/code> is only calling <code>icrc()<\/code> multiple times to test it. It may make sense to generate an hardware accelerator only for the <code>icrc()<\/code> function.<br \/>\nThis is possible with <em>bambu<\/em>, using the command line option <code>--top-fname=&lt;function_name&gt;<\/code>, like this:<\/p>\n<pre>$ bambu ..\/spec.c --top-fname=icrc<\/pre>\n<p>This will generate a new <code>icrc.v<\/code> Verilog file in the current directory, along with a new <code>synthesize_Synthesis_icrc_minimal_interface.sh<\/code> shell script for the synthesis, and another subdirectory of <code>HLS_output\/Synthesis\/<\/code> to handle this.<br \/>\nThe result is that <code>main()<\/code> is not synthesized and a smaller core implementing only the <code>icrc()<\/code> functionality is produced.<\/p>\n<h2>4) Simulation<\/h2>\n<p>Before actually starting the synthesis, it is possible to simulate the generated design. The C source code is compiled and executed with randomly generated inputs or with user-provided inputs. The execution of the C program returns a result which is compared with the result produced by the simulated Verilog: if they match the co-simulation succeeds, otherwise it fails and the difference is reported to the user.<br \/>\nThis section will show how to perform and control the co-simulation workflow.<\/p>\n<p>The basic <em>bambu<\/em> invocation for simulation is the following.<\/p>\n<pre>$ bambu ..\/spec.c --simulate --simulator=VERILATOR<\/pre>\n<p>This command invokes the <em>bambu<\/em> with the default HLS flow, but after the generation of the HDL design, the co-simulation flow is automatically started and performed with Verilator.<br \/>\nThe <code>--simulate<\/code> flag enables co-simulation, while <code>--simulator=YOUR_FAVORITE_SIMULATOR<\/code> tells bambu which simulator to use.<br \/>\nValid strings for YOUR_FAVORITE_SIMULATOR are:<\/p>\n<ul>\n<li><code>VERILATOR<\/code><\/li>\n<li><code>ICARUS<\/code><\/li>\n<li><code>MODELSIM<\/code><\/li>\n<li><code>XSIM<\/code>\u00a0 (the Xilinx simulator provided with Vivado)<\/li>\n<li><code>ISIM<\/code>\u00a0 (the Xilinx simulator provided with ISE)<\/li>\n<\/ul>\n<p>If none of the above is specified and you simply pass <code>--simulate<\/code>, <em>bambu<\/em> selects one by default. Remember that you need to have <em>bambu<\/em> configured with the proper options to the <code>configure<\/code> script and to have the correct simulator installed in order to use it. See <a href=\"http:\/\/panda.dei.polimi.it\/?page_id=88\">panda installation<\/a> for information on how to do it. In the remainder of the tutorial VERILATOR is used. Be careful because it does not support VHDL.<\/p>\n<p>In general, one should provide input values for the simulation. If they are not specified, <em>bambu<\/em> generates them randomly and saves them in a <code>test.xml<\/code> file in the current working directory. In this example, given that <code>main()<\/code> has no arguments the <code>test.xml<\/code> file is an empty stub, like this:<\/p>\n<pre>$ cat test.xml\r\n&lt;?xml version=\"1.0\"?&gt;\r\n&lt;function&gt;\r\n &lt;testbench\/&gt;\r\n&lt;\/function&gt;<\/pre>\n<p><em>bambu<\/em> also generates a short report on the simulation cycles:<\/p>\n<pre> Total cycles : 2898 cycles\r\n Number of executions : 1\r\n Average execution : 2898 cycles<\/pre>\n<p>The report contains information about how many times the design was simulated (1 time) and how many cycles the simulation took to terminate (2898 cycles). The simulation is useful for preliminary functional verification and for performances evaluation. Moreover, the obtained number of cycles can be slightly different on different systems.<\/p>\n<p>To co-simulate the <code>icrc()<\/code> function, the test inputs cannot be generated randomly, because the parameter <code>unsigned char *lin<\/code> is a pointer, and the <code>icrc()<\/code> function assumes that it points to an array of <code>unsigned char<\/code>s whose length is expressed by the parameter <code>unsigned int len<\/code>. For this reason, the task of providing meaningful inputs is entirely demanded to the user. The examples provided with <em>bambu<\/em> already contain the .xml files with the input data. For example, for <code>icrc()<\/code>, the <code>..\/test_icrc.xml<\/code> file can be used. Its content is the following:<\/p>\n<pre>&lt;?xml version=\"1.0\"?&gt;\r\n&lt;function&gt;\r\n &lt;testbench crc=\"0\" lin=\"{97,115,100,102,102,101,97,103,101,119,97,72,65,70,69,70,97,101,68,115,70,69,97,119,70,100,115,70,97,101,102,97,101,101,114,100,106,103,112,105,109,50,51,0}\" len=\"40\" jinit=\"0\" jrev=\"1\"\/&gt;\r\n &lt;testbench crc=\"57266\" lin=\"{97,115,100,102,102,101,97,103,101,119,97,72,65,70,69,70,97,101,68,115,70,69,97,119,70,100,115,70,97,101,102,97,101,101,114,100,106,103,112,105,109,50,51,0}\" len=\"42\" jinit=\"-1\" jrev=\"1\"\/&gt;\r\n&lt;\/function&gt;<\/pre>\n<p>In the tutorial directory created in section (3), <em>bambu<\/em> can be invoked in this way:<\/p>\n<pre>$ bambu ..\/spec.c --top-fname=icrc --generate-tb=..\/test_icrc.xml --simulate --simulator=VERILATOR<\/pre>\n<p><em>bambu<\/em> will create a design for the <code>icrc()<\/code> function and will start the co-simulation workflow with the input data in <code>..\/test_icrc.xml<\/code>.<\/p>\n<p><code>test_icrc.xml<\/code> contains 2 <code>&lt;testbench ...\/&gt;;<\/code> nodes. Each of them represents the arguments of a call to the <code>icrc()<\/code> function. The context is preserved across consecutive calls, both in C and in HDL. In this way, if the first call makes some change in global or <code>static<\/code> variables, they will be visible in the following calls. This behavior is intended to reproduce the case when a HW module is executed multiple times and it keeps an internal state across multiple executions. With <code>test_icrc.xml<\/code> the <code>icrc()<\/code> function is executed two times consecutively. The content of the generated report is:<\/p>\n<pre>Total cycles : 2897 cycles\r\nNumber of executions : 2\r\nAverage execution : 1448 cycles<\/pre>\n<p>Differently from the previous report, the number of executions is 2 and the total number of cycles is 2897, with an average of 1448 cycles per execution.<br \/>\nThe <code>results.txt<\/code> file that was created during the execution in your working directory contains a detailed report of the number of cycles for each call.<\/p>\n<pre>$ cat results.txt\r\n 1 2725\r\n 1 172<\/pre>\n<p>Each line of this file contains data about an execution corresponding to one line of <code>&lt;testbench ...\/&gt;<\/code> line in the XML. The first number of every row is the result of the execution (1 for success &#8211; 0 for failure) while the second value is the number of the cycles.<\/p>\n<h2>5) A Complete Example<\/h2>\n<p>After showing how to generate the Verilog design from C, and how to validate it with the co-simulation, a complete example for a real-world use case will be presented.<br \/>\nThis example starts with a project with a mix of C and Verilog source files. In this scenario, the Verilog files are hand-written and describe very low-level operations, possibly performing I\/O or interfacing with other peripherals (but they can be any kind of user-provided Verilog modules). The C source code, instead, describes at a higher level the whole specification, which has to interface with the Verilog modules to accomplish its functionality. In such a scenario, HLS is used to create a single design where hand-written Verilog modules are integrated with the code generated by <em>bambu<\/em> starting from the C source code. In particular, it will be shown how to map C function calls onto Verilog modules and, how to use the co-simulation workflow even when hand-written modules are part of the project. Co-simulation of mixed design is possible only if a C golden reference for HDL modules is provided. Finally, it will be shown how to generate the bitstream from the mixed C\/Verilog project and how to flash it on a Digilent NEXYS4 evaluation board.<\/p>\n<p><a href=\"http:\/\/panda.dei.polimi.it\/wp-content\/uploads\/Nexys4.jpg\" rel=\"attachment wp-att-571\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-571\" src=\"http:\/\/panda.dei.polimi.it\/wp-content\/uploads\/Nexys4-300x275.jpg\" alt=\"Nexys4\" width=\"300\" height=\"275\" srcset=\"https:\/\/panda.deib.polimi.it\/wp-content\/uploads\/Nexys4-300x275.jpg 300w, https:\/\/panda.deib.polimi.it\/wp-content\/uploads\/Nexys4-768x704.jpg 768w, https:\/\/panda.deib.polimi.it\/wp-content\/uploads\/Nexys4-1024x938.jpg 1024w, https:\/\/panda.deib.polimi.it\/wp-content\/uploads\/Nexys4.jpg 2000w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>This board contains a Xilinx Artix-7 FPGA, with a wide number of different external interfaces (USB, Ethernet, JTAG, microSD, accelerometer, VGA output, temperature sensor, multiple LEDs, pushbuttons, 7-segment displays, manual switches, and others).<br \/>\nThe example aims to build a fixed-point binary-to-decimal converter. The input binary representation is set with the 16 manual switches, and the resulting decimal representation of the number is shown in real-time on the 7-segments displays. For binary representation, an unsigned <a href=\"https:\/\/en.wikipedia.org\/wiki\/Q_%28number_format%29\">Q16.16 binary format for fixed-point<\/a> is used. The first 8 switches on the left in the picture are used for the integer bits, while the 8 switches to the right are used for the fractional bits. As shown in the picture below, when a switch is moved up, the corresponding bit is set to 1 and the green led nearby the switch is turned on. When a switch is moved down, the led is turned off and the corresponding bit is set to 0. At the same time, the decimal representation on the 7-segments display is updated accordingly. The conversion can be controlled with two push buttons, as depicted in the picture. The central button starts the conversion. After the conversion is started every action on the switches directly changes the result on the 7-segments displays. The upper button stops the conversion so that changes of the positions of the switches do not change the value on the 7-segments displays. If the central button is pressed again, the conversion is restarted.<\/p>\n<p><a href=\"http:\/\/panda.dei.polimi.it\/wp-content\/uploads\/nexys4-example.jpg\" rel=\"attachment wp-att-573\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-573\" src=\"http:\/\/panda.dei.polimi.it\/wp-content\/uploads\/nexys4-example-300x169.jpg\" alt=\"nexys4-example\" width=\"300\" height=\"169\" srcset=\"https:\/\/panda.deib.polimi.it\/wp-content\/uploads\/nexys4-example-300x169.jpg 300w, https:\/\/panda.deib.polimi.it\/wp-content\/uploads\/nexys4-example-768x432.jpg 768w, https:\/\/panda.deib.polimi.it\/wp-content\/uploads\/nexys4-example-1024x576.jpg 1024w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Implementing this accelerator by means of <em>bambu<\/em> is the final objective of this tutorial.<\/p>\n<h4>5.1) Mapping C functions to hand-written HDL modules<\/h4>\n<p>The first step is going in the example directory:<\/p>\n<pre>$ cd BAMBU_SOURCE_ROOT_DIR\/examples\/led_example\r\n$ mkdir tutorial\r\n$ cd tutorial<\/pre>\n<p>Next step is <em>bambu<\/em> invocation:<\/p>\n<pre>$ bambu ..\/led_example.c --top-fname=led_example ..\/IPs.xml<\/pre>\n<p>With respect to the previous examples, the significant change is that the file <code>..\/IPs.xml<\/code> is passed to <em>bambu<\/em> along with the C source code. <code>..\/IPs.xml<\/code> contains a list of cells, in the form <code>&lt;cell&gt;...&lt;\/cell&gt;<\/code>. Each of them represents the mapping of a C function onto a Verilog module. Every cell also contains some information on the Verilog module, that will be used for the interconnection with other modules in the design and with external I\/O ports during High-Level Synthesis.<br \/>\nIn this example, in <code>leds_example.c<\/code> there are 4 called functions for which the C source code is not provided. These functions are <code>sw_ctrl()<\/code>, <code>leds_ctrl()<\/code>, <code>sevensegments_ctrl()<\/code> and <code>btn_ctrl()<\/code>. They are defined as extern in separate headers. Their prototypes are the following.<\/p>\n<pre>extern unsigned short sw_ctrl();\r\nextern void leds_ctrl(unsigned short val);\r\nextern void sevensegments_ctrl(unsigned long long val, unsigned long long mask);\r\nextern unsigned char btn_ctrl();<\/pre>\n<p>Every function acts as a device driver for some peripherals of the board. It has not yet been shown how to specify to <em>bambu<\/em> how the pins are connected, but this aspect can be ignored for the moment.<\/p>\n<p>The function <code>sw_ctrl()<\/code> is used to read the position of the manual switches. From the C source code side, it takes no arguments and returns an <code>unsigned short<\/code>. The returned value is 16 bits wide and every bit represents the position of a manual switch. It takes no argument because the value of the switches will be internally read from some I\/O pin.<\/p>\n<p>The function <code>leds_ctrl()<\/code> controls the LEDs connected to the switches. It takes an <code>unsigned short<\/code> argument and it returns <code>void<\/code>. The argument is an <code>unsigned short<\/code> representing the position of the manual switches. No value is returned, but internally the function sets some I\/O pins to power on the LEDs whose corresponding switches are set to &#8220;1&#8221;.<\/p>\n<p>The function <code>sevensegments_ctrl()<\/code> drives the 7-segments displays. It takes two <code>unsigned long long<\/code> arguments: <code>val<\/code> and <code>mask<\/code>. These values are used to make the displays show the correct numbers. The specification of the format can be found on the datasheet of the board. Also, this function does not return any value, because the 7-segments displays have no notification mechanism to communicate the success of the operation.<\/p>\n<p>Finally, <code>btn_ctrl()<\/code> handles the two pushbuttons. It takes no arguments, because the state of the buttons is read from I\/O pins, and it returns an <code>unsigned char<\/code> representing the state of the buttons.<\/p>\n<p>These four modules will not be synthesized from C code, but the already existing Verilog modules will be used: <code>sw_ctrl.v<\/code>, <code>leds_ctrl.v<\/code>, <code>sevensegments_ctrl.v<\/code> and <code>btn_ctrl.v<\/code>. The information on where are the descriptions of these Verilog modules is contained in <code>IPs.xml<\/code>.<\/p>\n<p><code>IPs.xml<\/code> contains 4 cells, one for every C function that is mapped on an HW module. For every cell, the following information must be specified:<\/p>\n<ol>\n<li><code>&lt;name&gt;module_name&lt;\/name&gt;<\/code>: the name of the Verilog module.<\/li>\n<li><code>&lt;operation operation_name=\"op_name\" [params]\/&gt;<\/code>: the high-level information on the operation that is mapped onto the Verilog module associated with this cell.<br \/>\n<code>\"op_name\"<\/code>: a string used by the HLS engine during module allocation and binding, to decide which unresolved C function is mapped onto the Verilog module described by this cell.<br \/>\n<code>[params]<\/code>: a list of assignments in the form <code>par_name=\"par_val\"<\/code>.<br \/>\nThese values are used by the HLS engine for performing the schedule.<br \/>\n<code>bounded=\"0\"<\/code> specifies that the execution time is unknown or not constant while <code>bounded=\"1\"<\/code> specifies that the execution time is known and constant; by default (i.e., if this parameter is not specified) it is assumed that the execution time is constant and known. For a bounded operation, the following quantities have to be specified, depending if the module is pipelined or not. If the module is pipelined the necessary additional parameters are:<\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\n<li><code>cycles=\"n\"<\/code>, where <code>n<\/code> is the total number of cycles for the execution;<\/li>\n<li><code>initiation_time=\"k\"<\/code>, where <code>k<\/code> is the initiation time of the pipeline;<\/li>\n<li><code>stage_period=\"f\"<\/code>, where <code>f<\/code> is a floating point number representing the execution time (in nanoseconds) of a stage of the pipeline.<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p>If the module is not pipelined the necessary additional parameters are:<\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\n<li><code>cycles=\"n\"<\/code>, where <code>n<\/code> is the total number of cycles for the execution, greater or equal than 1;<\/li>\n<li><code>execution_time=\"f\"<\/code>, where <code>f<\/code> is a floating point number representing the execution time in nanoseconds, it is only meaningful when <code>n<\/code> is 1, because it allows chaining;<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p>In <code>IPs.xml<\/code> all the modules are bounded and there are both pipelined and not pipelined modules.<\/li>\n<li><code>&lt;circuit&gt;&lt;component_o id=\"module_name\"&gt;[body]&lt;\/component_o&gt;&lt;\/circuit&gt;<\/code>: inside this block the port bindings and the Verilog file where the implementation of the module can be found are specified. <code>\"module_name\"<\/code> must match the <code>\"module_name\"<\/code> string used in <code>&lt;name&gt;\"module_name\"&lt;\/name&gt;<\/code>.<br \/>\nThe <code>[body]<\/code> contains several fields. The relevant ones in this example are:<\/p>\n<ol>\n<li><code>&lt;structural_type_descriptor id_type=\"module_name\"&gt;<\/code>: the name of this Verilog module which will be used for its instantiation in other modules.<\/li>\n<li>A list of port specifications. Every port specification has the form<br \/>\n<code>&lt;port_o id=\"signal_name\" dir=\"direction\" [params]&gt;&lt;structural_type_descriptor type=\"type_str\" size=\"n\"&gt;&lt;\/port_o&gt;<\/code><br \/>\n<code>\"direction\"<\/code> can be <code>\"IN\"<\/code> or <code>\"OUT\"<\/code>, depending on the direction of the signal. <em>bambu<\/em> cannot interface directly C source code with modules with <code>inout<\/code> ports in Verilog. In C the semantic is always either <code>\"IN\"<\/code> (for parameters passed to functions) or <code>\"OUT\"<\/code> (for return values of functions).<br \/>\n<code>\"signal_name\"<\/code> must match the name of a module port, as specified in the Verilog file containing the description of the module. The in\/out direction must match that of the Verilog files.<br \/>\n<code>\"type_str\"<\/code> is a string representing the type of the signal. Valid types are <code>\"BOOL\"<\/code>, <code>\"INT\"<\/code>, <code>\"UINT\"<\/code> and <code>REAL<\/code>.<br \/>\n<code>\"n\"<\/code> is a positive integer representing the bitsize of the port. It must always be 1 for <code>\"BOOL\"<\/code>. For the other types it must be the size of the corresponding variable in C.<br \/>\nThe order of the specification of the ports must be the same in the Verilog declaration and in the XML description passed to <em>bambu<\/em>.<br \/>\n&#8211; The first port must always be the clock port, so it must be a boolean_port named clock. A special attribute is also used to specify <em>bambu<\/em> that it is the <strong>clock<\/strong> port. The complete XML specification is:<\/p>\n<pre>&lt;port_o id=\"clock\" dir=\"IN\" is_clock=\"1\"&gt;\r\n  &lt;structural_type_descriptor type=\"BOOL\" size=\"1\"\/&gt;\r\n&lt;\/port_o&gt;<\/pre>\n<p>&#8211; The second must always be the <strong>reset<\/strong> signal. The complete XML specification is:<\/p>\n<pre>&lt;port_o id=\"reset\" dir=\"IN\"&gt;\r\n  &lt;structural_type_descriptor type=\"BOOL\" size=\"1\"\/&gt;\r\n&lt;\/port_o&gt;<\/pre>\n<p>&#8211; The third must always be the <strong>start_port<\/strong>. The complete XML specification is:<\/p>\n<pre>&lt;port_o id=\"start_port\" dir=\"IN\"&gt;\r\n  &lt;structural_type_descriptor type=\"BOOL\" size=\"1\"\/&gt;\r\n&lt;\/port_o&gt;<\/pre>\n<p>&#8211; Then, if the module is not bounded, it is necessary to specify the <strong>done_port<\/strong>. The complete XML specification is:<\/p>\n<pre>&lt;port_o id=\"done_port\" dir=\"OUT\"&gt;\r\n  &lt;structural_type_descriptor type=\"BOOL\" size=\"1\"\/&gt;\r\n&lt;\/port_o&gt;<\/pre>\n<p>This port is used for unbounded modules, to signal the caller that the execution has terminated and the results are ready in the return port (if the function return type is not <code>void<\/code>).<br \/>\n&#8211; The next port to be specified is the <strong>return_port<\/strong>. This is the port used to return a value to the caller. For this reason, it is not necessary to specify it if the mapped function has void return type. The <code>id<\/code> can be any name, the <code>dir<\/code> must be <code>\"OUT\"<\/code> and the <code>type<\/code> and <code>size<\/code> must match the return type of the C function.<br \/>\n&#8211; Then it is possible to specify the ports for the parameters of the mapped function. Also, in this case, the <code>id<\/code> can be any name, but <code>dir<\/code> must be <code>\"IN\"<\/code>. The <code>type<\/code> and <code>size<\/code> must match those of the parameters of the mapped function. The mapping of ports to parameter will be done following the specification order.<br \/>\n&#8211; Finally, the last ports to be specified are those used to drive global Verilog signals, connected to some external peripherals. In this example, there are <code>leds<\/code> signal (controlling the LEDs, and others in other modules). All these external global signals must be specified with additional ports. For the <code>leds<\/code> signal the full XML specification is:<\/p>\n<pre>&lt;port_o id=\"done_port\" dir=\"OUT\" is_global=\"1\" is_extern=\"1\"&gt;\r\n  &lt;structural_type_descriptor type=\"UINT\" size=\"16\" \/&gt;\r\n&lt;\/port_o&gt;<\/pre>\n<p>The <code>is_global<\/code> and <code>is_extern<\/code> parameters will do the trick.<\/li>\n<li><code>&lt;NP_functionality LIBRARY=\"module_name\" VERILOG_FILE_PROVIDED=\"verilog_filename.v\"&gt;<\/code>: this specifies where the Verilog description of the provided module is.<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p>This is the full description of the XML format that can be used to specify to <em>bambu<\/em> how to map C function calls onto user-provided Verilog modules.<br \/>\nIn case you are using external modules written in VHDL instead of Verilog, you simply have to change <code>VERILOG_FILE_PROVIDED<\/code> to <code>VHDL_FILE_PROVIDED<\/code> in the xml, and to change the <code>\"verilog_filename.v\"<\/code> accordingly to the proper VHDL file name.<\/p>\n<p>Now we can continue with the example. The last command we ran was:<\/p>\n<pre>$ bambu ..\/led_example.c ..\/IPs.xml --top-fname=led_example<\/pre>\n<p>This command performs HLS on <code>led_example.c<\/code>, specifying to <em>bambu<\/em> the Verilog binding, but the information provided to the tool is not enough to generate the final accelerator. Indeed, in the generated <code>led_example.v<\/code> there are some instances of Verilog modules that are used but are not defined. The HLS flow completes successfully, but the generated design cannot be synthesized because the user-defined Verilog modules are not present. So, the command line has to be extended in this way:<\/p>\n<pre>$ bambu ..\/led_example.c ..\/IPs.xml --top-fname=led_example --file-input-data=..\/leds_ctrl.v,..\/sw_ctrl.v,..\/btn_ctrl.v,..\/sevensegments_ctrl.v<\/pre>\n<p>Here the argument <code>--file-input--data=..\/leds_ctrl.v,..\/sw_ctrl.v,..\/btn_ctrl.v,..\/sevensegments_ctrl.v<\/code> tells <em>bambu<\/em> where to find the definitions of the Verilog modules. The given Verilog files will be copied in the working directory and the synthesis script will be set up to use them.<\/p>\n<h4>5.2) Simulation with hand-written HDL modules<\/h4>\n<p>Before going on to the generation of the bitstream, one may be interested in checking the correctness of the generated HDL with simulation. Like explained above, <em>bambu<\/em> has two command-line arguments that can be used to do this: <code>--simulate<\/code> and <code>--simulator=YOUR_FAVORITE_SIMULATOR<\/code>. When using simulation, <em>bambu<\/em> does not just simulate your design, but it also generates automatically the testbench for you, starting from the original specification. The specification is usually the original C code used for HLS. However, in this example, there are some Verilog modules that are not generated with HLS. These modules control the LEDs, the buttons, and basically everything that interacts with the peripherals of the board. Even providing information about the position of Verilog custom modules, the co-simulation cannot be executed since it requires to have the full specification written in C source code. For this reason, it is also necessary to provide a reference C implementation for each hand-written Verilog module. In this way, <em>bambu<\/em> can compile and execute the C code to provide a golden reference for the co-simulation. To provide the C reference implementations, run <em>bambu<\/em> as follows:<\/p>\n<pre>$ bambu ..\/led_example.c ..\/IPs.xml --top-fname=led_example --simulate --simulator=VERILATOR --file-input-data=..\/leds_ctrl.v,..\/sw_ctrl.v,..\/btn_ctrl.v,..\/sevensegments_ctrl.v --C-no-parse=..\/leds_ctrl.c,..\/sw_ctrl.c,..\/btn_ctrl.c,..\/sevensegments_ctrl.c<\/pre>\n<p>The argument <code>--C-no-parse=..\/leds_ctrl.c,..\/sw_ctrl.c,..\/btn_ctrl.c,..\/sevensegments_ctrl.c<\/code> specifies <em>bambu<\/em> to use also these C source files to create the executable for the co-simulation. However, these files are not used for HLS: the C function calls are still mapped on the user-provided Verilog modules as described in <code>IPs.xml<\/code>.<\/p>\n<p>This just works but a few subtleties are going on under the hood. Here the C files (passed with the command line option <code>--C-no-parse<\/code>) mimick in C the behavior of the underlying Verilog modules. If you look into <code>btn_ctrl.c<\/code> you can see that in the C version the button is always pressed (it always returns 1). Now, when performing the co-simulation with the testbench generated from the C code, <em>bambu<\/em> expects that the behavior of the HDL is the same as the C code. This is done by checking that the value returned by the C program is the same as the result written on the output port of the generated HW module. In this case, the function we synthesized returns void, so there is actually no value to compare. But the key difference is that software execution terminates because the &#8216;button&#8217; is pressed. If during the simulation nobody is pressing the button, the simulation runs forever, waiting for the button to be pressed. In this sense, it does not behave like the C code. This situation is handled adding some extra code in <code>btn_ctrl.v<\/code>, inside the <code>btn_ctrl<\/code> module:<\/p>\n<pre> \/\/ synthesis translate_off \r\nreg [4:0] button_press_countdown = 5'b11111; \r\nwire [4:0] next_button_press_countdown; \r\nassign next_button_press_countdown = button_press_countdown - 1; \r\n \r\nalways @(posedge clock) \r\nbegin \r\n\u00a0 button_press_countdown &lt;= next_button_press_countdown; \r\nend \r\n \r\nalways @(posedge clock) \r\nbegin \r\n\u00a0 if (button_press_countdown == 0) \r\n\u00a0 begin \r\n\u00a0 out1 &lt;= 1; \r\n\u00a0 sigTmp &lt;= 1; \r\n\u00a0 stble &lt;= 1; \r\n\u00a0 end \r\nend \r\n\/\/ synthesis translate_on<\/pre>\n<p>Thanks to the directives in the comments, this code is not synthesized. In this way, if you generate the bitstream for the board everything will work as expected with the real buttons.<br \/>\nHowever, in simulation, you will see that the button is artificially pressed &#8216;from inside&#8217;, so that the Verilog code behaves like expected in co-simulation and <em>bambu<\/em> is happy.<br \/>\nThere are other ways to achieve this, like using delayed assignments in an initial block, always with the <code>translate_off<\/code> and <code>translate_on<\/code> directives. This is just an example.<\/p>\n<p>This is an issue you have to bear in mind every time you use co-simulation together with hand-written or third-parties modules.<br \/>\nYou always have to provide a C model for co-simulation and make sure that the behavior of the modules not generated with HLS actually matches the behavior of the corresponding C models. Otherwise, the co-simulation will return an error and the flow will not continue.<\/p>\n<p>The other option, if you&#8217;re only interested in getting the bitstream on the board and you don&#8217;t care about co-simulation, is to skip simulation altogether. You can do it by removing <code>--simulate<\/code> and <code>--simulator=VERILATOR<\/code> from the command line and go on to the generation of the bitstream.<\/p>\n<h4>5.3) Generation of the bitstream with <em>bambu<\/em><\/h4>\n<p>Now it is time to set the target device and the design constraints, to generate the bitstream and flash it to the board. Again, you will need to have the vendor tools installed and configured properly to work with <em>bambu<\/em>.\u00a0 Check the <a href=\"http:\/\/panda.dei.polimi.it\/?page_id=88\">panda installation instructions<\/a> to see how to do it.<\/p>\n<p>The complete command line for <em>bambu<\/em> with the options for the Nexys4 board is the following:<\/p>\n<pre>$ bambu ..\/led_example.c ..\/IPs.xml --top-fname=led_example --file-input-data=..\/leds_ctrl.v,..\/sw_ctrl.v,..\/btn_ctrl.v,..\/sevensegments_ctrl.v --C-no-parse=..\/leds_ctrl.c,..\/sw_ctrl.c,..\/btn_ctrl.c,..\/sevensegments_ctrl.c --clock-period=10 --device-name=xc7a100t-1csg324-VVD --evaluation=PERIOD,AREA,FREQUENCY,CLOCK_SLACK,REGISTERS,DSPS,BRAMS ..\/constraints_STD.xml --backend-sdc-extensions=..\/Nexys4_Master.sdc<\/pre>\n<p>Different options have been added:<\/p>\n<ul>\n<li><code>--clock-period=10<\/code> sets the desired clock period to 10 nanoseconds (100 MHz).<\/li>\n<li><code>--device-name=xc7a100t-1csg324-VVD<\/code> is the Xilinx part number of the target FPGA considered in the example. <em>bambu<\/em> supports different FPGAs. To see how to add support for new FPGAs, see the discussion on this google group.<\/li>\n<li><code>--evaluation=PERIOD,AREA,FREQUENCY,CLOCK_SLACK,REGISTERS,DSPS,BRAMS<\/code> lists the metrics that have to be evaluated by <em>bambu<\/em> during the analysis of the results. Since the listed metrics require synthesis of the generated accelerator, <em>bambu<\/em> will invoke the vendor tools up to the place and route step to evaluate them. This is also necessary for the generation of the bitstream (that will be performed in a separate step).<\/li>\n<li><code>..\/constraints_STD.xml<\/code>: this XML file specifies to <em>bambu<\/em> that only one copy of the user-provided Verilog modules must be instantiated in the final design. In general, <em>bambu<\/em> is able to take the decision to duplicate some HW modules to exploit available parallelism, but I\/O peripherals cannot be duplicated. In this example, every user-defined module drives some signals to control I\/O peripherals, so all of them cannot be duplicated.<\/li>\n<li><code>--backend-sdc-extensions=..\/Nexys4_Master.sdc<\/code>: this is a standard Xilinx Design Constraint file, that describes the pin mapping of the Verilog signals. It is necessary to connect the Verilog signals in the driver modules to the correct I\/O pins to drive LEDs, switches, pushbuttons and 7-segments displays. The syntax of this file must adhere to the Xilinx SDC syntax, which is an extension of the Synopsys Design Constraints. A detailed description can be found <a href=\"http:\/\/www.xilinx.com\/support\/documentation\/sw_manuals\/xilinx2015_4\/ug903-vivado-using-constraints.pdf\">here<\/a>.<\/li>\n<\/ul>\n<p>After this final step, the bitstream can be generated and can be flashed to the device. This is accomplished by exploiting the .tcl script provided with the example: program_nexys4.tcl. First, it has to be copied in the present working directory.<\/p>\n<pre>$ cp ..\/program_nexys4.tcl .\/<\/pre>\n<p>Then it has to be opened and modified changing the directory string at line 2 from <code>synth\/HLS_output\/Synthesis\/vivado_flow\/post_route.dcp<\/code> to <code>HLS_output\/Synthesis\/vivado_flow\/post_route.dcp<\/code>. The<code>program_nexys4.tcl<\/code> is not intended to be used from this tutorial and it has to be fixed with the correct path. After fixing the path, the board has to be connected to the PC with the USB cable and it has to be turned on. Finally, Vivado can be invoked to generate the bitstream and to flash it to the device.<\/p>\n<pre>$ vivado -mode batch -nojournal -nolog -source program_nexys4.tcl<\/pre>\n<p>The Vivado binary must be in the <code>PATH<\/code>, otherwise the full path of the executable has to be specified. This command will program the board with the result of the High-Level Synthesis flow. The central push button can now be pressed, and the manual switches can now be used to control the LEDs and the 7-segments displays.<\/p>\n<p>If you have any problems please report them <a href=\"https:\/\/groups.google.com\/forum\/#!forum\/panda-project-discussions-questions\" target=\"_blank\" rel=\"noopener noreferrer\">on this google group<\/a>.<\/p>\n<h2>6) Additional Information<\/h2>\n<p>This tutorial shows a typical use case of <em>bambu<\/em> covering some of the command-line options, but there are several other options, to select different algorithms and policies for High-Level Synthesis, for tweaking the output to meet the designed needs and other advanced things. All the possible command-line options available in <em>bambu<\/em> can be listed with the command<\/p>\n<pre>$ bambu -h<\/pre>\n<p>or<\/p>\n<pre>$ bambu --help<\/pre>\n<p>For other questions about how the options can be used please feel free to ask for help <a href=\"https:\/\/groups.google.com\/forum\/#!forum\/panda-project-discussions-questions\" target=\"_blank\" rel=\"noopener noreferrer\">on this google group<\/a> or send an email to panda-info@polimi.it.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1) Introduction This tutorial is intended to guide new users with no previous experience using bambu. It will guide through all the necessary steps, starting from a C source application, explaining the different ways to use bambu, and showing how to generate and synthesize a working Verilog design. 2) Preliminaries For this tutorial it will &hellip; <a href=\"https:\/\/panda.deib.polimi.it\/?page_id=555\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\"><em>bambu<\/em> Tutorial<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":101012,"featured_media":0,"parent":649,"menu_order":4,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-555","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>bambu Tutorial - panda.deib.polimi.it<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/panda.deib.polimi.it\/?page_id=555\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"bambu Tutorial - panda.deib.polimi.it\" \/>\n<meta property=\"og:description\" content=\"1) Introduction This tutorial is intended to guide new users with no previous experience using bambu. It will guide through all the necessary steps, starting from a C source application, explaining the different ways to use bambu, and showing how to generate and synthesize a working Verilog design. 2) Preliminaries For this tutorial it will &hellip; Continue reading bambu Tutorial &rarr;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/panda.deib.polimi.it\/?page_id=555\" \/>\n<meta property=\"og:site_name\" content=\"panda.deib.polimi.it\" \/>\n<meta property=\"article:modified_time\" content=\"2020-10-07T12:27:47+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/panda.dei.polimi.it\/wp-content\/uploads\/Nexys4-300x275.jpg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:site\" content=\"@PandA4Design\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"28 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/panda.deib.polimi.it\\\/?page_id=555\",\"url\":\"https:\\\/\\\/panda.deib.polimi.it\\\/?page_id=555\",\"name\":\"bambu Tutorial - panda.deib.polimi.it\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/panda.deib.polimi.it\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/panda.deib.polimi.it\\\/?page_id=555#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/panda.deib.polimi.it\\\/?page_id=555#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/panda.dei.polimi.it\\\/wp-content\\\/uploads\\\/Nexys4-300x275.jpg\",\"datePublished\":\"2016-03-23T15:14:42+00:00\",\"dateModified\":\"2020-10-07T12:27:47+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/panda.deib.polimi.it\\\/?page_id=555#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/panda.deib.polimi.it\\\/?page_id=555\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/panda.deib.polimi.it\\\/?page_id=555#primaryimage\",\"url\":\"http:\\\/\\\/panda.dei.polimi.it\\\/wp-content\\\/uploads\\\/Nexys4-300x275.jpg\",\"contentUrl\":\"http:\\\/\\\/panda.dei.polimi.it\\\/wp-content\\\/uploads\\\/Nexys4-300x275.jpg\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/panda.deib.polimi.it\\\/?page_id=555#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/panda.deib.polimi.it\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"TUTORIALS\",\"item\":\"https:\\\/\\\/panda.deib.polimi.it\\\/?page_id=649\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"bambu Tutorial\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/panda.deib.polimi.it\\\/#website\",\"url\":\"https:\\\/\\\/panda.deib.polimi.it\\\/\",\"name\":\"panda.deib.polimi.it\",\"description\":\"A framework for Hardware-Software Co-Design of Embedded Systems\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/panda.deib.polimi.it\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"bambu Tutorial - panda.deib.polimi.it","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/panda.deib.polimi.it\/?page_id=555","og_locale":"en_US","og_type":"article","og_title":"bambu Tutorial - panda.deib.polimi.it","og_description":"1) Introduction This tutorial is intended to guide new users with no previous experience using bambu. It will guide through all the necessary steps, starting from a C source application, explaining the different ways to use bambu, and showing how to generate and synthesize a working Verilog design. 2) Preliminaries For this tutorial it will &hellip; Continue reading bambu Tutorial &rarr;","og_url":"https:\/\/panda.deib.polimi.it\/?page_id=555","og_site_name":"panda.deib.polimi.it","article_modified_time":"2020-10-07T12:27:47+00:00","og_image":[{"url":"http:\/\/panda.dei.polimi.it\/wp-content\/uploads\/Nexys4-300x275.jpg","type":"","width":"","height":""}],"twitter_card":"summary_large_image","twitter_site":"@PandA4Design","twitter_misc":{"Est. reading time":"28 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/panda.deib.polimi.it\/?page_id=555","url":"https:\/\/panda.deib.polimi.it\/?page_id=555","name":"bambu Tutorial - panda.deib.polimi.it","isPartOf":{"@id":"https:\/\/panda.deib.polimi.it\/#website"},"primaryImageOfPage":{"@id":"https:\/\/panda.deib.polimi.it\/?page_id=555#primaryimage"},"image":{"@id":"https:\/\/panda.deib.polimi.it\/?page_id=555#primaryimage"},"thumbnailUrl":"http:\/\/panda.dei.polimi.it\/wp-content\/uploads\/Nexys4-300x275.jpg","datePublished":"2016-03-23T15:14:42+00:00","dateModified":"2020-10-07T12:27:47+00:00","breadcrumb":{"@id":"https:\/\/panda.deib.polimi.it\/?page_id=555#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/panda.deib.polimi.it\/?page_id=555"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/panda.deib.polimi.it\/?page_id=555#primaryimage","url":"http:\/\/panda.dei.polimi.it\/wp-content\/uploads\/Nexys4-300x275.jpg","contentUrl":"http:\/\/panda.dei.polimi.it\/wp-content\/uploads\/Nexys4-300x275.jpg"},{"@type":"BreadcrumbList","@id":"https:\/\/panda.deib.polimi.it\/?page_id=555#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/panda.deib.polimi.it\/"},{"@type":"ListItem","position":2,"name":"TUTORIALS","item":"https:\/\/panda.deib.polimi.it\/?page_id=649"},{"@type":"ListItem","position":3,"name":"bambu Tutorial"}]},{"@type":"WebSite","@id":"https:\/\/panda.deib.polimi.it\/#website","url":"https:\/\/panda.deib.polimi.it\/","name":"panda.deib.polimi.it","description":"A framework for Hardware-Software Co-Design of Embedded Systems","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/panda.deib.polimi.it\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"}]}},"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/panda.deib.polimi.it\/index.php?rest_route=\/wp\/v2\/pages\/555","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/panda.deib.polimi.it\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/panda.deib.polimi.it\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/panda.deib.polimi.it\/index.php?rest_route=\/wp\/v2\/users\/101012"}],"replies":[{"embeddable":true,"href":"https:\/\/panda.deib.polimi.it\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=555"}],"version-history":[{"count":43,"href":"https:\/\/panda.deib.polimi.it\/index.php?rest_route=\/wp\/v2\/pages\/555\/revisions"}],"predecessor-version":[{"id":945,"href":"https:\/\/panda.deib.polimi.it\/index.php?rest_route=\/wp\/v2\/pages\/555\/revisions\/945"}],"up":[{"embeddable":true,"href":"https:\/\/panda.deib.polimi.it\/index.php?rest_route=\/wp\/v2\/pages\/649"}],"wp:attachment":[{"href":"https:\/\/panda.deib.polimi.it\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=555"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}