Added ScriptPass helper class for script-like passes
authorClifford Wolf <clifford@clifford.at>
Thu, 31 Mar 2016 09:16:34 +0000 (11:16 +0200)
committerClifford Wolf <clifford@clifford.at>
Thu, 31 Mar 2016 09:16:34 +0000 (11:16 +0200)
kernel/register.cc
kernel/register.h
kernel/yosys.cc
techlibs/common/synth.cc
techlibs/ice40/synth_ice40.cc

index 49a67324dc337ae812151d4ed8601c37cdd170b6..ebe3055ac4fb5af01afe20b3c5c0743acdda0dcc 100644 (file)
@@ -80,6 +80,7 @@ Pass::pre_post_exec_state_t Pass::pre_execute()
        state.begin_ns = PerformanceTimer::query();
        state.parent_pass = current_pass;
        current_pass = this;
+       clear_flags();
        return state;
 }
 
@@ -99,6 +100,10 @@ void Pass::help()
        log("\n");
 }
 
+void Pass::clear_flags()
+{
+}
+
 void Pass::cmd_log_args(const std::vector<std::string> &args)
 {
        if (args.size() <= 1)
@@ -282,6 +287,60 @@ void Pass::call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::vec
        design->selected_active_module = backup_selected_active_module;
 }
 
+bool ScriptPass::check_label(std::string label, std::string info)
+{
+       if (active_design == nullptr) {
+               log("\n");
+               if (info.empty())
+                       log("    %s:\n", label.c_str());
+               else
+                       log("    %s:    %s\n", label.c_str(), info.c_str());
+               return true;
+       } else {
+               if (!active_run_from.empty() && active_run_from == active_run_to) {
+                       block_active = (label == active_run_from);
+               } else {
+                       if (label == active_run_from)
+                               block_active = true;
+                       if (label == active_run_to)
+                               block_active = false;
+               }
+               return block_active;
+       }
+}
+
+void ScriptPass::run(std::string command, std::string info)
+{
+       if (active_design == nullptr) {
+               if (info.empty())
+                       log("        %s\n", command.c_str());
+               else
+                       log("        %s    %s\n", command.c_str(), info.c_str());
+       } else
+               Pass::call(active_design, command);
+}
+
+void ScriptPass::run_script(RTLIL::Design *design, std::string run_from, std::string run_to)
+{
+       help_mode = false;
+       active_design = design;
+       block_active = run_from.empty();
+       active_run_from = run_from;
+       active_run_to = run_to;
+       script();
+}
+
+void ScriptPass::help_script()
+{
+       clear_flags();
+       help_mode = true;
+       active_design = nullptr;
+       block_active = true;
+       active_run_from.clear();
+       active_run_to.clear();
+       script();
+}
+
 Frontend::Frontend(std::string name, std::string short_help) :
                Pass(name.rfind("=", 0) == 0 ? name.substr(1) : "read_" + name, short_help),
                frontend_name(name.rfind("=", 0) == 0 ? name.substr(1) : name)
index 0ef07b7603a98a508edb06be9893056c4b0577bd..8024c56a0362d5a47f44659c2e152512a420815d 100644 (file)
@@ -31,6 +31,7 @@ struct Pass
        virtual ~Pass();
 
        virtual void help();
+       virtual void clear_flags();
        virtual void execute(std::vector<std::string> args, RTLIL::Design *design) = 0;
 
        int call_counter;
@@ -63,6 +64,22 @@ struct Pass
        static void done_register();
 };
 
+struct ScriptPass : Pass
+{
+       bool block_active, help_mode;
+       RTLIL::Design *active_design;
+       std::string active_run_from, active_run_to;
+
+       ScriptPass(std::string name, std::string short_help = "** document me **") : Pass(name, short_help) { }
+
+       virtual void script() = 0;
+
+       bool check_label(std::string label, std::string info = std::string());
+       void run(std::string command, std::string info = std::string());
+       void run_script(RTLIL::Design *design, std::string run_from = std::string(), std::string run_to = std::string());
+       void help_script();
+};
+
 struct Frontend : Pass
 {
        // for reading of here documents
index 501d942244456a397c42bd33cfe3a808c258ae43..8da57fd4e9f7aea91e7b3e297c1485ffda4cd66b 100644 (file)
@@ -1100,8 +1100,8 @@ struct HistoryPass : public Pass {
 } HistoryPass;
 #endif
 
-struct ScriptPass : public Pass {
-       ScriptPass() : Pass("script", "execute commands from script file") { }
+struct ScriptCmdPass : public Pass {
+       ScriptCmdPass() : Pass("script", "execute commands from script file") { }
        virtual void help() {
                log("\n");
                log("    script <filename> [<from_label>:<to_label>]\n");
@@ -1127,7 +1127,7 @@ struct ScriptPass : public Pass {
                else
                        extra_args(args, 2, design, false);
        }
-} ScriptPass;
+} ScriptCmdPass;
 
 YOSYS_NAMESPACE_END
 
index c837e1378e488f56e921a4967bc2926a60176c41..8eb1aeba4d06d22fb85f634bc38073d556ca94c1 100644 (file)
 USING_YOSYS_NAMESPACE
 PRIVATE_NAMESPACE_BEGIN
 
-bool check_label(bool &active, std::string run_from, std::string run_to, std::string label)
+struct SynthPass : public ScriptPass
 {
-       if (!run_from.empty() && run_from == run_to) {
-               active = (label == run_from);
-       } else {
-               if (label == run_from)
-                       active = true;
-               if (label == run_to)
-                       active = false;
-       }
-       return active;
-}
+       SynthPass() : ScriptPass("synth", "generic synthesis script") { }
 
-struct SynthPass : public Pass {
-       SynthPass() : Pass("synth", "generic synthesis script") { }
-       virtual void help()
+       virtual void help() YS_OVERRIDE
        {
                //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
                log("\n");
@@ -75,49 +64,28 @@ struct SynthPass : public Pass {
                log("\n");
                log("\n");
                log("The following commands are executed by this synthesis command:\n");
+               help_script();
                log("\n");
-               log("    begin:\n");
-               log("        hierarchy -check [-top <top>]\n");
-               log("\n");
-               log("    coarse:\n");
-               log("        proc\n");
-               log("        opt_expr\n");
-               log("        opt_clean\n");
-               log("        check\n");
-               log("        opt\n");
-               log("        wreduce\n");
-               log("        alumacc\n");
-               log("        share\n");
-               log("        opt\n");
-               log("        fsm\n");
-               log("        opt -fast\n");
-               log("        memory -nomap\n");
-               log("        opt_clean\n");
-               log("\n");
-               log("    fine:\n");
-               log("        opt -fast -full\n");
-               log("        memory_map\n");
-               log("        opt -full\n");
-               log("        techmap\n");
-               log("        opt -fast\n");
-       #ifdef YOSYS_ENABLE_ABC
-               log("        abc -fast\n");
-               log("        opt -fast\n");
-       #endif
-               log("\n");
-               log("    check:\n");
-               log("        hierarchy -check\n");
-               log("        stat\n");
-               log("        check\n");
-               log("\n");
        }
-       virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+
+       std::string top_module, fsm_opts, memory_opts;
+       bool noalumacc, nofsm, noabc;
+
+       virtual void clear_flags() YS_OVERRIDE
+       {
+               top_module.clear();
+               fsm_opts.clear();
+               memory_opts.clear();
+
+               noalumacc = false;
+               nofsm = false;
+               noabc = false;
+       }
+
+       virtual void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
        {
-               std::string top_module, fsm_opts, memory_opts;
-               std::string run_from, run_to;
-               bool noalumacc = false;
-               bool nofsm = false;
-               bool noabc = false;
+               string run_from, run_to;
+               clear_flags();
 
                size_t argidx;
                for (argidx = 1; argidx < args.size(); argidx++)
@@ -164,62 +132,69 @@ struct SynthPass : public Pass {
                if (!design->full_selection())
                        log_cmd_error("This comannd only operates on fully selected designs!\n");
 
-               bool active = run_from.empty();
-
                log_header("Executing SYNTH pass.\n");
                log_push();
 
-               if (check_label(active, run_from, run_to, "begin"))
+               run_script(design, run_from, run_to);
+
+               log_pop();
+       }
+
+       virtual void script() YS_OVERRIDE
+       {
+               if (check_label("begin"))
                {
-                       if (top_module.empty())
-                               Pass::call(design, stringf("hierarchy -check"));
-                       else
-                               Pass::call(design, stringf("hierarchy -check -top %s", top_module.c_str()));
+                       if (help_mode) {
+                               run("hierarchy -check [-top <top>]");
+                       } else {
+                               if (top_module.empty())
+                                       run(stringf("hierarchy -check"));
+                               else
+                                       run(stringf("hierarchy -check -top %s", top_module.c_str()));
+                       }
                }
 
-               if (check_label(active, run_from, run_to, "coarse"))
+               if (check_label("coarse"))
                {
-                       Pass::call(design, "proc");
-                       Pass::call(design, "opt_expr");
-                       Pass::call(design, "opt_clean");
-                       Pass::call(design, "check");
-                       Pass::call(design, "opt");
-                       Pass::call(design, "wreduce");
+                       run("proc");
+                       run("opt_expr");
+                       run("opt_clean");
+                       run("check");
+                       run("opt");
+                       run("wreduce");
                        if (!noalumacc)
-                               Pass::call(design, "alumacc");
-                       Pass::call(design, "share");
-                       Pass::call(design, "opt");
+                               run("alumacc");
+                       run("share");
+                       run("opt");
                        if (!nofsm)
-                               Pass::call(design, "fsm" + fsm_opts);
-                       Pass::call(design, "opt -fast");
-                       Pass::call(design, "memory -nomap" + memory_opts);
-                       Pass::call(design, "opt_clean");
+                               run("fsm" + fsm_opts);
+                       run("opt -fast");
+                       run("memory -nomap" + memory_opts);
+                       run("opt_clean");
                }
 
-               if (check_label(active, run_from, run_to, "fine"))
+               if (check_label("fine"))
                {
-                       Pass::call(design, "opt -fast -full");
-                       Pass::call(design, "memory_map");
-                       Pass::call(design, "opt -full");
-                       Pass::call(design, "techmap");
-                       Pass::call(design, "opt -fast");
+                       run("opt -fast -full");
+                       run("memory_map");
+                       run("opt -full");
+                       run("techmap");
+                       run("opt -fast");
 
                        if (!noabc) {
                #ifdef YOSYS_ENABLE_ABC
-                               Pass::call(design, "abc -fast");
-                               Pass::call(design, "opt -fast");
+                               run("abc -fast");
+                               run("opt -fast");
                #endif
                        }
                }
 
-               if (check_label(active, run_from, run_to, "check"))
+               if (check_label("check"))
                {
-                       Pass::call(design, "hierarchy -check");
-                       Pass::call(design, "stat");
-                       Pass::call(design, "check");
+                       run("hierarchy -check");
+                       run("stat");
+                       run("check");
                }
-
-               log_pop();
        }
 } SynthPass;
 
index f24d31a8c07f6a36c91f412bf341f3eaa22d12dd..2ed7642ae79e5db7241694016e890f3df3e3d81b 100644 (file)
 USING_YOSYS_NAMESPACE
 PRIVATE_NAMESPACE_BEGIN
 
-bool check_label(bool &active, std::string run_from, std::string run_to, std::string label)
+struct SynthIce40Pass : public ScriptPass
 {
-       if (label == run_from)
-               active = true;
-       if (label == run_to)
-               active = false;
-       return active;
-}
+       SynthIce40Pass() : ScriptPass("synth_ice40", "synthesis for iCE40 FPGAs") { }
 
-struct SynthIce40Pass : public Pass {
-       SynthIce40Pass() : Pass("synth_ice40", "synthesis for iCE40 FPGAs") { }
-       virtual void help()
+       virtual void help() YS_OVERRIDE
        {
                //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
                log("\n");
@@ -77,73 +70,30 @@ struct SynthIce40Pass : public Pass {
                log("\n");
                log("\n");
                log("The following commands are executed by this synthesis command:\n");
+               help_script();
                log("\n");
-               log("    begin:\n");
-               log("        read_verilog -lib +/ice40/cells_sim.v\n");
-               log("        hierarchy -check -top <top>\n");
-               log("\n");
-               log("    flatten:         (unless -noflatten)\n");
-               log("        proc\n");
-               log("        flatten\n");
-               log("        tribuf -logic\n");
-               log("\n");
-               log("    coarse:\n");
-               log("        synth -run coarse\n");
-               log("\n");
-               log("    bram:            (skip if -nobram)\n");
-               log("        memory_bram -rules +/ice40/brams.txt\n");
-               log("        techmap -map +/ice40/brams_map.v\n");
-               log("\n");
-               log("    fine:\n");
-               log("        opt -fast -mux_undef -undriven -fine\n");
-               log("        memory_map\n");
-               log("        opt -undriven -fine\n");
-               log("        techmap -map +/techmap.v [-map +/ice40/arith_map.v]\n");
-               log("        abc -dff     (only if -retime)\n");
-               log("        ice40_opt\n");
-               log("\n");
-               log("    map_ffs:\n");
-               log("        dffsr2dff\n");
-               log("        dff2dffe -direct-match $_DFF_*\n");
-               log("        techmap -map +/ice40/cells_map.v\n");
-               log("        opt_expr -mux_undef\n");
-               log("        simplemap\n");
-               log("        ice40_ffinit\n");
-               log("        ice40_ffssr\n");
-               log("        ice40_opt -full\n");
-               log("\n");
-               log("    map_luts:\n");
-               log("        abc          (only if -abc2)\n");
-               log("        ice40_opt    (only if -abc2)\n");
-               log("        abc -lut 4\n");
-               log("        clean\n");
-               log("\n");
-               log("    map_cells:\n");
-               log("        techmap -map +/ice40/cells_map.v\n");
-               log("        clean\n");
-               log("\n");
-               log("    check:\n");
-               log("        hierarchy -check\n");
-               log("        stat\n");
-               log("        check -noinit\n");
-               log("\n");
-               log("    blif:\n");
-               log("        write_blif -gates -attr -param <file-name>\n");
-               log("\n");
-               log("    edif:\n");
-               log("        write_edif <file-name>\n");
-               log("\n");
        }
-       virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+
+       string top_opt = "-auto-top";
+       string blif_file, edif_file;
+       bool nocarry, nobram, flatten, retime, abc2;
+
+       virtual void clear_flags() YS_OVERRIDE
+       {
+               top_opt = "-auto-top";
+               blif_file = "";
+               edif_file = "";
+               nocarry = false;
+               nobram = false;
+               flatten = true;
+               retime = false;
+               abc2 = false;
+       }
+
+       virtual void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
        {
-               std::string top_opt = "-auto-top";
                std::string run_from, run_to;
-               std::string blif_file, edif_file;
-               bool nocarry = false;
-               bool nobram = false;
-               bool flatten = true;
-               bool retime = false;
-               bool abc2 = false;
+               clear_flags();
 
                size_t argidx;
                for (argidx = 1; argidx < args.size(); argidx++)
@@ -199,97 +149,100 @@ struct SynthIce40Pass : public Pass {
                if (!design->full_selection())
                        log_cmd_error("This comannd only operates on fully selected designs!\n");
 
-               bool active = run_from.empty();
-
                log_header("Executing SYNTH_ICE40 pass.\n");
                log_push();
 
-               if (check_label(active, run_from, run_to, "begin"))
+               run_script(design, run_from, run_to);
+
+               log_pop();
+       }
+
+       virtual void script() YS_OVERRIDE
+       {
+               if (check_label("begin"))
                {
-                       Pass::call(design, "read_verilog -lib +/ice40/cells_sim.v");
-                       Pass::call(design, stringf("hierarchy -check %s", top_opt.c_str()));
+                       run("read_verilog -lib +/ice40/cells_sim.v");
+                       run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
                }
 
-               if (flatten && check_label(active, run_from, run_to, "flatten"))
+               if (flatten && check_label("flatten", "(unless -noflatten)"))
                {
-                       Pass::call(design, "proc");
-                       Pass::call(design, "flatten");
-                       Pass::call(design, "tribuf -logic");
+                       run("proc");
+                       run("flatten");
+                       run("tribuf -logic");
                }
 
-               if (check_label(active, run_from, run_to, "coarse"))
+               if (check_label("coarse"))
                {
-                       Pass::call(design, "synth -run coarse");
+                       run("synth -run coarse");
                }
 
-               if (!nobram && check_label(active, run_from, run_to, "bram"))
+               if (!nobram && check_label("bram", "(skip if -nobram)"))
                {
-                       Pass::call(design, "memory_bram -rules +/ice40/brams.txt");
-                       Pass::call(design, "techmap -map +/ice40/brams_map.v");
+                       run("memory_bram -rules +/ice40/brams.txt");
+                       run("techmap -map +/ice40/brams_map.v");
                }
 
-               if (check_label(active, run_from, run_to, "fine"))
+               if (check_label("fine"))
                {
-                       Pass::call(design, "opt -fast -mux_undef -undriven -fine");
-                       Pass::call(design, "memory_map");
-                       Pass::call(design, "opt -undriven -fine");
+                       run("opt -fast -mux_undef -undriven -fine");
+                       run("memory_map");
+                       run("opt -undriven -fine");
                        if (nocarry)
-                               Pass::call(design, "techmap");
+                               run("techmap");
                        else
-                               Pass::call(design, "techmap -map +/techmap.v -map +/ice40/arith_map.v");
-                       if (retime)
-                               Pass::call(design, "abc -dff");
-                       Pass::call(design, "ice40_opt");
+                               run("techmap -map +/techmap.v -map +/ice40/arith_map.v");
+                       if (retime || help_mode)
+                               run("abc -dff", "(only if -retime)");
+                       run("ice40_opt");
                }
 
-               if (check_label(active, run_from, run_to, "map_ffs"))
+               if (check_label("map_ffs"))
                {
-                       Pass::call(design, "dffsr2dff");
-                       Pass::call(design, "dff2dffe -direct-match $_DFF_*");
-                       Pass::call(design, "techmap -map +/ice40/cells_map.v");
-                       Pass::call(design, "opt_expr -mux_undef");
-                       Pass::call(design, "simplemap");
-                       Pass::call(design, "ice40_ffinit");
-                       Pass::call(design, "ice40_ffssr");
-                       Pass::call(design, "ice40_opt -full");
+                       run("dffsr2dff");
+                       run("dff2dffe -direct-match $_DFF_*");
+                       run("techmap -map +/ice40/cells_map.v");
+                       run("opt_expr -mux_undef");
+                       run("simplemap");
+                       run("ice40_ffinit");
+                       run("ice40_ffssr");
+                       run("ice40_opt -full");
                }
 
-               if (check_label(active, run_from, run_to, "map_luts"))
+               if (check_label("map_luts"))
                {
-                       if (abc2) {
-                               Pass::call(design, "abc");
-                               Pass::call(design, "ice40_opt");
+                       if (abc2 || help_mode) {
+                               run("abc", "      (only if -abc2)");
+                               run("ice40_opt", "(only if -abc2)");
                        }
-                       Pass::call(design, "abc -lut 4");
-                       Pass::call(design, "clean");
+                       run("abc -lut 4");
+                       run("clean");
                }
 
-               if (check_label(active, run_from, run_to, "map_cells"))
+               if (check_label("map_cells"))
                {
-                       Pass::call(design, "techmap -map +/ice40/cells_map.v");
-                       Pass::call(design, "clean");
+                       run("techmap -map +/ice40/cells_map.v");
+                       run("clean");
                }
 
-               if (check_label(active, run_from, run_to, "check"))
+               if (check_label("check"))
                {
-                       Pass::call(design, "hierarchy -check");
-                       Pass::call(design, "stat");
-                       Pass::call(design, "check -noinit");
+                       run("hierarchy -check");
+                       run("stat");
+                       run("check -noinit");
                }
 
-               if (check_label(active, run_from, run_to, "blif"))
+               if (check_label("blif"))
                {
-                       if (!blif_file.empty())
-                               Pass::call(design, stringf("write_blif -gates -attr -param %s", blif_file.c_str()));
+                       if (!blif_file.empty() || help_mode)
+                               run(stringf("write_blif -gates -attr -param %s", help_mode ? "<file-name>" : blif_file.c_str()));
                }
 
-               if (check_label(active, run_from, run_to, "edif"))
+               if (check_label("edif"))
                {
-                       if (!edif_file.empty())
-                               Pass::call(design, stringf("write_edif %s", edif_file.c_str()));
+                       if (!edif_file.empty() || help_mode)
+                               run(stringf("write_edif %s", help_mode ? "<file-name>" : edif_file.c_str()));
                }
-
-               log_pop();
        }
 } SynthIce40Pass;