From 81cbc8f8d87205f8327e37a23b22d69039b4325d Mon Sep 17 00:00:00 2001 From: A-Alosius Date: Mon, 21 Jul 2025 21:45:16 +0200 Subject: [PATCH] Updated integration test tutorial --- .../{Examples.md => IntegrationTest.md} | 66 +++++++++++-------- 1 file changed, 37 insertions(+), 29 deletions(-) rename docs/GettingStarted/Tutorials/Introduction/{Examples.md => IntegrationTest.md} (53%) diff --git a/docs/GettingStarted/Tutorials/Introduction/Examples.md b/docs/GettingStarted/Tutorials/Introduction/IntegrationTest.md similarity index 53% rename from docs/GettingStarted/Tutorials/Introduction/Examples.md rename to docs/GettingStarted/Tutorials/Introduction/IntegrationTest.md index 95d83fe767..500e4adc01 100644 --- a/docs/GettingStarted/Tutorials/Introduction/Examples.md +++ b/docs/GettingStarted/Tutorials/Introduction/IntegrationTest.md @@ -1,12 +1,9 @@ # Running an Integration Test -## 1. Binary Search -This example describes how to use Dynamatic and become more familiarized with its HLS flow. You will see how: -- compile your C code to RTL -- simulate the resulting circuit using ModelSim -- synthesize your circuit using vivado -- visualize your circuit +## Binary Search +This tutorial is a walkthrough Dynamatic's HLS workflow from C code input to simulation and visualization of the generated RTL implementation. ### Source Code +To present a usecase where Dynamatic outshines conventional HLS tool, we will be considering a simple binary search algorithm. ```c //===- binary_search.c - Search for integer in array -------------*- C -*-===// // @@ -53,7 +50,9 @@ int main(void) { return 0; } ``` -This HLS code includes control flow inside loops, limiting pipelining in statically scheduled HLS due to worst-case assumptions—here, the branch is taken and the loop exits early. Dynamically scheduled HLS, like Dynamatic, adapts to runtime behavior. Let's see how the generated circuit handles control flow more flexibly. +This HLS code includes control flow inside loops, limiting pipelining in statically scheduled HLS due to worst-case assumptions—here, the branch is taken and the loop exits early. Dynamically scheduled HLS, like Dynamatic, adapts to runtime behavior. Let's see how the generated circuit handles control flow more flexibly. + +Below is are the steps for converting the `binary_search.c` file into RTL code. #### Launching Dynamatic If you haven't added Dynamatic to path, navigate to the directory where you cloned Dynamatic and run the command below: @@ -72,14 +71,25 @@ username:~/Dynamatic/dynamatic$ ./bin/dynamatic dynamatic> ``` #### Set the Path to the C Target C File -Use the `set-src` command to direct Dynamatic to the file you want to synthesize into RTL +Dynamatic needs to know where your target C file is located. To provide this information, use the `set-src` command to direct Dynamatic to the file you want to synthesize into RTL ```sh dynamatic> set-src integration-test/binary_search/binary_search.c ``` +> [!NOTE] +> The target function should have the same name as the `.c` file containing it except for the extension. + #### Compile the C File to a Lower Intermediate Representation -You can choose the **buffer placement algorithm** with the `--buffer-algorithm` flag. For this example, we use `fpga20`, a throughput driven algorithm which requires Gurobi installed as describe in the [Advanced Build](../../../UserGuide/AdvancedBuild.md#1-gurobi) page. +You can compile this code using the `compile` command. +> [!NOTE] +> Dynamatic creates an `out` directory in the same directory as your C kernel where all output files will be stored as you run commands + +The `out/comp` directory created will allow you to have a look at the control flow graph for your program as well as a visual representation of the elastic circuit generated (basic blocks, adders, multipliers, coparisons, etc.). + +If you have a MILP solver (Gurobi), you can choose the **buffer placement algorithm** (either `fpga20` or `fpl22`) with the `--buffer-algorithm` flag. If you do not have Gurobi, Dynamatic will use the simple buffer placement strategy (`on-merges`). For this example, we use `fpga20`, a throughput driven algorithm which requires Gurobi installed as describe in the [Advanced Build](../../../UserGuide/AdvancedBuild.md#1-gurobi) page. > [!TIP] -> If you are not sure which options are available for the compile command, add anything after it and hit enter to see the options e.g compile -- +> If you are not sure which options are available for any command, use the `help` command to see a list of commands and their respective options. + +Running the `compile` commands prints the following on the screen outlining the steps in the compilation process. ```sh dynamatic> compile --buffer-algorithm fpga20 [INFO] Compiled source to affine @@ -103,22 +113,30 @@ dynamatic> compile --buffer-algorithm fpga20 [INFO] Lowered to HW [INFO] Compilation succeeded ``` -> [!TIP] -> Two PNG files are generated at compile time, `kernel_name.png` and `kernel_name_CFG.png`, allowing you to have a preview of your circuit and its control flow graph generated by Dynamatic as shown below. +> [!TIP] +> Two PNG files are generated at compile time, `kernel_name.png` and `kernel_name_CFG.png`, allowing you to have a preview of your circuit and its control flow graph generated by Dynamatic as shown below. You should see a `binary_tree_CFG.png` and `binary_tree.png` file in your `comp` directory for this example. **Binary Search CFG** ![Binary search CFG](./Figures/binary_search_CFG.png) **Binary Search Dataflow Circuit** ![Binary search circuit](./Figures/binary_search.png) -#### Generate HDL from `mlir` File +Your images may look different if you used a different buffer placement algorithm. + +#### Generate RTL +You can generate RTL in VHDL or Verilog by running the `write-hdl` command. An `mlir` file is generated during the compile process. -`write-hdl` converts it into HDL code for your kernel. The default HDL is VHDL. You can choose verilog or vhdl with the `--hdl` flag +`write-hdl` converts it into RTL code implementing your kernel. The default HDL is VHDL. +> [!TIP] +> You can choose verilog with the `--hdl` flag and value `verilog` ```sh -dynamatic> write-hdl --hdl vhdl +dynamatic> write-hdl [INFO] Exported RTL (vhdl) [INFO] HDL generation succeeded ``` +You should now see an `out/hdl` folder with all the VHDL files generated by the command. For instance, `hdl/binary_search.vhd` is the top level RTL file where all units are registered. + #### Simulate Your Circuit -This step simulates the kernel in C and HDL (using modelsim) and compares the results for equality. +Now that we have the HDL implementation of our circuit, we can verify whether it yields the same results as our C kernel using the `simulate` command. +This step runs a cosimulation of our kernel in C with clang and the VHDL (using ModelSim/Questa) and compares the results and memory states for equality. It creates an `out/sim` directory with our simulation results. ```sh dynamatic> simulate [INFO] Built kernel for IO gen. @@ -126,21 +144,11 @@ dynamatic> simulate [INFO] Launching Modelsim simulation [INFO] Simulation succeeded ``` -#### Sythesize With Vivado -This step is optional. It allows to get more timing and performance related files using vivado. You must have vivado installed. -```sh -dynamatic> synthesize -[INFO] Created synthesis scripts -[INFO] Launching Vivado synthesis -[INFO] Logic synthesis succeeded -``` -> [!NOTE] -> If this step fails despite you having vivado installed and added to path, `source` the vivado/vitis `settings64.sh` in your shell and try again. +A successful simulation indicates that our generated RTL functions as expected. You can check the `sim/results.txt` file to verify the clock cycle count exhibited by the circuit. Also, you can use the waveform viewer in ModelSim by opening the `sim/HLS_VERIFY/vsim.wlf` file. -> [!WARNING] -> Adding the sourcing of the `settings64.sh` to path may hinder future compilations as the vivado compiler varies from the regular clang compiler on your machine #### Visualize and Simulate Your Circuit -By running the `visualize` command, the Godot GUI will be launched with your dataflow circuit open, and ready to be played with +You can visualize the circuit using our interactive data flow visualizer that allows you to see the states of different edges across the different clock cycles and animate the circuit execution. +By running the `visualize` command, the Godot GUI will be launched with your dataflow circuit open, and ready to be played with. This allows you to observe the circuit intuitively as you observe throughput, stalls, and signal states. ```sh dynamatic> visualize [INFO] Generated channel changes