diff options
author | Eddie Hung <eddie@fpgeh.com> | 2020-01-13 09:04:20 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-13 09:04:20 -0800 |
commit | ca2f3db53f3f330d283079bf44b3cef6b7f197be (patch) | |
tree | b633788b56a0575be8f70644641c352adb1a653e | |
parent | 0f489c5ea340869206888c6f1feb672b7202b185 (diff) | |
parent | 35e49fde4dfa67030a3e80d0bdf700c97258ed45 (diff) | |
download | yosys-ca2f3db53f3f330d283079bf44b3cef6b7f197be.tar.gz yosys-ca2f3db53f3f330d283079bf44b3cef6b7f197be.tar.bz2 yosys-ca2f3db53f3f330d283079bf44b3cef6b7f197be.zip |
Merge pull request #1620 from YosysHQ/eddie/abc9_scratchpad
abc9: add some scripts/options into "scratchpad"
-rw-r--r-- | kernel/rtlil.cc | 1 | ||||
-rw-r--r-- | kernel/rtlil.h | 2 | ||||
-rw-r--r-- | passes/cmds/scratchpad.cc | 25 | ||||
-rw-r--r-- | passes/techmap/abc9.cc | 100 | ||||
-rw-r--r-- | techlibs/xilinx/synth_xilinx.cc | 15 | ||||
-rw-r--r-- | tests/techmap/abc9.ys | 40 |
6 files changed, 147 insertions, 36 deletions
diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index ab4f4f377..f286d139f 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -46,6 +46,7 @@ IdString RTLIL::ID::Y; IdString RTLIL::ID::keep; IdString RTLIL::ID::whitebox; IdString RTLIL::ID::blackbox; +dict<std::string, std::string> RTLIL::constpad; RTLIL::Const::Const() { diff --git a/kernel/rtlil.h b/kernel/rtlil.h index e5b24cc02..6251d265d 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -377,6 +377,8 @@ namespace RTLIL extern IdString blackbox; }; + extern dict<std::string, std::string> constpad; + static inline std::string escape_id(std::string str) { if (str.size() > 0 && str[0] != '\\' && str[0] != '$') return "\\" + str; diff --git a/passes/cmds/scratchpad.cc b/passes/cmds/scratchpad.cc index 7ec55b78e..34ec0863a 100644 --- a/passes/cmds/scratchpad.cc +++ b/passes/cmds/scratchpad.cc @@ -70,8 +70,10 @@ struct ScratchpadPass : public Pass { { if (args[argidx] == "-get" && argidx+1 < args.size()) { string identifier = args[++argidx]; - if (design->scratchpad.count(identifier)){ + if (design->scratchpad.count(identifier)) { log("%s\n", design->scratchpad_get_string(identifier).c_str()); + } else if (RTLIL::constpad.count(identifier)) { + log("%s\n", RTLIL::constpad.at(identifier).c_str()); } else { log("\"%s\" not set\n", identifier.c_str()); } @@ -79,6 +81,8 @@ struct ScratchpadPass : public Pass { } if (args[argidx] == "-set" && argidx+2 < args.size()) { string identifier = args[++argidx]; + if (RTLIL::constpad.count(identifier)) + log_error("scratchpad entry \"%s\" is a global constant\n", identifier.c_str()); string value = args[++argidx]; if (value.front() == '\"' && value.back() == '\"') value = value.substr(1, value.size() - 2); design->scratchpad_set_string(identifier, value); @@ -92,8 +96,15 @@ struct ScratchpadPass : public Pass { if (args[argidx] == "-copy" && argidx+2 < args.size()) { string identifier_from = args[++argidx]; string identifier_to = args[++argidx]; - if (design->scratchpad.count(identifier_from) == 0) log_error("\"%s\" not set\n", identifier_from.c_str()); - string value = design->scratchpad_get_string(identifier_from); + string value; + if (design->scratchpad.count(identifier_from)) + value = design->scratchpad_get_string(identifier_from); + else if (RTLIL::constpad.count(identifier_from)) + value = RTLIL::constpad.at(identifier_from); + else + log_error("\"%s\" not set\n", identifier_from.c_str()); + if (RTLIL::constpad.count(identifier_to)) + log_error("scratchpad entry \"%s\" is a global constant\n", identifier_to.c_str()); design->scratchpad_set_string(identifier_to, value); continue; } @@ -102,10 +113,10 @@ struct ScratchpadPass : public Pass { string expected = args[++argidx]; if (expected.front() == '\"' && expected.back() == '\"') expected = expected.substr(1, expected.size() - 2); if (design->scratchpad.count(identifier) == 0) - log_error("Assertion failed: scratchpad entry '%s' is not defined\n", identifier.c_str()); + log_error("scratchpad entry '%s' is not defined\n", identifier.c_str()); string value = design->scratchpad_get_string(identifier); if (value != expected) { - log_error("Assertion failed: scratchpad entry '%s' is set to '%s' instead of the asserted '%s'\n", + log_error("scratchpad entry '%s' is set to '%s' instead of the asserted '%s'\n", identifier.c_str(), value.c_str(), expected.c_str()); } continue; @@ -113,13 +124,13 @@ struct ScratchpadPass : public Pass { if (args[argidx] == "-assert-set" && argidx+1 < args.size()) { string identifier = args[++argidx]; if (design->scratchpad.count(identifier) == 0) - log_error("Assertion failed: scratchpad entry '%s' is not defined\n", identifier.c_str()); + log_error("scratchpad entry '%s' is not defined\n", identifier.c_str()); continue; } if (args[argidx] == "-assert-unset" && argidx+1 < args.size()) { string identifier = args[++argidx]; if (design->scratchpad.count(identifier) > 0) - log_error("Assertion failed: scratchpad entry '%s' is defined\n", identifier.c_str()); + log_error("scratchpad entry '%s' is defined\n", identifier.c_str()); continue; } break; diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 471c11a80..8a6195741 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -22,20 +22,6 @@ // Berkeley Logic Synthesis and Verification Group, ABC: A System for Sequential Synthesis and Verification // http://www.eecs.berkeley.edu/~alanmi/abc/ -#if 0 -// Based on &flow3 - better QoR but more experimental -#define ABC_COMMAND_LUT "&st; &ps -l; &sweep -v; &scorr; " \ - "&st; &if {W}; &save; &st; &syn2; &if {W} -v; &save; &load; "\ - "&st; &if -g -K 6; &dch -f; &if {W} -v; &save; &load; "\ - "&st; &if -g -K 6; &synch2; &if {W} -v; &save; &load; "\ - "&mfs; &ps -l" -#else -#define ABC_COMMAND_LUT "&st; &scorr; &sweep; &dc2; &st; &dch -f; &ps; &if {W} {D} -v; &mfs; &ps -l" -#endif - - -#define ABC_FAST_COMMAND_LUT "&st; &if {W} {D}" - #include "kernel/register.h" #include "kernel/sigtools.h" #include "kernel/celltypes.h" @@ -292,7 +278,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip } else abc9_script += stringf("source %s", script_file.c_str()); } else if (!lut_costs.empty() || !lut_file.empty()) { - abc9_script += fast_mode ? ABC_FAST_COMMAND_LUT : ABC_COMMAND_LUT; + abc9_script += fast_mode ? RTLIL::constpad.at("abc9.script.default.fast").substr(1,std::string::npos) + : RTLIL::constpad.at("abc9.script.default").substr(1,std::string::npos); } else log_abort(); @@ -305,7 +292,26 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip for (size_t pos = abc9_script.find("{W}"); pos != std::string::npos; pos = abc9_script.find("{W}", pos)) abc9_script = abc9_script.substr(0, pos) + wire_delay + abc9_script.substr(pos+3); - abc9_script += stringf("; &write -n %s/output.aig", tempdir_name.c_str()); + std::string C; + if (design->scratchpad.count("abc9.if.C")) + C = "-C " + design->scratchpad_get_string("abc9.if.C"); + for (size_t pos = abc9_script.find("{C}"); pos != std::string::npos; pos = abc9_script.find("{C}", pos)) + abc9_script = abc9_script.substr(0, pos) + C + abc9_script.substr(pos+3); + + std::string R; + if (design->scratchpad.count("abc9.if.R")) + R = "-R " + design->scratchpad_get_string("abc9.if.R"); + for (size_t pos = abc9_script.find("{R}"); pos != std::string::npos; pos = abc9_script.find("{R}", pos)) + abc9_script = abc9_script.substr(0, pos) + R + abc9_script.substr(pos+3); + + abc9_script += stringf("; &ps -l; &write -n %s/output.aig;", tempdir_name.c_str()); + if (design->scratchpad_get_bool("abc9.verify")) { + if (dff_mode) + abc9_script += "verify -s;"; + else + abc9_script += "verify;"; + } + abc9_script += "time"; abc9_script = add_echos_to_abc9_cmd(abc9_script); for (size_t i = 0; i+1 < abc9_script.size(); i++) @@ -725,6 +731,51 @@ clone_lut: struct Abc9Pass : public Pass { Abc9Pass() : Pass("abc9", "use ABC9 for technology mapping") { } + void on_register() YS_OVERRIDE + { + RTLIL::constpad["abc9.script.default"] = "+&scorr; &sweep; &dc2; &dch -f; &ps; &if {C} {W} {D} {R} -v; &mfs"; + RTLIL::constpad["abc9.script.default.area"] = "+&scorr; &sweep; &dc2; &dch -f; &ps; &if {C} {W} {D} {R} -a -v; &mfs"; + RTLIL::constpad["abc9.script.default.fast"] = "+&if {C} {W} {D} {R} -v"; + // Based on ABC's &flow + RTLIL::constpad["abc9.script.flow"] = "+&scorr; &sweep;" \ + "&dch -C 500;" \ + /* Round 1 */ \ + /* Map 1 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ + "&st; &dsdb;" \ + /* Map 2 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ + "&st; &syn2 -m -R 10; &dsdb;" \ + "&blut -a -K 6;" \ + /* Map 3 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ + /* Round 2 */ \ + "&st; &sopb;" \ + /* Map 1 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ + "&st; &dsdb;" \ + /* Map 2 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ + "&st; &syn2 -m -R 10; &dsdb;" \ + "&blut -a -K 6;" \ + /* Map 3 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ + /* Round 3 */ \ + /* Map 1 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ + "&st; &dsdb;" \ + /* Map 2 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;" \ + "&st; &syn2 -m -R 10; &dsdb;" \ + "&blut -a -K 6;" \ + /* Map 3 */ "&unmap; &if {C} {W} {D} {R} -v; &save; &load; &mfs;"; + // Based on ABC's &flow2 + RTLIL::constpad["abc9.script.flow2"] = "+&scorr; &sweep;" \ + /* Comm1 */ "&synch2 -K 6 -C 500; &if -m {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save;"\ + /* Comm2 */ "&dch -C 500; &if -m {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save;"\ + "&load; &st; &sopb -R 10 -C 4; " \ + /* Comm3 */ "&synch2 -K 6 -C 500; &if -m "/*"-E 5"*/" {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save;"\ + /* Comm2 */ "&dch -C 500; &if -m {C} {W} {D} {R} -v; &mfs "/*"-W 4 -M 500 -C 7000"*/"; &save; "\ + "&load"; + // Based on ABC's &flow3 + RTLIL::constpad["abc9.script.flow3"] = "+&scorr; &sweep;" \ + "&if {C} {W} {D}; &save; &st; &syn2; &if {C} {W} {D} {R} -v; &save; &load;"\ + "&st; &if {C} -g -K 6; &dch -f; &if {C} {W} {D} {R} -v; &save; &load;"\ + "&st; &if {C} -g -K 6; &synch2; &if {C} {W} {D} {R} -v; &save; &load;"\ + "&mfs"; + } void help() YS_OVERRIDE { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| @@ -752,18 +803,15 @@ struct Abc9Pass : public Pass { log("\n"); log(" if no -script parameter is given, the following scripts are used:\n"); log("\n"); - log(" for -lut/-luts (only one LUT size):\n"); - log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str()); - log("\n"); - log(" for -lut/-luts (different LUT sizes):\n"); - log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str()); + log(" for -lut/-luts:\n"); + log("%s\n", fold_abc9_cmd(RTLIL::constpad.at("abc9.script.default").substr(1,std::string::npos)).c_str()); log("\n"); log(" -fast\n"); log(" use different default scripts that are slightly faster (at the cost\n"); log(" of output quality):\n"); log("\n"); log(" for -lut/-luts:\n"); - log("%s\n", fold_abc9_cmd(ABC_FAST_COMMAND_LUT).c_str()); + log("%s\n", fold_abc9_cmd(RTLIL::constpad.at("abc9.script.default.fast").substr(1,std::string::npos)).c_str()); log("\n"); log(" -D <picoseconds>\n"); log(" set delay target. the string {D} in the default scripts above is\n"); @@ -861,6 +909,11 @@ struct Abc9Pass : public Pass { wire_delay = "-W " + design->scratchpad_get_string("abc9.W"); } + if (design->scratchpad_get_bool("abc9.debug")) { + cleanup = false; + show_tempdir = true; + } + size_t argidx; char pwd [PATH_MAX]; if (!getcwd(pwd, sizeof(pwd))) { @@ -875,9 +928,6 @@ struct Abc9Pass : public Pass { } if (arg == "-script" && argidx+1 < args.size()) { script_file = args[++argidx]; - rewrite_filename(script_file); - if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+') - script_file = std::string(pwd) + "/" + script_file; continue; } if (arg == "-D" && argidx+1 < args.size()) { diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 63d00027a..d916093dc 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -26,13 +26,16 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -#define XC7_WIRE_DELAY 300 // Number with which ABC will map a 6-input gate - // to one LUT6 (instead of a LUT5 + LUT2) - struct SynthXilinxPass : public ScriptPass { SynthXilinxPass() : ScriptPass("synth_xilinx", "synthesis for Xilinx FPGAs") { } + void on_register() YS_OVERRIDE + { + RTLIL::constpad["synth_xilinx.abc9.xc7.W"] = "300"; // Number with which ABC will map a 6-input gate + // to one LUT6 (instead of a LUT5 + LUT2) + } + void help() YS_OVERRIDE { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| @@ -555,7 +558,11 @@ struct SynthXilinxPass : public ScriptPass run("techmap " + techmap_args); run("read_verilog -icells -lib +/xilinx/abc9_model.v"); std::string abc9_opts = " -box +/xilinx/abc9_xc7.box"; - abc9_opts += stringf(" -W %d", XC7_WIRE_DELAY); + auto k = stringf("synth_xilinx.abc9.%s.W", family.c_str()); + if (active_design->scratchpad.count(k)) + abc9_opts += stringf(" -W %s", active_design->scratchpad_get_string(k).c_str()); + else + abc9_opts += stringf(" -W %s", RTLIL::constpad.at(k).c_str()); if (nowidelut) abc9_opts += " -lut +/xilinx/abc9_xc7_nowide.lut"; else diff --git a/tests/techmap/abc9.ys b/tests/techmap/abc9.ys new file mode 100644 index 000000000..20f263da8 --- /dev/null +++ b/tests/techmap/abc9.ys @@ -0,0 +1,40 @@ +read_verilog <<EOT +`define N 256 +module top(input [`N-1:0] a, output o); +wire [`N-2:0] w; +assign w[0] = a[0] & a[1]; +genvar i; +generate for (i = 1; i < `N-1; i++) +assign w[i] = w[i-1] & a[i+1]; +endgenerate +assign o = w[`N-2]; +endmodule +EOT +simplemap +dump +design -save gold + +abc9 -lut 4 + +design -load gold +abc9 -lut 4 -fast + +design -load gold +scratchpad -copy abc9.script.default.area abc9.script +abc9 -lut 4 + +design -load gold +scratchpad -copy abc9.script.default.fast abc9.script +abc9 -lut 4 + +design -load gold +scratchpad -copy abc9.script.flow abc9.script +abc9 -lut 4 + +design -load gold +scratchpad -copy abc9.script.flow2 abc9.script +abc9 -lut 4 + +design -load gold +scratchpad -copy abc9.script.flow3 abc9.script +abc9 -lut 4 |