diff options
Diffstat (limited to 'passes/pmgen/pmgen.py')
-rw-r--r-- | passes/pmgen/pmgen.py | 57 |
1 files changed, 44 insertions, 13 deletions
diff --git a/passes/pmgen/pmgen.py b/passes/pmgen/pmgen.py index c6e9a9cbf..e252c52f5 100644 --- a/passes/pmgen/pmgen.py +++ b/passes/pmgen/pmgen.py @@ -186,6 +186,9 @@ def process_pmgfile(f, filename): block["src"] = "%s:%d" % (filename, linenr) block["pattern"] = (current_pattern, current_subpattern) + block["genargs"] = None + block["gencode"] = None + line = line.split() assert len(line) == 2 assert (line[1] not in state_types[current_pattern]) or (state_types[current_pattern][line[1]] == "Cell*") @@ -236,6 +239,19 @@ def process_pmgfile(f, filename): block["semioptional"] = True continue + if a[0] == "generate": + block["genargs"] = list([int(s) for s in a[1:]]) + block["gencode"] = list() + assert len(block["genargs"]) < 2 + while True: + linenr += 1 + l = f.readline() + assert l != "" + a = l.split() + if a[0] == "endmatch": break + block["gencode"].append(rewrite_cpp(l.rstrip())) + break + assert False if block["optional"]: @@ -310,7 +326,17 @@ with open(outfile, "w") as f: print("struct {}_pm {{".format(prefix), file=f) print(" Module *module;", file=f) print(" SigMap sigmap;", file=f) - print(" std::function<void()> on_accept;".format(prefix), file=f) + print(" std::function<void()> on_accept;", file=f) + print(" bool generate_mode;", file=f) + print("", file=f) + + print(" uint32_t rngseed;", file=f) + print(" int rng(unsigned int n) {", file=f) + print(" rngseed ^= rngseed << 13;", file=f) + print(" rngseed ^= rngseed >> 17;", file=f) + print(" rngseed ^= rngseed << 5;", file=f) + print(" return rngseed % n;", file=f) + print(" }", file=f) print("", file=f) for index in range(len(blocks)): @@ -415,7 +441,7 @@ with open(outfile, "w") as f: print("", file=f) print(" {}_pm(Module *module, const vector<Cell*> &cells) :".format(prefix), file=f) - print(" module(module), sigmap(module) {", file=f) + print(" module(module), sigmap(module), generate_mode(false), rngseed(12345678) {", file=f) for current_pattern in sorted(patterns.keys()): for s, t in sorted(udata_types[current_pattern].items()): if t.endswith("*"): @@ -469,17 +495,15 @@ with open(outfile, "w") as f: print(" run_{}([&](){{on_accept_f(*this);}});".format(current_pattern), file=f) print(" }", file=f) print("", file=f) - print(" void run_{}(std::function<void(state_{}_t&)> on_accept_f) {{".format(current_pattern, current_pattern), file=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) - for p, s in sorted(subpatterns.keys()): - print(" void block_subpattern_{}_{}() {{ block_{}(); }}".format(p, s, subpatterns[(p, s)]), file=f) + if len(subpatterns): + for p, s in sorted(subpatterns.keys()): + print(" void block_subpattern_{}_{}() {{ block_{}(); }}".format(p, s, subpatterns[(p, s)]), file=f) + print("", file=f) current_pattern = None current_subpattern = None @@ -611,8 +635,8 @@ with open(outfile, "w") as f: print(" std::get<{}>(key) = {};".format(field, entry[2]), file=f) print(" const vector<Cell*> &cells = index_{}[key];".format(index), file=f) - if block["semioptional"]: - print(" bool found_semioptional_match = false;", file=f) + if block["semioptional"] or block["genargs"] is not None: + print(" bool found_any_match = false;", file=f) print("", file=f) print(" for (int idx = 0; idx < GetSize(cells); idx++) {", file=f) @@ -620,8 +644,8 @@ with open(outfile, "w") as f: print(" if (blacklist_cells.count({})) continue;".format(block["cell"]), file=f) for expr in block["filter"]: print(" if (!({})) continue;".format(expr), file=f) - if block["semioptional"]: - print(" found_semioptional_match = true;", file=f) + if block["semioptional"] or block["genargs"] is not None: + print(" found_any_match = true;", file=f) print(" block_{}();".format(index+1), file=f) print(" if (rollback) {", file=f) print(" if (rollback != {}) {{".format(index+1), file=f) @@ -639,10 +663,17 @@ with open(outfile, "w") as f: print(" block_{}();".format(index+1), file=f) if block["semioptional"]: - print(" if (!found_semioptional_match) block_{}();".format(index+1), file=f) + print(" if (!found_any_match) block_{}();".format(index+1), file=f) print(" {} = backup_{};".format(block["cell"], block["cell"]), file=f) + if block["genargs"] is not None: + print(" if (generate_mode && !found_any_match) {", file=f) + if len(block["genargs"]) == 1: + print(" if (rng(100) >= {}) return;".format(block["genargs"][0]), file=f) + for line in block["gencode"]: + print(" " + line, file=f) + print(" }", file=f) else: assert False |