/ice40_dsp_pm.h
+/peepopt_pm.h
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 $<,$^)
--- /dev/null
+/*
+ * 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
--- /dev/null
+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
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)):