From 7ec408fd31fe6150bd0fe9a5154b98b07fd8f3af Mon Sep 17 00:00:00 2001 From: Lucas Ramirez Date: Mon, 20 Nov 2023 17:12:45 -0500 Subject: [PATCH] [dynamatic] Stability and scripts improvements This commit improves the Dynamatic frontend in numerous ways before the v.0.2.0 internal release. Major changes are listed below. - Fix issues when using relative paths and when running the frontend from a non-standard location. The frontend does its convert everything to absolute paths to minimize the risk of path errors. - Rename the `synthesize` step/script to `compile` and the `logic-synthesize` step/script to `synthesize` to be more accurate. - All outputs from the compile step now go to the `comp` subdirectory within the output directory, for easier bookkeeping. - Factor in some of the common Bash functions used by most frontend scripts in a single `utils.sh` file that is sourced by all other scripts at the beginning (required that all scripts receive Dynamatic's path as their first argument). - Before running commands that might create temporary files (e.g., `vivado`), cd to the output directory to make move/remove steps unnecessary and avoid leaving temporary files at the frontend running location. - Make success/failure state reporting more consistent across commands. - Added sample script to run our entire flow on all our current integration tests. --- build.sh | 4 +- tools/dynamatic/dynamatic.cpp | 96 ++++---- tools/dynamatic/samples/fir.sh | 8 +- tools/dynamatic/samples/fpl22.sh | 61 ----- tools/dynamatic/samples/run-all-tests.sh | 209 +++++++++++++++++ tools/dynamatic/samples/test_all.sh | 60 ----- tools/dynamatic/scripts/compile.sh | 168 ++++++++++++++ tools/dynamatic/scripts/logic-synthesize.sh | 96 -------- tools/dynamatic/scripts/simulate.sh | 34 +-- tools/dynamatic/scripts/synthesize.sh | 240 +++++--------------- tools/dynamatic/scripts/utils.sh | 34 +++ tools/dynamatic/scripts/write-hdl.sh | 43 +--- 12 files changed, 536 insertions(+), 517 deletions(-) delete mode 100644 tools/dynamatic/samples/fpl22.sh create mode 100644 tools/dynamatic/samples/run-all-tests.sh delete mode 100644 tools/dynamatic/samples/test_all.sh create mode 100755 tools/dynamatic/scripts/compile.sh delete mode 100755 tools/dynamatic/scripts/logic-synthesize.sh create mode 100644 tools/dynamatic/scripts/utils.sh diff --git a/build.sh b/build.sh index c2740a51a..0f3c525ed 100755 --- a/build.sh +++ b/build.sh @@ -314,10 +314,10 @@ create_symlink build/bin/exp-frequency-profiler create_symlink build/bin/handshake-simulator # Make the scripts used by the frontend executable -chmod +x tools/dynamatic/scripts/synthesize.sh +chmod +x tools/dynamatic/scripts/compile.sh chmod +x tools/dynamatic/scripts/write-hdl.sh chmod +x tools/dynamatic/scripts/simulate.sh -chmod +x tools/dynamatic/scripts/logic-synthesize.sh +chmod +x tools/dynamatic/scripts/synthesize.sh echo "" echo_subsection "Build successful!" diff --git a/tools/dynamatic/dynamatic.cpp b/tools/dynamatic/dynamatic.cpp index e294707b5..212b79848 100644 --- a/tools/dynamatic/dynamatic.cpp +++ b/tools/dynamatic/dynamatic.cpp @@ -69,7 +69,7 @@ const static std::string HEADER = DELIM + "============== Dynamatic | Dynamic High-Level Synthesis Compiler " "===============\n" + - "======================= EPFL-LAP - v0.1.0 | October 2023 " + "======================= EPFL-LAP - v0.2.0 | November 2023 " "=======================\n" + DELIM + "\n\n"; const static std::string PROMPT = "dynamatic> "; @@ -78,10 +78,10 @@ const static std::string PROMPT = "dynamatic> "; const static std::string CMD_SET_SRC = "set-src"; const static std::string CMD_SET_DYNAMATIC_PATH = "set-dynamatic-path"; const static std::string CMD_SET_LEGACY_PATH = "set-legacy-path"; -const static std::string CMD_SYNTHESIZE = "synthesize"; +const static std::string CMD_COMPILE = "compile"; const static std::string CMD_WRITE_HDL = "write-hdl"; const static std::string CMD_SIMULATE = "simulate"; -const static std::string CMD_LOGIC_SYNTHESIZE = "logic-synthesize"; +const static std::string CMD_SYNTHESIZE = "synthesize"; const static std::string CMD_HELP = "help"; const static std::string CMD_EXIT = "exit"; @@ -99,6 +99,10 @@ struct FrontendState { bool legacyPathIsSet(StringRef keyword); + std::string getScriptsPath() const { + return dynamaticPath + "/tools/dynamatic/scripts"; + } + std::string makeAbsolutePath(StringRef path); }; @@ -189,17 +193,17 @@ class SetLegacyPath : public Command { class SetSrc : public Command { public: SetSrc(FrontendState &state) - : Command(CMD_SET_SRC, "Sets the C source to synthesize", state, + : Command(CMD_SET_SRC, "Sets the C source to compile", state, {{"source", "path to source file"}}){}; CommandResult decode(SmallVector &tokens) override; }; -class Synthesize : public Command { +class Compile : public Command { public: - Synthesize(FrontendState &state) - : Command(CMD_SYNTHESIZE, - "Synthesizes the source kernel into a dataflow circuit; " + Compile(FrontendState &state) + : Command(CMD_COMPILE, + "Compiles the source kernel into a dataflow circuit; " "produces both handshake-level IR and an equivalent DOT file", state, {}, {{"simple-buffers", "Use simple buffer placement"}}){}; @@ -212,7 +216,7 @@ class WriteHDL : public Command { WriteHDL(FrontendState &state) : Command( CMD_WRITE_HDL, - "Converts the DOT file produced after synthesis to VHDL using the " + "Converts the DOT file produced after compile to VHDL using the " "legacy dot2vhdl tool", state){}; @@ -230,10 +234,10 @@ class Simulate : public Command { CommandResult decode(SmallVector &tokens) override; }; -class LogicSynthesize : public Command { +class Synthesize : public Command { public: - LogicSynthesize(FrontendState &state) - : Command(CMD_LOGIC_SYNTHESIZE, + Synthesize(FrontendState &state) + : Command(CMD_SYNTHESIZE, "Synthesizes the VHDL produced during HDL writing using Vivado", state){}; @@ -266,6 +270,12 @@ class FrontendCommands { }; } // namespace +static CommandResult execShellCommand(StringRef cmd) { + int ret = std::system(cmd.str().c_str()); + llvm::outs() << "\n"; + return ret != 0 ? CommandResult::FAIL : CommandResult::SUCCESS; +} + std::string FrontendState::makeAbsolutePath(StringRef path) { SmallString<128> str; path::append(str, path); @@ -455,7 +465,7 @@ CommandResult SetSrc::decode(SmallVector &tokens) { return CommandResult::SUCCESS; } -CommandResult Synthesize::decode(SmallVector &tokens) { +CommandResult Compile::decode(SmallVector &tokens) { ParsedCommand parsed; if (failed(parse(tokens, parsed))) return CommandResult::SYNTAX_ERROR; @@ -472,14 +482,9 @@ CommandResult Synthesize::decode(SmallVector &tokens) { parsed.optArgsPresent.contains("simple-buffers") ? "1" : "0"; // Create and execute the command - std::stringstream exec; - exec << "./tools/dynamatic/scripts/synthesize.sh " << state.dynamaticPath - << " " << kernelDir << " " << outputDir << " " << kernelName << " " - << buffers; - if (int ret = std::system(exec.str().c_str()); ret != 0) - return CommandResult::FAIL; - - return CommandResult::SUCCESS; + return execShellCommand(state.getScriptsPath() + "/compile.sh " + + state.dynamaticPath + " " + kernelDir + " " + + outputDir + " " + kernelName + " " + buffers); } CommandResult WriteHDL::decode(SmallVector &tokens) { @@ -495,8 +500,8 @@ CommandResult WriteHDL::decode(SmallVector &tokens) { std::string kernelDir = path::parent_path(*state.sourcePath).str(); std::string kernelName = path::filename(*state.sourcePath).drop_back(2).str(); std::string outputDir = kernelDir + sep.str() + "out"; - std::string dotPath = - kernelDir + sep.str() + "out" + sep.str() + kernelName + ".dot"; + std::string dotPath = kernelDir + sep.str() + "out" + sep.str() + "comp" + + sep.str() + kernelName + ".dot"; // The DOT file must exist to produce the corresponding VHDL if (!fs::exists(dotPath)) { @@ -505,13 +510,9 @@ CommandResult WriteHDL::decode(SmallVector &tokens) { } // Create and execute the command - std::stringstream exec; - exec << "./tools/dynamatic/scripts/write-hdl.sh " << *state.legacyPath << " " - << outputDir << " " << kernelName; - if (int ret = std::system(exec.str().c_str()); ret != 0) - return CommandResult::FAIL; - - return CommandResult::SUCCESS; + return execShellCommand(state.getScriptsPath() + "/write-hdl.sh " + + state.dynamaticPath + " " + *state.legacyPath + " " + + outputDir + " " + kernelName); } CommandResult Simulate::decode(SmallVector &tokens) { @@ -527,8 +528,8 @@ CommandResult Simulate::decode(SmallVector &tokens) { std::string kernelDir = path::parent_path(*state.sourcePath).str(); std::string kernelName = path::filename(*state.sourcePath).drop_back(2).str(); std::string outputDir = kernelDir + sep.str() + "out"; - std::string vhdlPath = - kernelDir + sep.str() + "out" + sep.str() + kernelName + ".vhd"; + std::string vhdlPath = kernelDir + sep.str() + "out" + sep.str() + "comp" + + sep.str() + kernelName + ".vhd"; // The DOT file must exist to produce the corresponding VHDL if (!fs::exists(vhdlPath)) { @@ -537,17 +538,12 @@ CommandResult Simulate::decode(SmallVector &tokens) { } // Create and execute the command - std::stringstream exec; - exec << "./tools/dynamatic/scripts/simulate.sh " << state.dynamaticPath << " " - << *state.legacyPath << " " << kernelDir << " " << outputDir << " " - << kernelName; - if (int ret = std::system(exec.str().c_str()); ret != 0) - return CommandResult::FAIL; - - return CommandResult::SUCCESS; + return execShellCommand(state.getScriptsPath() + "/simulate.sh " + + state.dynamaticPath + " " + *state.legacyPath + " " + + kernelDir + " " + outputDir + " " + kernelName); } -CommandResult LogicSynthesize::decode(SmallVector &tokens) { +CommandResult Synthesize::decode(SmallVector &tokens) { ParsedCommand parsed; if (failed(parse(tokens, parsed))) return CommandResult::SYNTAX_ERROR; @@ -560,8 +556,8 @@ CommandResult LogicSynthesize::decode(SmallVector &tokens) { std::string kernelDir = path::parent_path(*state.sourcePath).str(); std::string kernelName = path::filename(*state.sourcePath).drop_back(2).str(); std::string outputDir = kernelDir + sep.str() + "out"; - std::string vhdlPath = - kernelDir + sep.str() + "out" + sep.str() + kernelName + ".vhd"; + std::string vhdlPath = kernelDir + sep.str() + "out" + sep.str() + "comp" + + sep.str() + kernelName + ".vhd"; // The DOT file must exist to produce the corresponding VHDL if (!fs::exists(vhdlPath)) { @@ -570,13 +566,9 @@ CommandResult LogicSynthesize::decode(SmallVector &tokens) { } // Create and execute the command - std::stringstream exec; - exec << "./tools/dynamatic/scripts/logic-synthesize.sh " << *state.legacyPath - << " " << outputDir << " " << kernelName; - if (int ret = std::system(exec.str().c_str()); ret != 0) - return CommandResult::FAIL; - - return CommandResult::SUCCESS; + return execShellCommand(state.getScriptsPath() + "/synthesize.sh " + + state.dynamaticPath + " " + *state.legacyPath + " " + + outputDir + " " + kernelName); } static void tokenizeInput(StringRef input, SmallVector &tokens) { @@ -630,10 +622,10 @@ int main(int argc, char **argv) { commands.add(state); commands.add(state); commands.add(state); - commands.add(state); + commands.add(state); commands.add(state); commands.add(state); - commands.add(state); + commands.add(state); commands.add(state); commands.add(state); diff --git a/tools/dynamatic/samples/fir.sh b/tools/dynamatic/samples/fir.sh index f8a25a4e8..aa21a4d7b 100644 --- a/tools/dynamatic/samples/fir.sh +++ b/tools/dynamatic/samples/fir.sh @@ -12,9 +12,9 @@ set-legacy-path ../dynamatic-utils/legacy-dynamatic/dhls/etc/dynamatic # without the extension) set-src integration-test/fir/fir.c -# Synthesize (from source to Handshake/DOT) +# Compile (from source to Handshake IR/DOT) # Remove the flag to run smart buffer placement (requires Gurobi) -synthesize --simple-buffers +compile --simple-buffers # Generate the VHDL for the dataflow circuit write-hdl @@ -23,7 +23,7 @@ write-hdl simulate # Synthesize using Vivado -logic-synthesize +synthesize # Exit the frontend -exit \ No newline at end of file +exit diff --git a/tools/dynamatic/samples/fpl22.sh b/tools/dynamatic/samples/fpl22.sh deleted file mode 100644 index 605a14a18..000000000 --- a/tools/dynamatic/samples/fpl22.sh +++ /dev/null @@ -1,61 +0,0 @@ -# Run all integration tests available on the repository - -# Indicate the path to your legacy Dynamatic install here (required for write-hdl) -set-legacy-path ../dynamatic-utils/legacy-dynamatic/dhls/etc/dynamatic - -# bicg -set-src integration-test/bicg/bicg.c -synthesize --simple-buffers -write-hdl -simulate - -# binary_search -set-src integration-test/binary_search/binary_search.c -synthesize --simple-buffers -write-hdl -simulate - -# fir -set-src integration-test/fir/fir.c -synthesize --simple-buffers -write-hdl -simulate - -# gaussian -set-src integration-test/gaussian/gaussian.c -synthesize --simple-buffers -write-hdl -simulate - -# gcd -set-src integration-test/gcd/gcd.c -synthesize --simple-buffers -write-hdl -simulate - -# matvec -set-src integration-test/matvec/matvec.c -synthesize --simple-buffers -write-hdl -simulate - -# polyn_mult -set-src integration-test/polyn_mult/polyn_mult.c -synthesize --simple-buffers -write-hdl -simulate - -# sobel -set-src integration-test/sobel/sobel.c -synthesize --simple-buffers -write-hdl -simulate - -# stencil_2d -set-src integration-test/stencil_2d/stencil_2d.c -synthesize --simple-buffers -write-hdl -simulate - -# Exit the frontend -exit \ No newline at end of file diff --git a/tools/dynamatic/samples/run-all-tests.sh b/tools/dynamatic/samples/run-all-tests.sh new file mode 100644 index 000000000..cb262746e --- /dev/null +++ b/tools/dynamatic/samples/run-all-tests.sh @@ -0,0 +1,209 @@ +# Fully run (from C to synthesis) all integration tests available on the +# repository + +# Indicate the path to your legacy Dynamatic install here +set-legacy-path ../dynamatic-utils/legacy-dynamatic/dhls/etc/dynamatic + +set-src integration-test/bicg/bicg.c +compile +write-hdl +simulate +synthesize +set-src integration-test/binary_search/binary_search.c +compile +write-hdl +simulate +synthesize +set-src integration-test/fir/fir.c +compile +write-hdl +simulate +synthesize +set-src integration-test/gaussian/gaussian.c +compile +write-hdl +simulate +synthesize +set-src integration-test/gcd/gcd.c +compile +write-hdl +simulate +synthesize +set-src integration-test/gemver/gemver.c +compile +write-hdl +simulate +synthesize +set-src integration-test/if_loop_1/if_loop_1.c +compile +write-hdl +simulate +synthesize +set-src integration-test/if_loop_2/if_loop_2.c +compile +write-hdl +simulate +synthesize +set-src integration-test/if_loop_3/if_loop_3.c +compile +write-hdl +simulate +synthesize +set-src integration-test/iir/iir.c +compile +write-hdl +simulate +synthesize +set-src integration-test/image_resize/image_resize.c +compile +write-hdl +simulate +synthesize +set-src integration-test/insertion_sort/insertion_sort.c +compile +write-hdl +simulate +synthesize +set-src integration-test/kernel_2mm/kernel_2mm.c +compile +write-hdl +simulate +synthesize +set-src integration-test/kernel_3mm/kernel_3mm.c +compile +write-hdl +simulate +synthesize +set-src integration-test/loop_array/loop_array.c +compile +write-hdl +simulate +synthesize +set-src integration-test/matrix/matrix.c +compile +write-hdl +simulate +synthesize +set-src integration-test/matrix_power/matrix_power.c +compile +write-hdl +simulate +synthesize +set-src integration-test/matvec/matvec.c +compile +write-hdl +simulate +synthesize +set-src integration-test/memory_loop/memory_loop.c +compile +write-hdl +simulate +synthesize +set-src integration-test/mul_example/mul_example.c +compile +write-hdl +simulate +synthesize +set-src integration-test/pivot/pivot.c +compile +write-hdl +simulate +synthesize +set-src integration-test/polyn_mult/polyn_mult.c +compile +write-hdl +simulate +synthesize +set-src integration-test/simple_example/simple_example.c +compile +write-hdl +simulate +synthesize +set-src integration-test/sobel/sobel.c +compile +write-hdl +simulate +synthesize +set-src integration-test/stencil_2d/stencil_2d.c +compile +write-hdl +simulate +synthesize +set-src integration-test/sumi3_mem/sumi3_mem.c +compile +write-hdl +simulate +synthesize +set-src integration-test/test_memory_1/test_memory_1.c +compile +write-hdl +simulate +synthesize +set-src integration-test/test_memory_2/test_memory_2.c +compile +write-hdl +simulate +synthesize +set-src integration-test/test_memory_3/test_memory_3.c +compile +write-hdl +simulate +synthesize +set-src integration-test/test_memory_4/test_memory_4.c +compile +write-hdl +simulate +synthesize +set-src integration-test/test_memory_5/test_memory_5.c +compile +write-hdl +simulate +synthesize +set-src integration-test/test_memory_6/test_memory_6.c +compile +write-hdl +simulate +synthesize +set-src integration-test/test_memory_7/test_memory_7.c +compile +write-hdl +simulate +synthesize +set-src integration-test/test_memory_8/test_memory_8.c +compile +write-hdl +simulate +synthesize +set-src integration-test/test_memory_9/test_memory_9.c +compile +write-hdl +simulate +synthesize +set-src integration-test/test_memory_10/test_memory_10.c +compile +write-hdl +simulate +synthesize +set-src integration-test/threshold/threshold.c +compile +write-hdl +simulate +synthesize +set-src integration-test/triangular/triangular.c +compile +write-hdl +simulate +synthesize +set-src integration-test/vector_rescale/vector_rescale.c +compile +write-hdl +simulate +synthesize +set-src integration-test/video_filter/video_filter.c +compile +write-hdl +simulate +synthesize + +# Exit the frontend +exit \ No newline at end of file diff --git a/tools/dynamatic/samples/test_all.sh b/tools/dynamatic/samples/test_all.sh deleted file mode 100644 index d376da914..000000000 --- a/tools/dynamatic/samples/test_all.sh +++ /dev/null @@ -1,60 +0,0 @@ -# Indicate the path to your legacy Dynamatic install here (required for write-hdl) -set-legacy-path ../dynamatic-utils/legacy-dynamatic/dhls/etc/dynamatic - -set-src integration-test/bicg/bicg.c -synthesize --simple-buffers -set-src integration-test/if_loop_1/if_loop_1.c -synthesize --simple-buffers -set-src integration-test/if_loop_2/if_loop_2.c -synthesize --simple-buffers -set-src integration-test/if_loop_3/if_loop_3.c -synthesize --simple-buffers -set-src integration-test/iir/iir.c -synthesize --simple-buffers -set-src integration-test/image_resize/image_resize.c -synthesize --simple-buffers -set-src integration-test/insertion_sort/insertion_sort.c -synthesize --simple-buffers -set-src integration-test/kernel_2mm/kernel_2mm.c -synthesize --simple-buffers -set-src integration-test/kernel_3mm/kernel_3mm.c -synthesize --simple-buffers -set-src integration-test/loop_array/loop_array.c -synthesize --simple-buffers -set-src integration-test/matrix_power/matrix_power.c -synthesize --simple-buffers -set-src integration-test/memory_loop/memory_loop.c -synthesize --simple-buffers -set-src integration-test/mul_example/mul_example.c -synthesize --simple-buffers -set-src integration-test/pivot/pivot.c -synthesize --simple-buffers -set-src integration-test/simple_example/simple_example.c -synthesize --simple-buffers -set-src integration-test/sumi3_mem/sumi3_mem.c -synthesize --simple-buffers -set-src integration-test/test_memory_1/test_memory_1.c -synthesize --simple-buffers -set-src integration-test/test_memory_2/test_memory_2.c -synthesize --simple-buffers -set-src integration-test/test_memory_3/test_memory_3.c -synthesize --simple-buffers -set-src integration-test/test_memory_4/test_memory_4.c -synthesize --simple-buffers -set-src integration-test/test_memory_5/test_memory_5.c -synthesize --simple-buffers -set-src integration-test/test_memory_6/test_memory_6.c -synthesize --simple-buffers -set-src integration-test/test_memory_7/test_memory_7.c -synthesize --simple-buffers -set-src integration-test/test_memory_8/test_memory_8.c -synthesize --simple-buffers -set-src integration-test/test_memory_9/test_memory_9.c -synthesize --simple-buffers -set-src integration-test/test_memory_10/test_memory_10.c -synthesize --simple-buffers -set-src integration-test/vector_rescale/vector_rescale.c -synthesize --simple-buffers - -# Exit the frontend -exit \ No newline at end of file diff --git a/tools/dynamatic/scripts/compile.sh b/tools/dynamatic/scripts/compile.sh new file mode 100755 index 000000000..c22eddd89 --- /dev/null +++ b/tools/dynamatic/scripts/compile.sh @@ -0,0 +1,168 @@ +#!/bin/bash + +source "$1"/tools/dynamatic/scripts/utils.sh + +# ============================================================================ # +# Variable definitions +# ============================================================================ # + +# Script arguments +DYNAMATIC_DIR=$1 +SRC_DIR=$2 +OUTPUT_DIR=$3 +KERNEL_NAME=$4 +USE_SIMPLE_BUFFERS=$5 + +# Binaries used during compilation +POLYGEIST_PATH="$DYNAMATIC_DIR/polygeist/llvm-project/clang/lib/Headers/" +POLYGEIST_CLANG_BIN="$DYNAMATIC_DIR/bin/cgeist" +CLANGXX_BIN="$DYNAMATIC_DIR/bin/clang++" +DYNAMATIC_OPT_BIN="$DYNAMATIC_DIR/bin/dynamatic-opt" +DYNAMATIC_PROFILER_BIN="$DYNAMATIC_DIR/bin/exp-frequency-profiler" +DYNAMATIC_EXPORT_DOT_BIN="$DYNAMATIC_DIR/bin/export-dot" + +# Generated directories/files +COMP_DIR="$OUTPUT_DIR/comp" +F_AFFINE="$COMP_DIR/affine.mlir" +F_AFFINE_MEM="$COMP_DIR/affine_mem.mlir" +F_SCF="$COMP_DIR/scf.mlir" +F_CF="$COMP_DIR/std.mlir" +F_CF_TRANFORMED="$COMP_DIR/std_transformed.mlir" +F_CF_DYN_TRANSFORMED="$COMP_DIR/std_dyn_transformed.mlir" +F_PROFILER_BIN="$COMP_DIR/$KERNEL_NAME-profile" +F_PROFILER_INPUTS="$COMP_DIR/profiler-inputs.txt" +F_HANDSHAKE="$COMP_DIR/handshake.mlir" +F_HANDSHAKE_TRANSFORMED="$COMP_DIR/handshake_transformed.mlir" +F_HANDSHAKE_BUFFERED="$COMP_DIR/handshake_buffered.mlir" +F_HANDSHAKE_EXPORT="$COMP_DIR/handshake_export.mlir" +F_FREQUENCIES="$COMP_DIR/frequencies.csv" + +# ============================================================================ # +# Helper funtions +# ============================================================================ # + +# Exports Handshake-level IR to DOT using Dynamatic, then converts the DOT to +# a PNG using dot. +# $1: mode to run the tool in; options are "visual", "legacy", "legacy-buffers" +# $2: output filename, without extension (will use .dot and .png) +export_dot() { + local mode=$1 + local f_dot="$COMP_DIR/$2.dot" + local f_png="$COMP_DIR/$2.png" + + # Export to DOT + "$DYNAMATIC_EXPORT_DOT_BIN" "$F_HANDSHAKE_EXPORT" "--mode=$mode" \ + "--edge-style=spline" \ + "--timing-models=$DYNAMATIC_DIR/data/components.json" \ + > "$f_dot" + exit_on_fail "Failed to create $2 DOT" "Created $2 DOT" + + # Convert DOT graph to PNG + dot -Tpng "$f_dot" > "$f_png" + exit_on_fail "Failed to convert $2 DOT to PNG" "Converted $2 DOT to PNG" + return 0 +} + +# ============================================================================ # +# Compilation flow +# ============================================================================ # + +# Reset output directory +rm -rf "$COMP_DIR" && mkdir -p "$COMP_DIR" + +# source -> affine level +"$POLYGEIST_CLANG_BIN" "$SRC_DIR/$KERNEL_NAME.c" -I \ + "$POLYGEIST_PATH/llvm-project/clang/lib/Headers/" --function="$KERNEL_NAME" \ + -S -O3 --memref-fullrank --raise-scf-to-affine \ + > "$F_AFFINE" 2>/dev/null +exit_on_fail "Failed to compile source to affine" "Compiled source to affine" + +# affine level -> pre-processing and memory analysis +"$DYNAMATIC_OPT_BIN" "$F_AFFINE" --allow-unregistered-dialect \ + --remove-polygeist-attributes --mark-memory-dependencies \ + --mark-memory-interfaces \ + > "$F_AFFINE_MEM" +exit_on_fail "Failed to run memory analysis" "Ran memory analysis" + +# affine level -> scf level +"$DYNAMATIC_OPT_BIN" "$F_AFFINE_MEM" --lower-affine-to-scf \ + --flatten-memref-row-major --scf-simple-if-to-select \ + --scf-rotate-for-loops \ + > "$F_SCF" +exit_on_fail "Failed to compile affine to scf" "Compiled affine to scf" + +# scf level -> cf level +"$DYNAMATIC_OPT_BIN" "$F_SCF" --lower-scf-to-cf > "$F_CF" +exit_on_fail "Failed to compile scf to cf" "Compiled scf to cf" + +# cf transformations (standard) +"$DYNAMATIC_OPT_BIN" "$F_CF" --canonicalize --cse --sccp --symbol-dce \ + --control-flow-sink --loop-invariant-code-motion --canonicalize \ + > "$F_CF_TRANFORMED" +exit_on_fail "Failed to apply standard transformations to cf" \ + "Applied standard transformations to cf" + +# cf transformations (dynamatic) +"$DYNAMATIC_OPT_BIN" "$F_CF_TRANFORMED" --flatten-memref-calls \ + --arith-reduce-strength="max-adder-depth-mul=1" --push-constants \ + > "$F_CF_DYN_TRANSFORMED" +exit_on_fail "Failed to apply Dynamatic transformations to cf" \ + "Applied Dynamatic transformations to cf" + +# cf level -> handshake level +"$DYNAMATIC_OPT_BIN" "$F_CF_DYN_TRANSFORMED" --lower-std-to-handshake-fpga18 \ + --handshake-fix-arg-names="source=$SRC_DIR/$KERNEL_NAME.c" \ + > "$F_HANDSHAKE" +exit_on_fail "Failed to compile cf to handshake" "Compiled cf to handshake" + +# handshake transformations +"$DYNAMATIC_OPT_BIN" "$F_HANDSHAKE" \ + --handshake-concretize-index-type="width=32" \ + --handshake-minimize-cst-width --handshake-optimize-bitwidths="legacy" \ + --handshake-materialize-forks-sinks --handshake-infer-basic-blocks \ + > "$F_HANDSHAKE_TRANSFORMED" +exit_on_fail "Failed to apply transformations to handshake" \ + "Applied transformations to handshake" + +# Buffer placement +if [[ $USE_SIMPLE_BUFFERS -ne 0 ]]; then + # Simple buffer placement + "$DYNAMATIC_OPT_BIN" "$F_HANDSHAKE_TRANSFORMED" \ + --handshake-place-buffers="algorithm=on-merges" \ + > "$F_HANDSHAKE_BUFFERED" + exit_on_fail "Failed to place simple buffers" "Placed simple buffers" +else + # Compile kernel's main function to extract profiling information + "$CLANGXX_BIN" "$SRC_DIR/$KERNEL_NAME.c" -D PRINT_PROFILING_INFO \ + -Wno-deprecated -o "$F_PROFILER_BIN" + exit_on_fail "Failed to build kernel for profiling" "Built kernel for profiling" + + "$F_PROFILER_BIN" > "$F_PROFILER_INPUTS" + exit_on_fail "Failed to kernel for profiling" "Ran kernel for profiling" + + # cf-level profiler + "$DYNAMATIC_PROFILER_BIN" "$F_CF_DYN_TRANSFORMED" \ + --top-level-function="$KERNEL_NAME" --input-args-file="$F_PROFILER_INPUTS" \ + > $F_FREQUENCIES + exit_on_fail "Failed to profile cf-level" "Profiled cf-level" + + # Smart buffer placement + echo_info "Running smart buffer placement" + cd "$COMP_DIR" + "$DYNAMATIC_OPT_BIN" "$F_HANDSHAKE_TRANSFORMED" \ + --handshake-set-buffering-properties="version=fpga20" \ + --handshake-place-buffers="algorithm=fpga20-legacy frequencies=$F_FREQUENCIES timing-models=$DYNAMATIC_DIR/data/components.json timeout=300 dump-logs" \ + > "$F_HANDSHAKE_BUFFERED" + exit_on_fail "Failed to place smart buffers" "Placed smart buffers" + cd - > /dev/null +fi + +# handshake canonicalization +"$DYNAMATIC_OPT_BIN" "$F_HANDSHAKE_BUFFERED" --handshake-canonicalize \ + > "$F_HANDSHAKE_EXPORT" +exit_on_fail "Failed to canonicalize Handshake" "Canonicalized handshake" + +# Export to DOT (one clean for viewing and one compatible with legacy) +export_dot "visual" "visual" +export_dot "legacy" "$KERNEL_NAME" +echo_info "Compilation succeeded" diff --git a/tools/dynamatic/scripts/logic-synthesize.sh b/tools/dynamatic/scripts/logic-synthesize.sh deleted file mode 100755 index 45d21c4d5..000000000 --- a/tools/dynamatic/scripts/logic-synthesize.sh +++ /dev/null @@ -1,96 +0,0 @@ -#!/bin/bash - -# ============================================================================ # -# Variable definitions -# ============================================================================ # - -# Script variables -LEGACY_DIR=$1 -OUTPUT_DIR=$2 -KERNEL_NAME=$3 - -# Generated directories/files -SYNTH_DIR="$OUTPUT_DIR/synth" -HDL_DIR="$SYNTH_DIR/hdl" -F_REPORT="$SYNTH_DIR/report.txt" -F_SCRIPT="$SYNTH_DIR/synthesize.tcl" -F_PERIOD="$SYNTH_DIR/period_4.xdc" -F_UTILIZATION_SYN="$SYNTH_DIR/utilization_post_syn.rpt" -F_TIMING_SYN="$SYNTH_DIR/timing_post_syn.rpt" -F_UTILIZATION_PR="$SYNTH_DIR/utilization_post_pr.rpt" -F_TIMING_PR="$SYNTH_DIR/timing_post_pr.rpt" - - -# ============================================================================ # -# Helper funtions -# ============================================================================ # - -# Prints some information to stdout. -# $1: the text to print -echo_info() { - echo "[INFO] $1" -} - -# Prints a fatal error message to stdout. -# $1: the text to print -echo_fatal() { - echo "[FATAL] $1" -} - -# ============================================================================ # -# Simulation flow -# ============================================================================ # - -# Reset simulation directory -rm -rf "$SYNTH_DIR" && mkdir -p "$SYNTH_DIR" - -# Copy all synthesizable components to specific folder for Vivado -mkdir -p "$HDL_DIR" -cp "$OUTPUT_DIR/$KERNEL_NAME.vhd" "$HDL_DIR" -cp "$LEGACY_DIR"/components/*.vhd "$HDL_DIR" - -# See if we should include any LSQ in the synthesis script -READ_VERILOG="" -if ls "$OUTPUT_DIR"/LSQ*.v 1> /dev/null 2>&1; then - cp "$OUTPUT_DIR/"LSQ*.v "$HDL_DIR" - READ_VERILOG="read_verilog [glob $SYNTH_DIR/hdl/*.v]" -fi - -# Generate synthesis script -echo -e \ -"set_param general.maxThreads 8 -read_vhdl -vhdl2008 [glob $SYNTH_DIR/hdl/*.vhd] -$READ_VERILOG -read_xdc "$F_PERIOD" -synth_design -top $KERNEL_NAME -part xc7k160tfbg484-2 -no_iobuf -mode out_of_context -report_utilization > $F_UTILIZATION_SYN -report_timing > $F_TIMING_SYN -opt_design -place_design -phys_opt_design -route_design -phys_opt_design -report_utilization > $F_UTILIZATION_PR -report_timing > $F_TIMING_PR -exit" > "$F_SCRIPT" - -echo -e \ -"create_clock -name clk -period 4.000 -waveform {0.000 2.000} [get_ports clk] -set_property HD.CLK_SRC BUFGCTRL_X0Y0 [get_ports clk] - -#set_input_delay 0 -clock CLK [all_inputs] -#set_output_delay 0 -clock CLK [all_outputs]" > "$F_PERIOD" - -echo_info "Created synthesization scripts" -echo_info "Launching Vivado synthesis" -vivado -mode tcl -source "$F_SCRIPT" > "$F_REPORT" -RET=$? -rm -rf *.jou *.log .Xil -if [[ $RET -ne 0 ]]; then - echo_fatal "Logic synthesis failed" - exit 1 -fi -echo_info "Logic synthesis succeeded" - -echo_info "All done!" -echo "" diff --git a/tools/dynamatic/scripts/simulate.sh b/tools/dynamatic/scripts/simulate.sh index 57df49626..ac015e3e8 100755 --- a/tools/dynamatic/scripts/simulate.sh +++ b/tools/dynamatic/scripts/simulate.sh @@ -1,16 +1,19 @@ #!/bin/bash +source "$1"/tools/dynamatic/scripts/utils.sh + # ============================================================================ # # Variable definitions # ============================================================================ # -# Script variables +# Script arguments DYNAMATIC_DIR=$1 LEGACY_DIR=$2 SRC_DIR=$3 OUTPUT_DIR=$4 KERNEL_NAME=$5 +COMP_DIR="$OUTPUT_DIR/comp" HLS_VERIFIER="$LEGACY_DIR/Regression_test/hls_verifier/HlsVerifier/build/hlsverifier" # Generated directories/files @@ -22,22 +25,6 @@ VHDL_OUT_DIR="$SIM_DIR/VHDL_OUT" INPUT_VECTORS_DIR="$SIM_DIR/INPUT_VECTORS" HLS_VERIFY_DIR="$SIM_DIR/HLS_VERIFY" -# ============================================================================ # -# Helper funtions -# ============================================================================ # - -# Prints some information to stdout. -# $1: the text to print -echo_info() { - echo "[INFO] $1" -} - -# Prints a fatal error message to stdout. -# $1: the text to print -echo_fatal() { - echo "[FATAL] $1" -} - # ============================================================================ # # Simulation flow # ============================================================================ # @@ -53,8 +40,8 @@ mkdir -p "$C_SRC_DIR" "$C_OUT_DIR" "$VHDL_SRC_DIR" "$VHDL_OUT_DIR" \ cp "$DYNAMATIC_DIR/integration-test/integration_utils.h" "$SIM_DIR" # Copy VHDL module and VHDL components to dedicated folder -cp "$OUTPUT_DIR/$KERNEL_NAME.vhd" "$VHDL_SRC_DIR" -cp "$OUTPUT_DIR/"LSQ*.v "$VHDL_SRC_DIR" 2> /dev/null +cp "$COMP_DIR/$KERNEL_NAME.vhd" "$VHDL_SRC_DIR" +cp "$COMP_DIR/"LSQ*.v "$VHDL_SRC_DIR" 2> /dev/null cp "$LEGACY_DIR"/components/*.vhd "$VHDL_SRC_DIR" # Copy sources to dedicated folder @@ -67,11 +54,4 @@ cd "$HLS_VERIFY_DIR" "$HLS_VERIFIER" cover -aw32 "../C_SRC/$KERNEL_NAME.c" \ "../C_SRC/$KERNEL_NAME.c" "$KERNEL_NAME" \ > "../report.txt" -if [[ $? -ne 0 ]]; then - echo_fatal "Simulation failed" - exit 1 -fi -echo_info "Simulation succeeded" - -echo_info "All done!" -echo "" +exit_on_fail "Simulation failed" "Simulation succeeded" diff --git a/tools/dynamatic/scripts/synthesize.sh b/tools/dynamatic/scripts/synthesize.sh index ae85a1086..571156802 100755 --- a/tools/dynamatic/scripts/synthesize.sh +++ b/tools/dynamatic/scripts/synthesize.sh @@ -1,204 +1,76 @@ #!/bin/bash +source "$1"/tools/dynamatic/scripts/utils.sh + # ============================================================================ # # Variable definitions # ============================================================================ # -# Script variables +# Script arguments DYNAMATIC_DIR=$1 -SRC_DIR=$2 +LEGACY_DIR=$2 OUTPUT_DIR=$3 KERNEL_NAME=$4 -USE_SIMPLE_BUFFERS=$5 - -# Binaries used during synthesis -POLYGEIST_PATH="$DYNAMATIC_DIR/polygeist/llvm-project/clang/lib/Headers/" -POLYGEIST_CLANG_BIN="$DYNAMATIC_DIR/bin/cgeist" -CLANGXX_BIN="$DYNAMATIC_DIR/bin/clang++" -DYNAMATIC_OPT_BIN="$DYNAMATIC_DIR/bin/dynamatic-opt" -DYNAMATIC_PROFILER_BIN="$DYNAMATIC_DIR/bin/exp-frequency-profiler" -DYNAMATIC_EXPORT_DOT_BIN="$DYNAMATIC_DIR/bin/export-dot" - -# Generated files -F_AFFINE="$OUTPUT_DIR/affine.mlir" -F_AFFINE_MEM="$OUTPUT_DIR/affine_mem.mlir" -F_SCF="$OUTPUT_DIR/scf.mlir" -F_CF="$OUTPUT_DIR/std.mlir" -F_CF_TRANFORMED="$OUTPUT_DIR/std_transformed.mlir" -F_CF_DYN_TRANSFORMED="$OUTPUT_DIR/std_dyn_transformed.mlir" -F_PROFILER_BIN="$OUTPUT_DIR/$KERNEL_NAME-profile" -F_PROFILER_INPUTS="$OUTPUT_DIR/profiler-inputs.txt" -F_HANDSHAKE="$OUTPUT_DIR/handshake.mlir" -F_HANDSHAKE_TRANSFORMED="$OUTPUT_DIR/handshake_transformed.mlir" -F_HANDSHAKE_BUFFERED="$OUTPUT_DIR/handshake_buffered.mlir" -F_HANDSHAKE_EXPORT="$OUTPUT_DIR/handshake_export.mlir" -F_FREQUENCIES="$OUTPUT_DIR/frequencies.csv" - -# ============================================================================ # -# Helper funtions -# ============================================================================ # -# Prints some information to stdout. -# $1: the text to print -echo_info() { - echo "[INFO] $1" -} +COMP_DIR="$OUTPUT_DIR/comp" -# Prints a fatal error message to stdout. -# $1: the text to print -echo_fatal() { - echo "[FATAL] $1" -} - - -# Exits the script with a fatal error message if the last command that was -# called before this function failed, otherwise optionally prints an information -# message. -# $1: fatal error message -# $2: [optional] information message -exit_on_fail() { - if [[ $? -ne 0 ]]; then - if [[ ! -z $1 ]]; then - echo_fatal "$1" - exit 1 - fi - echo_fatal "Failed!" - exit 1 - else - if [[ ! -z $2 ]]; then - echo_info "$2" - fi - fi -} - -# Exports Handshake-level IR to DOT using Dynamatic, then converts the DOT to -# a PNG using dot. -# $1: mode to run the tool in; options are "visual", "legacy", "legacy-buffers" -# $2: output filename, without extension (will use .dot and .png) -export_dot() { - local mode=$1 - local f_dot="$OUTPUT_DIR/$2.dot" - local f_png="$OUTPUT_DIR/$2.png" - - # Export to DOT - "$DYNAMATIC_EXPORT_DOT_BIN" "$F_HANDSHAKE_EXPORT" "--mode=$mode" \ - "--edge-style=spline" \ - "--timing-models=$DYNAMATIC_DIR/data/components.json" \ - > "$f_dot" - exit_on_fail "Failed to create $2 DOT" "Created $2 DOT" - - # Convert DOT graph to PNG - dot -Tpng "$f_dot" > "$f_png" - exit_on_fail "Failed to convert $2 DOT to PNG" "Converted $2 DOT to PNG" - return 0 -} +# Generated directories/files +SYNTH_DIR="$OUTPUT_DIR/synth" +HDL_DIR="$SYNTH_DIR/hdl" +F_REPORT="$SYNTH_DIR/report.txt" +F_SCRIPT="$SYNTH_DIR/synthesize.tcl" +F_PERIOD="$SYNTH_DIR/period_4.xdc" +F_UTILIZATION_SYN="$SYNTH_DIR/utilization_post_syn.rpt" +F_TIMING_SYN="$SYNTH_DIR/timing_post_syn.rpt" +F_UTILIZATION_PR="$SYNTH_DIR/utilization_post_pr.rpt" +F_TIMING_PR="$SYNTH_DIR/timing_post_pr.rpt" # ============================================================================ # # Synthesis flow # ============================================================================ # -# Reset output directory -rm -rf "$OUTPUT_DIR" && mkdir -p "$OUTPUT_DIR" - -# source -> affine level -"$POLYGEIST_CLANG_BIN" "$SRC_DIR/$KERNEL_NAME.c" -I \ - "$POLYGEIST_PATH/llvm-project/clang/lib/Headers/" --function="$KERNEL_NAME" \ - -S -O3 --memref-fullrank --raise-scf-to-affine \ - > "$F_AFFINE" 2>/dev/null -exit_on_fail "Failed to compile source to affine" "Compiled source to affine" +# Reset simulation directory +rm -rf "$SYNTH_DIR" && mkdir -p "$SYNTH_DIR" -# affine level -> pre-processing and memory analysis -"$DYNAMATIC_OPT_BIN" "$F_AFFINE" --allow-unregistered-dialect \ - --remove-polygeist-attributes --mark-memory-dependencies \ - --mark-memory-interfaces \ - > "$F_AFFINE_MEM" -exit_on_fail "Failed to run memory analysis" "Ran memory analysis" +# Copy all synthesizable components to specific folder for Vivado +mkdir -p "$HDL_DIR" +cp "$COMP_DIR/$KERNEL_NAME.vhd" "$HDL_DIR" +cp "$LEGACY_DIR"/components/*.vhd "$HDL_DIR" -# affine level -> scf level -"$DYNAMATIC_OPT_BIN" "$F_AFFINE_MEM" --lower-affine-to-scf \ - --flatten-memref-row-major --scf-simple-if-to-select \ - --scf-rotate-for-loops \ - > "$F_SCF" -exit_on_fail "Failed to compile affine to scf" "Compiled affine to scf" - -# scf level -> cf level -"$DYNAMATIC_OPT_BIN" "$F_SCF" --lower-scf-to-cf > "$F_CF" -exit_on_fail "Failed to compile scf to cf" "Compiled scf to cf" - -# cf transformations (standard) -"$DYNAMATIC_OPT_BIN" "$F_CF" --canonicalize --cse --sccp --symbol-dce \ - --control-flow-sink --loop-invariant-code-motion --canonicalize \ - > "$F_CF_TRANFORMED" -exit_on_fail "Failed to apply standard transformations to cf" \ - "Applied standard transformations to cf" - -# cf transformations (dynamatic) -"$DYNAMATIC_OPT_BIN" "$F_CF_TRANFORMED" --flatten-memref-calls \ - --arith-reduce-strength="max-adder-depth-mul=1" --push-constants \ - > "$F_CF_DYN_TRANSFORMED" -exit_on_fail "Failed to apply Dynamatic transformations to cf" \ - "Applied Dynamatic transformations to cf" - -# cf level -> handshake level -"$DYNAMATIC_OPT_BIN" "$F_CF_DYN_TRANSFORMED" --lower-std-to-handshake-fpga18 \ - --handshake-fix-arg-names="source=$SRC_DIR/$KERNEL_NAME.c" \ - > "$F_HANDSHAKE" -exit_on_fail "Failed to compile cf to handshake" "Compiled cf to handshake" - -# handshake transformations -"$DYNAMATIC_OPT_BIN" "$F_HANDSHAKE" \ - --handshake-concretize-index-type="width=32" \ - --handshake-minimize-cst-width --handshake-optimize-bitwidths="legacy" \ - --handshake-materialize-forks-sinks --handshake-infer-basic-blocks \ - > "$F_HANDSHAKE_TRANSFORMED" -exit_on_fail "Failed to apply transformations to handshake" \ - "Applied transformations to handshake" - -# Buffer placement -if [[ $USE_SIMPLE_BUFFERS -ne 0 ]]; then - # Simple buffer placement - "$DYNAMATIC_OPT_BIN" "$F_HANDSHAKE_TRANSFORMED" \ - --handshake-place-buffers="algorithm=on-merges" \ - > "$F_HANDSHAKE_BUFFERED" - exit_on_fail "Failed to place simple buffers" "Placed simple buffers" -else - # Compile kernel's main function to extract profiling information - "$CLANGXX_BIN" "$SRC_DIR/$KERNEL_NAME.c" -D PRINT_PROFILING_INFO \ - -Wno-deprecated -o "$F_PROFILER_BIN" - exit_on_fail "Failed to build kernel for profiling" "Built kernel for profiling" - - "$F_PROFILER_BIN" > "$F_PROFILER_INPUTS" - exit_on_fail "Failed to kernel for profiling" "Ran kernel for profiling" - - # cf-level profiler - "$DYNAMATIC_PROFILER_BIN" "$F_CF_DYN_TRANSFORMED" \ - --top-level-function="$KERNEL_NAME" --input-args-file="$F_PROFILER_INPUTS" \ - > $F_FREQUENCIES - exit_on_fail "Failed to profile cf-level" "Profiled cf-level" - - # Smart buffer placement - echo_info "Running smart buffer placement" - "$DYNAMATIC_OPT_BIN" "$F_HANDSHAKE_TRANSFORMED" \ - --handshake-set-buffering-properties="version=fpga20" \ - --handshake-place-buffers="algorithm=fpga20-legacy frequencies=$OUTPUT_DIR/frequencies.csv timing-models=$DYNAMATIC_DIR/data/components.json timeout=300 dump-logs" \ - > "$F_HANDSHAKE_BUFFERED" - RET=$? - mv buffer-placement "$OUTPUT_DIR" > /dev/null 2>&1 - if [[ $RET -ne 0 ]]; then - echo_fatal "Failed to place smart buffers" - exit 1 - fi - echo_info "Placed smart buffers" +# See if we should include any LSQ in the synthesis script +READ_VERILOG="" +if ls "$COMP_DIR"/LSQ*.v 1> /dev/null 2>&1; then + cp "$COMP_DIR/"LSQ*.v "$HDL_DIR" + READ_VERILOG="read_verilog [glob $SYNTH_DIR/hdl/*.v]" fi -# handshake canonicalization -"$DYNAMATIC_OPT_BIN" "$F_HANDSHAKE_BUFFERED" --handshake-canonicalize \ - > "$F_HANDSHAKE_EXPORT" -exit_on_fail "Failed to canonicalize Handshake" "Canonicalized handshake" - -# Export to DOT (one clean for viewing and one compatible with legacy) -export_dot "visual" "visual" -export_dot "legacy" "$KERNEL_NAME" - -echo_info "All done!" -echo "" +# Generate synthesis script +echo -e \ +"set_param general.maxThreads 8 +read_vhdl -vhdl2008 [glob $SYNTH_DIR/hdl/*.vhd] +$READ_VERILOG +read_xdc "$F_PERIOD" +synth_design -top $KERNEL_NAME -part xc7k160tfbg484-2 -no_iobuf -mode out_of_context +report_utilization > $F_UTILIZATION_SYN +report_timing > $F_TIMING_SYN +opt_design +place_design +phys_opt_design +route_design +phys_opt_design +report_utilization > $F_UTILIZATION_PR +report_timing > $F_TIMING_PR +exit" > "$F_SCRIPT" + +echo -e \ +"create_clock -name clk -period 4.000 -waveform {0.000 2.000} [get_ports clk] +set_property HD.CLK_SRC BUFGCTRL_X0Y0 [get_ports clk] + +#set_input_delay 0 -clock CLK [all_inputs] +#set_output_delay 0 -clock CLK [all_outputs]" > "$F_PERIOD" + +echo_info "Created synthesization scripts" +echo_info "Launching Vivado synthesis" +cd "$SYNTH_DIR" +vivado -mode tcl -source "$F_SCRIPT" > "$F_REPORT" +exit_on_fail "Logic synthesis failed" "Logic synthesis succeeded" diff --git a/tools/dynamatic/scripts/utils.sh b/tools/dynamatic/scripts/utils.sh new file mode 100644 index 000000000..a7b96133c --- /dev/null +++ b/tools/dynamatic/scripts/utils.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +# Prints some information to stdout. +# $1: the text to print +echo_info() { + echo "[INFO] $1" +} + +# Prints a fatal error message to stdout. +# $1: the text to print +echo_fatal() { + echo "[FATAL] $1" +} + + +# Exits the script with a fatal error message if the last command that was +# called before this function failed, otherwise optionally prints an information +# message. +# $1: fatal error message +# $2: [optional] information message +exit_on_fail() { + if [[ $? -ne 0 ]]; then + if [[ ! -z $1 ]]; then + echo_fatal "$1" + exit 1 + fi + echo_fatal "Failed!" + exit 1 + else + if [[ ! -z $2 ]]; then + echo_info "$2" + fi + fi +} diff --git a/tools/dynamatic/scripts/write-hdl.sh b/tools/dynamatic/scripts/write-hdl.sh index ec47d4d7b..b33730d92 100755 --- a/tools/dynamatic/scripts/write-hdl.sh +++ b/tools/dynamatic/scripts/write-hdl.sh @@ -1,29 +1,18 @@ #!/bin/bash -# ============================================================================ # -# Variable definitions -# ============================================================================ # - -# Script variables -LEGACY_DIR=$1 -OUTPUT_DIR=$2 -KERNEL_NAME=$3 +source "$1"/tools/dynamatic/scripts/utils.sh # ============================================================================ # -# Helper funtions +# Variable definitions # ============================================================================ # -# Prints some information to stdout. -# $1: the text to print -echo_info() { - echo "[INFO] $1" -} +# Script arguments +DYNAMATIC_DIR=$1 +LEGACY_DIR=$2 +OUTPUT_DIR=$3 +KERNEL_NAME=$4 -# Prints a fatal error message to stdout. -# $1: the text to print -echo_fatal() { - echo "[FATAL] $1" -} +COMP_DIR="$OUTPUT_DIR/comp" # ============================================================================ # # HDL writing flow @@ -35,15 +24,7 @@ export PATH="${LEGACY_DIR}/bin:${PATH}" export DHLS_INSTALL_DIR="${LEGACY_DIR}/../.." # Convert DOT graph to VHDL -"$LEGACY_DIR/dot2vhdl/bin/dot2vhdl" "$OUTPUT_DIR/$KERNEL_NAME" >/dev/null -if [[ $? -ne 0 ]]; then - rm -rf LSQ* - echo_fatal "Failed to convert DOT to VHDL" - exit 1 -fi -mv LSQ* "$OUTPUT_DIR" 2> /dev/null -rm -f "$OUTPUT_DIR"/*.tcl -echo_info "Converted DOT to VHDL" - -echo_info "All done!" -echo "" +cd "$COMP_DIR" +"$LEGACY_DIR/dot2vhdl/bin/dot2vhdl" "$COMP_DIR/$KERNEL_NAME" >/dev/null +exit_on_fail "Failed to convert DOT to VHDL" "Converted DOT to VHDL" +echo_info "HDL generation succeeded"