aboutsummaryrefslogtreecommitdiffstats
path: root/passes/pmgen/test_pmgen.pmg
diff options
context:
space:
mode:
authorEddie Hung <eddie@fpgeh.com>2019-08-23 10:00:50 -0700
committerEddie Hung <eddie@fpgeh.com>2019-08-23 10:00:50 -0700
commit6872805a3eb738a0a5921b232022abfd507cebb8 (patch)
treeb871344e8f96cd30c5a6bc3f275476e30f792de0 /passes/pmgen/test_pmgen.pmg
parent6b51c154c6812f58676402ebbbdbb18d053ca4be (diff)
parentbb2d5bc4f85ac95104fbd2591ad92ebf0c22e11d (diff)
downloadyosys-6872805a3eb738a0a5921b232022abfd507cebb8.tar.gz
yosys-6872805a3eb738a0a5921b232022abfd507cebb8.tar.bz2
yosys-6872805a3eb738a0a5921b232022abfd507cebb8.zip
Merge remote-tracking branch 'origin/master' into mwk/xilinx_bufgmap
Diffstat (limited to 'passes/pmgen/test_pmgen.pmg')
-rw-r--r--passes/pmgen/test_pmgen.pmg106
1 files changed, 106 insertions, 0 deletions
diff --git a/passes/pmgen/test_pmgen.pmg b/passes/pmgen/test_pmgen.pmg
new file mode 100644
index 000000000..211477a62
--- /dev/null
+++ b/passes/pmgen/test_pmgen.pmg
@@ -0,0 +1,106 @@
+pattern reduce
+
+state <IdString> portname
+udata <vector<pair<Cell*, IdString>>> chain longest_chain
+udata <pool<Cell*>> non_first_cells
+udata <SigSpec> leaves
+
+code
+ non_first_cells.clear();
+ subpattern(setup);
+endcode
+
+match first
+ select first->type.in($_AND_, $_OR_, $_XOR_)
+ filter !non_first_cells.count(first)
+generate
+ SigSpec A = module->addWire(NEW_ID);
+ SigSpec B = module->addWire(NEW_ID);
+ SigSpec Y = module->addWire(NEW_ID);
+ switch (rng(3))
+ {
+ case 0:
+ module->addAndGate(NEW_ID, A, B, Y);
+ break;
+ case 1:
+ module->addOrGate(NEW_ID, A, B, Y);
+ break;
+ case 2:
+ module->addXorGate(NEW_ID, A, B, Y);
+ break;
+ }
+endmatch
+
+code
+ leaves = SigSpec();
+ longest_chain.clear();
+ chain.push_back(make_pair(first, \A));
+ subpattern(tail);
+ chain.back().second = \B;
+ subpattern(tail);
+finally
+ chain.pop_back();
+ log_assert(chain.empty());
+ if (GetSize(longest_chain) > 1)
+ accept;
+endcode
+
+// ------------------------------------------------------------------
+
+subpattern setup
+
+match first
+ select first->type.in($_AND_, $_OR_, $_XOR_)
+endmatch
+
+code portname
+ portname = \A;
+ branch;
+ portname = \B;
+endcode
+
+match next
+ select nusers(port(next, \Y)) == 2
+ select next->type.in($_AND_, $_OR_, $_XOR_)
+ index <IdString> next->type === first->type
+ index <SigSpec> port(next, \Y) === port(first, portname)
+endmatch
+
+code
+ non_first_cells.insert(next);
+endcode
+
+// ------------------------------------------------------------------
+
+subpattern tail
+arg first
+
+match next
+ semioptional
+ select nusers(port(next, \Y)) == 2
+ select next->type.in($_AND_, $_OR_, $_XOR_)
+ index <IdString> next->type === chain.back().first->type
+ index <SigSpec> port(next, \Y) === port(chain.back().first, chain.back().second)
+generate 10
+ SigSpec A = module->addWire(NEW_ID);
+ SigSpec B = module->addWire(NEW_ID);
+ SigSpec Y = port(chain.back().first, chain.back().second);
+ Cell *c = module->addAndGate(NEW_ID, A, B, Y);
+ c->type = chain.back().first->type;
+endmatch
+
+code
+ if (next) {
+ chain.push_back(make_pair(next, \A));
+ subpattern(tail);
+ chain.back().second = \B;
+ subpattern(tail);
+ } else {
+ if (GetSize(chain) > GetSize(longest_chain))
+ longest_chain = chain;
+ leaves.append(port(chain.back().first, chain.back().second));
+ }
+finally
+ if (next)
+ chain.pop_back();
+endcode