Add "peepopt" skeleton
authorClifford Wolf <clifford@clifford.at>
Mon, 29 Apr 2019 11:38:56 +0000 (13:38 +0200)
committerClifford Wolf <clifford@clifford.at>
Mon, 29 Apr 2019 11:38:56 +0000 (13:38 +0200)
Signed-off-by: Clifford Wolf <clifford@clifford.at>
passes/pmgen/.gitignore
passes/pmgen/Makefile.inc
passes/pmgen/peepopt.cc [new file with mode: 0644]
passes/pmgen/peepopt.pmg [new file with mode: 0644]
passes/pmgen/pmgen.py

index c9263057e5c5d004ab0df7d834fb78ca5ae04083..0ad36ea2c979b35816f2d871b54bc1bb4be8bb5f 100644 (file)
@@ -1 +1,2 @@
 /ice40_dsp_pm.h
+/peepopt_pm.h
index e0609d9ba368e1f76e0092bbb0cd60ff63ff4927..b8a14df903fb4037c103476bfdffaccfe03143fc 100644 (file)
@@ -1,8 +1,20 @@
 OBJS += passes/pmgen/ice40_dsp.o
+OBJS += passes/pmgen/peepopt.o
+
+# --------------------------------------
 
 passes/pmgen/ice40_dsp.o: passes/pmgen/ice40_dsp_pm.h
 EXTRA_OBJS += passes/pmgen/ice40_dsp_pm.h
 .SECONDARY: passes/pmgen/ice40_dsp_pm.h
 
 passes/pmgen/ice40_dsp_pm.h: passes/pmgen/pmgen.py passes/pmgen/ice40_dsp.pmg
-       $(P) mkdir -p passes/pmgen && python3 $^ $@
+       $(P) mkdir -p passes/pmgen && python3 $< -o $@ -p ice40_dsp $(filter-out $<,$^)
+
+# --------------------------------------
+
+passes/pmgen/peepopt.o: passes/pmgen/peepopt_pm.h
+EXTRA_OBJS += passes/pmgen/peepopt_pm.h
+.SECONDARY: passes/pmgen/peepopt_pm.h
+
+passes/pmgen/peepopt_pm.h: passes/pmgen/pmgen.py passes/pmgen/peepopt.pmg
+       $(P) mkdir -p passes/pmgen && python3 $< -o $@ -p peepopt $(filter-out $<,$^)
diff --git a/passes/pmgen/peepopt.cc b/passes/pmgen/peepopt.cc
new file mode 100644 (file)
index 0000000..e9aa8e3
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ *  yosys -- Yosys Open SYnthesis Suite
+ *
+ *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
+ *
+ *  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"
+#include "passes/pmgen/peepopt_pm.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct PeepoptPass : public Pass {
+       PeepoptPass() : Pass("peepopt", "collection of peephole optimizers") { }
+       void help() YS_OVERRIDE
+       {
+               //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+               log("\n");
+               log("    peepopt [options] [selection]\n");
+               log("\n");
+               log("This pass applies a collection of peephole optimizers to the current design.\n");
+               log("\n");
+       }
+       void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+       {
+               log_header(design, "Executing PEEOPOPT pass (run peephole optimizers).\n");
+
+               size_t argidx;
+               for (argidx = 1; argidx < args.size(); argidx++)
+               {
+                       // if (args[argidx] == "-singleton") {
+                       //      singleton_mode = true;
+                       //      continue;
+                       // }
+                       break;
+               }
+               extra_args(args, argidx, design);
+
+               for (auto module : design->selected_modules()) {
+                       peepopt_pm pm(module, module->selected_cells());
+                       pm.run_shiftmul();
+               }
+       }
+} PeepoptPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/passes/pmgen/peepopt.pmg b/passes/pmgen/peepopt.pmg
new file mode 100644 (file)
index 0000000..0a56016
--- /dev/null
@@ -0,0 +1,34 @@
+pattern shiftmul
+
+state <SigSpec> shamt
+
+match shift
+       select shift->type.in($shift, $shiftx, $shr)
+endmatch
+
+code shamt
+       shamt = port(shift, \B);
+       if (shamt[GetSize(shamt)-1] == State::S0) {
+               do {
+                       shamt.remove(GetSize(shamt)-1);
+               } while (shamt[GetSize(shamt)-1] == State::S0);
+       } else
+       if (param(shift, \B_SIGNED).as_bool()) {
+               reject;
+       }
+endcode
+
+match mul
+       select mul->type.in($mul)
+       select port(mul, \A).is_fully_const() || port(mul, \B).is_fully_const()
+       index <SigSpec> port(mul, \Y) === shamt
+endmatch
+
+code
+       IdString const_factor_port = port(mul, \A).is_fully_const() ? \A : \B;
+       int const_factor = port(mul, const_factor_port).as_int();
+       if (GetSize(port(shift, \Y)) > const_factor)
+               reject;
+       log_dump(shift, shamt, mul, const_factor);
+       reject;
+endcode
index bb4c9d66bc32e7a66705fc48b65c915315e6dcc1..24ad0735977012d02d328737c03573c162df90ca 100644 (file)
@@ -420,6 +420,10 @@ with open(outfile, "w") as f:
         print("    run_{}([&](){{on_accept_f(st_{});}});".format(current_pattern, current_pattern), file=f)
         print("  }", file=f)
         print("", file=f)
+        print("  void run_{}() {{".format(current_pattern), file=f)
+        print("    run_{}([](){{}});".format(current_pattern, current_pattern), file=f)
+        print("  }", file=f)
+        print("", file=f)
     current_pattern = None
 
     for index in range(len(blocks)):