Skip to content

Commit

Permalink
[dynamatic] Stability and scripts improvements
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
lucas-rami committed Nov 20, 2023
1 parent 20a691f commit 7ec408f
Show file tree
Hide file tree
Showing 12 changed files with 536 additions and 517 deletions.
4 changes: 2 additions & 2 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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!"
96 changes: 44 additions & 52 deletions tools/dynamatic/dynamatic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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> ";
Expand All @@ -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";

Expand All @@ -99,6 +99,10 @@ struct FrontendState {

bool legacyPathIsSet(StringRef keyword);

std::string getScriptsPath() const {
return dynamaticPath + "/tools/dynamatic/scripts";
}

std::string makeAbsolutePath(StringRef path);
};

Expand Down Expand Up @@ -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<std::string> &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"}}){};
Expand All @@ -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){};

Expand All @@ -230,10 +234,10 @@ class Simulate : public Command {
CommandResult decode(SmallVector<std::string> &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){};

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -455,7 +465,7 @@ CommandResult SetSrc::decode(SmallVector<std::string> &tokens) {
return CommandResult::SUCCESS;
}

CommandResult Synthesize::decode(SmallVector<std::string> &tokens) {
CommandResult Compile::decode(SmallVector<std::string> &tokens) {
ParsedCommand parsed;
if (failed(parse(tokens, parsed)))
return CommandResult::SYNTAX_ERROR;
Expand All @@ -472,14 +482,9 @@ CommandResult Synthesize::decode(SmallVector<std::string> &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<std::string> &tokens) {
Expand All @@ -495,8 +500,8 @@ CommandResult WriteHDL::decode(SmallVector<std::string> &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)) {
Expand All @@ -505,13 +510,9 @@ CommandResult WriteHDL::decode(SmallVector<std::string> &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<std::string> &tokens) {
Expand All @@ -527,8 +528,8 @@ CommandResult Simulate::decode(SmallVector<std::string> &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)) {
Expand All @@ -537,17 +538,12 @@ CommandResult Simulate::decode(SmallVector<std::string> &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<std::string> &tokens) {
CommandResult Synthesize::decode(SmallVector<std::string> &tokens) {
ParsedCommand parsed;
if (failed(parse(tokens, parsed)))
return CommandResult::SYNTAX_ERROR;
Expand All @@ -560,8 +556,8 @@ CommandResult LogicSynthesize::decode(SmallVector<std::string> &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)) {
Expand All @@ -570,13 +566,9 @@ CommandResult LogicSynthesize::decode(SmallVector<std::string> &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<std::string> &tokens) {
Expand Down Expand Up @@ -630,10 +622,10 @@ int main(int argc, char **argv) {
commands.add<SetDynamaticPath>(state);
commands.add<SetLegacyPath>(state);
commands.add<SetSrc>(state);
commands.add<Synthesize>(state);
commands.add<Compile>(state);
commands.add<WriteHDL>(state);
commands.add<Simulate>(state);
commands.add<LogicSynthesize>(state);
commands.add<Synthesize>(state);
commands.add<Help>(state);
commands.add<Exit>(state);

Expand Down
8 changes: 4 additions & 4 deletions tools/dynamatic/samples/fir.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -23,7 +23,7 @@ write-hdl
simulate

# Synthesize using Vivado
logic-synthesize
synthesize

# Exit the frontend
exit
exit
61 changes: 0 additions & 61 deletions tools/dynamatic/samples/fpl22.sh

This file was deleted.

Loading

0 comments on commit 7ec408f

Please sign in to comment.