Apply minor coding style changes to coolrunner2 target
authorClifford Wolf <clifford@clifford.at>
Mon, 3 Jul 2017 17:35:40 +0000 (19:35 +0200)
committerClifford Wolf <clifford@clifford.at>
Mon, 3 Jul 2017 17:35:40 +0000 (19:35 +0200)
techlibs/coolrunner2/coolrunner2_sop.cc [new file with mode: 0644]
techlibs/coolrunner2/coolrunner2_sop.cpp [deleted file]
techlibs/coolrunner2/synth_coolrunner2.cc [new file with mode: 0644]
techlibs/coolrunner2/synth_coolrunner2.cpp [deleted file]

diff --git a/techlibs/coolrunner2/coolrunner2_sop.cc b/techlibs/coolrunner2/coolrunner2_sop.cc
new file mode 100644 (file)
index 0000000..cc214cf
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ *  yosys -- Yosys Open SYnthesis Suite
+ *
+ *  Copyright (C) 2017 Robert Ou <rqou@robertou.com>
+ *
+ *  Permission to use, copy, modify, and/or distribute this software for any
+ *  purpose with or without fee is hereby granted, provided that the above
+ *  copyright notice and this permission notice appear in all copies.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "kernel/yosys.h"
+#include "kernel/sigtools.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct Coolrunner2SopPass : public Pass {
+       Coolrunner2SopPass() : Pass("coolrunner2_sop", "break $sop cells into ANDTERM/ORTERM cells") { }
+       virtual void help()
+       {
+               log("\n");
+               log("    coolrunner2_sop [options] [selection]\n");
+               log("\n");
+               log("Break $sop cells into ANDTERM/ORTERM cells.\n");
+               log("\n");
+       }
+       virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+       {
+               log_header(design, "Executing COOLRUNNER2_SOP pass (break $sop cells into ANDTERM/ORTERM cells).\n");
+               extra_args(args, 1, design);
+
+               // Find all the $_NOT_ cells
+               dict<SigBit, tuple<SigBit, Cell*>> not_cells;
+               for (auto module : design->selected_modules())
+               {
+                       SigMap sigmap(module);
+                       for (auto cell : module->selected_cells())
+                       {
+                               if (cell->type == "$_NOT_")
+                               {
+                                       auto not_input = cell->getPort("\\A")[0];
+                                       auto not_output = cell->getPort("\\Y")[0];
+                                       not_cells[not_input] = {not_output, cell};
+                               }
+                       }
+               }
+
+               pool<tuple<Module*, Cell*>> cells_to_remove;
+               for (auto module : design->selected_modules())
+               {
+                       SigMap sigmap(module);
+                       for (auto cell : module->selected_cells())
+                       {
+                               if (cell->type == "$sop")
+                               {
+                                       // Read the inputs/outputs/parameters of the $sop cell
+                                       auto sop_inputs = sigmap(cell->getPort("\\A"));
+                                       auto sop_output = sigmap(cell->getPort("\\Y"))[0];
+                                       auto sop_depth = cell->getParam("\\DEPTH").as_int();
+                                       auto sop_width = cell->getParam("\\WIDTH").as_int();
+                                       auto sop_table = cell->getParam("\\TABLE");
+
+                                       // Check for a $_NOT_ at the output
+                                       bool has_invert = false;
+                                       if (not_cells.count(sop_output))
+                                       {
+                                               auto not_cell = not_cells.at(sop_output);
+
+                                               has_invert = true;
+                                               sop_output = std::get<0>(not_cell);
+
+                                               // remove the $_NOT_ cell because it gets folded into the xor
+                                               cells_to_remove.insert({module, std::get<1>(not_cell)});
+                                       }
+
+                                       // Construct AND cells
+                                       pool<SigBit> intermed_wires;
+                                       for (int i = 0; i < sop_depth; i++) {
+                                               // Wire for the output
+                                               auto and_out = module->addWire(NEW_ID);
+                                               intermed_wires.insert(and_out);
+
+                                               // Signals for the inputs
+                                               pool<SigBit> and_in_true;
+                                               pool<SigBit> and_in_comp;
+                                               for (int j = 0; j < sop_width; j++)
+                                               {
+                                                       if (sop_table[2 * (i * sop_width + j) + 0])
+                                                       {
+                                                               and_in_comp.insert(sop_inputs[j]);
+                                                       }
+                                                       if (sop_table[2 * (i * sop_width + j) + 1])
+                                                       {
+                                                               and_in_true.insert(sop_inputs[j]);
+                                                       }
+                                               }
+
+                                               // Construct the cell
+                                               auto and_cell = module->addCell(NEW_ID, "\\ANDTERM");
+                                               and_cell->setParam("\\TRUE_INP", GetSize(and_in_true));
+                                               and_cell->setParam("\\COMP_INP", GetSize(and_in_comp));
+                                               and_cell->setPort("\\OUT", and_out);
+                                               and_cell->setPort("\\IN", and_in_true);
+                                               and_cell->setPort("\\IN_B", and_in_comp);
+                                       }
+
+                                       if (sop_depth == 1)
+                                       {
+                                               // If there is only one term, don't construct an OR cell. Directly construct the XOR gate
+                                               auto xor_cell = module->addCell(NEW_ID, "\\MACROCELL_XOR");
+                                               xor_cell->setParam("\\INVERT_OUT", has_invert);
+                                               xor_cell->setPort("\\IN_PTC", *intermed_wires.begin());
+                                               xor_cell->setPort("\\OUT", sop_output);
+                                       }
+                                       else
+                                       {
+                                               // Wire from OR to XOR
+                                               auto or_to_xor_wire = module->addWire(NEW_ID);
+
+                                               // Construct the OR cell
+                                               auto or_cell = module->addCell(NEW_ID, "\\ORTERM");
+                                               or_cell->setParam("\\WIDTH", sop_depth);
+                                               or_cell->setPort("\\IN", intermed_wires);
+                                               or_cell->setPort("\\OUT", or_to_xor_wire);
+
+                                               // Construct the XOR cell
+                                               auto xor_cell = module->addCell(NEW_ID, "\\MACROCELL_XOR");
+                                               xor_cell->setParam("\\INVERT_OUT", has_invert);
+                                               xor_cell->setPort("\\IN_ORTERM", or_to_xor_wire);
+                                               xor_cell->setPort("\\OUT", sop_output);
+                                       }
+
+                                       // Finally, remove the $sop cell
+                                       cells_to_remove.insert({module, cell});
+                               }
+                       }
+               }
+
+               // Actually do the removal now that we aren't iterating
+               for (auto mod_and_cell : cells_to_remove)
+               {
+                       std::get<0>(mod_and_cell)->remove(std::get<1>(mod_and_cell));
+               }
+       }
+} Coolrunner2SopPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/techlibs/coolrunner2/coolrunner2_sop.cpp b/techlibs/coolrunner2/coolrunner2_sop.cpp
deleted file mode 100644 (file)
index cc214cf..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- *  yosys -- Yosys Open SYnthesis Suite
- *
- *  Copyright (C) 2017 Robert Ou <rqou@robertou.com>
- *
- *  Permission to use, copy, modify, and/or distribute this software for any
- *  purpose with or without fee is hereby granted, provided that the above
- *  copyright notice and this permission notice appear in all copies.
- *
- *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
-#include "kernel/yosys.h"
-#include "kernel/sigtools.h"
-
-USING_YOSYS_NAMESPACE
-PRIVATE_NAMESPACE_BEGIN
-
-struct Coolrunner2SopPass : public Pass {
-       Coolrunner2SopPass() : Pass("coolrunner2_sop", "break $sop cells into ANDTERM/ORTERM cells") { }
-       virtual void help()
-       {
-               log("\n");
-               log("    coolrunner2_sop [options] [selection]\n");
-               log("\n");
-               log("Break $sop cells into ANDTERM/ORTERM cells.\n");
-               log("\n");
-       }
-       virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
-       {
-               log_header(design, "Executing COOLRUNNER2_SOP pass (break $sop cells into ANDTERM/ORTERM cells).\n");
-               extra_args(args, 1, design);
-
-               // Find all the $_NOT_ cells
-               dict<SigBit, tuple<SigBit, Cell*>> not_cells;
-               for (auto module : design->selected_modules())
-               {
-                       SigMap sigmap(module);
-                       for (auto cell : module->selected_cells())
-                       {
-                               if (cell->type == "$_NOT_")
-                               {
-                                       auto not_input = cell->getPort("\\A")[0];
-                                       auto not_output = cell->getPort("\\Y")[0];
-                                       not_cells[not_input] = {not_output, cell};
-                               }
-                       }
-               }
-
-               pool<tuple<Module*, Cell*>> cells_to_remove;
-               for (auto module : design->selected_modules())
-               {
-                       SigMap sigmap(module);
-                       for (auto cell : module->selected_cells())
-                       {
-                               if (cell->type == "$sop")
-                               {
-                                       // Read the inputs/outputs/parameters of the $sop cell
-                                       auto sop_inputs = sigmap(cell->getPort("\\A"));
-                                       auto sop_output = sigmap(cell->getPort("\\Y"))[0];
-                                       auto sop_depth = cell->getParam("\\DEPTH").as_int();
-                                       auto sop_width = cell->getParam("\\WIDTH").as_int();
-                                       auto sop_table = cell->getParam("\\TABLE");
-
-                                       // Check for a $_NOT_ at the output
-                                       bool has_invert = false;
-                                       if (not_cells.count(sop_output))
-                                       {
-                                               auto not_cell = not_cells.at(sop_output);
-
-                                               has_invert = true;
-                                               sop_output = std::get<0>(not_cell);
-
-                                               // remove the $_NOT_ cell because it gets folded into the xor
-                                               cells_to_remove.insert({module, std::get<1>(not_cell)});
-                                       }
-
-                                       // Construct AND cells
-                                       pool<SigBit> intermed_wires;
-                                       for (int i = 0; i < sop_depth; i++) {
-                                               // Wire for the output
-                                               auto and_out = module->addWire(NEW_ID);
-                                               intermed_wires.insert(and_out);
-
-                                               // Signals for the inputs
-                                               pool<SigBit> and_in_true;
-                                               pool<SigBit> and_in_comp;
-                                               for (int j = 0; j < sop_width; j++)
-                                               {
-                                                       if (sop_table[2 * (i * sop_width + j) + 0])
-                                                       {
-                                                               and_in_comp.insert(sop_inputs[j]);
-                                                       }
-                                                       if (sop_table[2 * (i * sop_width + j) + 1])
-                                                       {
-                                                               and_in_true.insert(sop_inputs[j]);
-                                                       }
-                                               }
-
-                                               // Construct the cell
-                                               auto and_cell = module->addCell(NEW_ID, "\\ANDTERM");
-                                               and_cell->setParam("\\TRUE_INP", GetSize(and_in_true));
-                                               and_cell->setParam("\\COMP_INP", GetSize(and_in_comp));
-                                               and_cell->setPort("\\OUT", and_out);
-                                               and_cell->setPort("\\IN", and_in_true);
-                                               and_cell->setPort("\\IN_B", and_in_comp);
-                                       }
-
-                                       if (sop_depth == 1)
-                                       {
-                                               // If there is only one term, don't construct an OR cell. Directly construct the XOR gate
-                                               auto xor_cell = module->addCell(NEW_ID, "\\MACROCELL_XOR");
-                                               xor_cell->setParam("\\INVERT_OUT", has_invert);
-                                               xor_cell->setPort("\\IN_PTC", *intermed_wires.begin());
-                                               xor_cell->setPort("\\OUT", sop_output);
-                                       }
-                                       else
-                                       {
-                                               // Wire from OR to XOR
-                                               auto or_to_xor_wire = module->addWire(NEW_ID);
-
-                                               // Construct the OR cell
-                                               auto or_cell = module->addCell(NEW_ID, "\\ORTERM");
-                                               or_cell->setParam("\\WIDTH", sop_depth);
-                                               or_cell->setPort("\\IN", intermed_wires);
-                                               or_cell->setPort("\\OUT", or_to_xor_wire);
-
-                                               // Construct the XOR cell
-                                               auto xor_cell = module->addCell(NEW_ID, "\\MACROCELL_XOR");
-                                               xor_cell->setParam("\\INVERT_OUT", has_invert);
-                                               xor_cell->setPort("\\IN_ORTERM", or_to_xor_wire);
-                                               xor_cell->setPort("\\OUT", sop_output);
-                                       }
-
-                                       // Finally, remove the $sop cell
-                                       cells_to_remove.insert({module, cell});
-                               }
-                       }
-               }
-
-               // Actually do the removal now that we aren't iterating
-               for (auto mod_and_cell : cells_to_remove)
-               {
-                       std::get<0>(mod_and_cell)->remove(std::get<1>(mod_and_cell));
-               }
-       }
-} Coolrunner2SopPass;
-
-PRIVATE_NAMESPACE_END
diff --git a/techlibs/coolrunner2/synth_coolrunner2.cc b/techlibs/coolrunner2/synth_coolrunner2.cc
new file mode 100644 (file)
index 0000000..ae4b843
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ *  yosys -- Yosys Open SYnthesis Suite
+ *
+ *  Copyright (C) 2017 Robert Ou <rqou@robertou.com>
+ *
+ *  Permission to use, copy, modify, and/or distribute this software for any
+ *  purpose with or without fee is hereby granted, provided that the above
+ *  copyright notice and this permission notice appear in all copies.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "kernel/register.h"
+#include "kernel/celltypes.h"
+#include "kernel/rtlil.h"
+#include "kernel/log.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct SynthCoolrunner2Pass : public ScriptPass
+{
+       SynthCoolrunner2Pass() : ScriptPass("synth_coolrunner2", "synthesis for Xilinx Coolrunner-II CPLDs") { }
+
+       virtual void help() YS_OVERRIDE
+       {
+               //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+               log("\n");
+               log("    synth_coolrunner2 [options]\n");
+               log("\n");
+               log("This command runs synthesis for Coolrunner-II CPLDs. This work is experimental.\n");
+               log("It is intended to be used with https://github.com/azonenberg/openfpga as the\n");
+               log("place-and-route.\n");
+               log("\n");
+               log("    -top <module>\n");
+               log("        use the specified module as top module (default='top')\n");
+               log("\n");
+               log("    -json <file>\n");
+               log("        write the design to the specified JSON file. writing of an output file\n");
+               log("        is omitted if this parameter is not specified.\n");
+               log("\n");
+               log("    -run <from_label>:<to_label>\n");
+               log("        only run the commands between the labels (see below). an empty\n");
+               log("        from label is synonymous to 'begin', and empty to label is\n");
+               log("        synonymous to the end of the command list.\n");
+               log("\n");
+               log("    -noflatten\n");
+               log("        do not flatten design before synthesis\n");
+               log("\n");
+               log("    -retime\n");
+               log("        run 'abc' with -dff option\n");
+               log("\n");
+               log("\n");
+               log("The following commands are executed by this synthesis command:\n");
+               help_script();
+               log("\n");
+       }
+
+       string top_opt, json_file;
+       bool flatten, retime;
+
+       virtual void clear_flags() YS_OVERRIDE
+       {
+               top_opt = "-auto-top";
+               json_file = "";
+               flatten = true;
+               retime = false;
+       }
+
+       virtual void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+       {
+               string run_from, run_to;
+               clear_flags();
+
+               size_t argidx;
+               for (argidx = 1; argidx < args.size(); argidx++)
+               {
+                       if (args[argidx] == "-top" && argidx+1 < args.size()) {
+                               top_opt = "-top " + args[++argidx];
+                               continue;
+                       }
+                       if (args[argidx] == "-json" && argidx+1 < args.size()) {
+                               json_file = args[++argidx];
+                               continue;
+                       }
+                       if (args[argidx] == "-run" && argidx+1 < args.size()) {
+                               size_t pos = args[argidx+1].find(':');
+                               if (pos == std::string::npos)
+                                       break;
+                               run_from = args[++argidx].substr(0, pos);
+                               run_to = args[argidx].substr(pos+1);
+                               continue;
+                       }
+                       if (args[argidx] == "-noflatten") {
+                               flatten = false;
+                               continue;
+                       }
+                       if (args[argidx] == "-retime") {
+                               retime = true;
+                               continue;
+                       }
+                       break;
+               }
+               extra_args(args, argidx, design);
+
+               if (!design->full_selection())
+                       log_cmd_error("This comannd only operates on fully selected designs!\n");
+
+               log_header(design, "Executing SYNTH_COOLRUNNER2 pass.\n");
+               log_push();
+
+               run_script(design, run_from, run_to);
+
+               log_pop();
+       }
+
+       virtual void script() YS_OVERRIDE
+       {
+               if (check_label("begin"))
+               {
+                       run("read_verilog -lib +/coolrunner2/cells_sim.v");
+                       run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
+               }
+
+               if (check_label("flatten", "(unless -noflatten)") && flatten)
+               {
+                       run("proc");
+                       run("flatten");
+                       run("tribuf -logic");
+               }
+
+               if (check_label("coarse"))
+               {
+                       run("synth -run coarse");
+               }
+
+               if (check_label("fine"))
+               {
+                       run("opt -fast -full");
+                       run("techmap");
+                       run("techmap -map +/coolrunner2/cells_latch.v");
+                       run("dfflibmap -prepare -liberty +/coolrunner2/xc2_dff.lib");
+               }
+
+               if (check_label("map_pla"))
+               {
+                       run("abc -sop -I 40 -P 56");
+                       run("coolrunner2_sop");
+                       run("opt -fast");
+               }
+
+               if (check_label("map_cells"))
+               {
+                       run("dfflibmap -liberty +/coolrunner2/xc2_dff.lib");
+                       run("dffinit -ff FDCP Q INIT");
+                       run("dffinit -ff FDCP_N Q INIT");
+                       run("dffinit -ff LDCP Q INIT");
+                       run("dffinit -ff LDCP_N Q INIT");
+                       run("iopadmap -bits -inpad IBUF O:I -outpad IOBUFE I:IO -inoutpad IOBUFE O:IO -toutpad IOBUFE E:I:IO -tinoutpad IOBUFE E:O:I:IO");
+               }
+
+               if (check_label("check"))
+               {
+                       run("hierarchy -check");
+                       run("stat");
+                       run("check -noinit");
+               }
+
+               if (check_label("json"))
+               {
+                       if (!json_file.empty() || help_mode)
+                               run(stringf("write_json %s", help_mode ? "<file-name>" : json_file.c_str()));
+               }
+
+               log_pop();
+       }
+} SynthCoolrunner2Pass;
+
+PRIVATE_NAMESPACE_END
diff --git a/techlibs/coolrunner2/synth_coolrunner2.cpp b/techlibs/coolrunner2/synth_coolrunner2.cpp
deleted file mode 100644 (file)
index 791bcff..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- *  yosys -- Yosys Open SYnthesis Suite
- *
- *  Copyright (C) 2017 Robert Ou <rqou@robertou.com>
- *
- *  Permission to use, copy, modify, and/or distribute this software for any
- *  purpose with or without fee is hereby granted, provided that the above
- *  copyright notice and this permission notice appear in all copies.
- *
- *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
-#include "kernel/register.h"
-#include "kernel/celltypes.h"
-#include "kernel/rtlil.h"
-#include "kernel/log.h"
-
-USING_YOSYS_NAMESPACE
-PRIVATE_NAMESPACE_BEGIN
-
-struct SynthCoolrunner2Pass : public ScriptPass
-{
-       SynthCoolrunner2Pass() : ScriptPass("synth_coolrunner2", "synthesis for Xilinx Coolrunner-II CPLDs") { }
-
-       virtual void help() YS_OVERRIDE
-       {
-               //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
-               log("\n");
-               log("    synth_coolrunner2 [options]\n");
-               log("\n");
-               log("This command runs synthesis for Coolrunner-II CPLDs. This work is experimental.\n");
-               log("It is intended to be used with https://github.com/azonenberg/openfpga as the\n");
-               log("place-and-route.\n");
-               log("\n");
-               log("    -top <module>\n");
-               log("        use the specified module as top module (default='top')\n");
-               log("\n");
-               log("    -json <file>\n");
-               log("        write the design to the specified JSON file. writing of an output file\n");
-               log("        is omitted if this parameter is not specified.\n");
-               log("\n");
-               log("    -run <from_label>:<to_label>\n");
-               log("        only run the commands between the labels (see below). an empty\n");
-               log("        from label is synonymous to 'begin', and empty to label is\n");
-               log("        synonymous to the end of the command list.\n");
-               log("\n");
-               log("    -noflatten\n");
-               log("        do not flatten design before synthesis\n");
-               log("\n");
-               log("    -retime\n");
-               log("        run 'abc' with -dff option\n");
-               log("\n");
-               log("\n");
-               log("The following commands are executed by this synthesis command:\n");
-               help_script();
-               log("\n");
-       }
-
-       string top_opt, json_file;
-       bool flatten, retime;
-
-       virtual void clear_flags() YS_OVERRIDE
-       {
-               top_opt = "-auto-top";
-               json_file = "";
-               flatten = true;
-               retime = false;
-       }
-
-       virtual void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
-       {
-               string run_from, run_to;
-               clear_flags();
-
-               size_t argidx;
-               for (argidx = 1; argidx < args.size(); argidx++)
-               {
-                       if (args[argidx] == "-top" && argidx+1 < args.size()) {
-                               top_opt = "-top " + args[++argidx];
-                               continue;
-                       }
-                       if (args[argidx] == "-json" && argidx+1 < args.size()) {
-                               json_file = args[++argidx];
-                               continue;
-                       }
-                       if (args[argidx] == "-run" && argidx+1 < args.size()) {
-                               size_t pos = args[argidx+1].find(':');
-                               if (pos == std::string::npos)
-                                       break;
-                               run_from = args[++argidx].substr(0, pos);
-                               run_to = args[argidx].substr(pos+1);
-                               continue;
-                       }
-                       if (args[argidx] == "-noflatten") {
-                               flatten = false;
-                               continue;
-                       }
-                       if (args[argidx] == "-retime") {
-                               retime = true;
-                               continue;
-                       }
-                       break;
-               }
-               extra_args(args, argidx, design);
-
-               if (!design->full_selection())
-                       log_cmd_error("This comannd only operates on fully selected designs!\n");
-
-               log_header(design, "Executing SYNTH_COOLRUNNER2 pass.\n");
-               log_push();
-
-               run_script(design, run_from, run_to);
-
-               log_pop();
-       }
-
-       virtual void script() YS_OVERRIDE
-       {
-               if (check_label("begin"))
-               {
-                       run("read_verilog -lib +/coolrunner2/cells_sim.v");
-                       run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
-               }
-
-               if (flatten && check_label("flatten", "(unless -noflatten)"))
-               {
-                       run("proc");
-                       run("flatten");
-                       run("tribuf -logic");
-               }
-
-               if (check_label("coarse"))
-               {
-                       run("synth -run coarse");
-               }
-
-               if (check_label("fine"))
-               {
-                       run("opt -fast -full");
-                       run("techmap");
-                       run("techmap -map +/coolrunner2/cells_latch.v");
-                       run("dfflibmap -prepare -liberty +/coolrunner2/xc2_dff.lib");
-               }
-
-               if (check_label("map_pla"))
-               {
-                       run("abc -sop -I 40 -P 56");
-                       run("coolrunner2_sop");
-                       run("opt -fast");
-               }
-
-               if (check_label("map_cells"))
-               {
-                       run("dfflibmap -liberty +/coolrunner2/xc2_dff.lib");
-                       run("dffinit -ff FDCP Q INIT");
-                       run("dffinit -ff FDCP_N Q INIT");
-                       run("dffinit -ff LDCP Q INIT");
-                       run("dffinit -ff LDCP_N Q INIT");
-                       run("iopadmap -bits -inpad IBUF O:I -outpad IOBUFE I:IO -inoutpad IOBUFE O:IO -toutpad IOBUFE E:I:IO -tinoutpad IOBUFE E:O:I:IO");
-               }
-
-               if (check_label("check"))
-               {
-                       run("hierarchy -check");
-                       run("stat");
-                       run("check -noinit");
-               }
-
-               if (check_label("json"))
-               {
-                       if (!json_file.empty() || help_mode)
-                               run(stringf("write_json %s", help_mode ? "<file-name>" : json_file.c_str()));
-               }
-
-               log_pop();
-       }
-} SynthCoolrunner2Pass;
-
-PRIVATE_NAMESPACE_END