aboutsummaryrefslogtreecommitdiffstats
path: root/passes/pmgen/xilinx_srl.pmg
diff options
context:
space:
mode:
Diffstat (limited to 'passes/pmgen/xilinx_srl.pmg')
-rw-r--r--passes/pmgen/xilinx_srl.pmg66
1 files changed, 64 insertions, 2 deletions
diff --git a/passes/pmgen/xilinx_srl.pmg b/passes/pmgen/xilinx_srl.pmg
index e7086c424..3f4efebe9 100644
--- a/passes/pmgen/xilinx_srl.pmg
+++ b/passes/pmgen/xilinx_srl.pmg
@@ -76,7 +76,7 @@ match next
select !port(next, \D)[0].wire->get_bool_attribute(\keep)
select nusers(port(next, \Q)) == 2
index <IdString> next->type === first->type
- index <SigSpec> port(next, \Q) === port(first, \D)
+ index <SigBit> port(next, \Q) === port(first, \D)
endmatch
code
@@ -109,7 +109,7 @@ match next
select !port(next, \D)[0].wire->get_bool_attribute(\keep)
select nusers(port(next, \Q)) == 2
index <IdString> next->type === chain.back()->type
- index <SigSpec> port(next, \Q) === port(chain.back(), \D)
+ index <SigBit> port(next, \Q) === port(chain.back(), \D)
//generate 10
// SigSpec A = module->addWire(NEW_ID);
// SigSpec B = module->addWire(NEW_ID);
@@ -145,3 +145,65 @@ finally
if (next)
chain.pop_back();
endcode
+
+// -----------
+
+pattern variable
+
+state <int> shiftx_width
+udata <int> minlen
+udata <pool<SigBit>> output_bits
+udata <vector<Cell*>> chain
+
+match shiftx
+ select shiftx->type.in($shiftx)
+ select !shiftx->has_keep_attr()
+ select param(shiftx, \Y_WIDTH) == 1
+ filter param(shiftx, \A_WIDTH).as_int() >= minlen
+endmatch
+
+code shiftx_width
+ shiftx_width = param(shiftx, \A_WIDTH).as_int();
+endcode
+
+match first
+ select first->type.in($_DFF_N_, $_DFF_P_, $_DFFE_NN_, $_DFFE_NP_, $_DFFE_PN_, $_DFFE_PP_)
+ select nusers(port(first, \Q)) == 2
+ index <SigBit> port(first, \Q) === port(shiftx, \A)[shiftx_width-1]
+ filter !output_bits.count(port(first, \Q))
+endmatch
+
+code
+ chain.push_back(first);
+ subpattern(tail);
+finally
+ if (GetSize(chain) == param(shiftx, \A_WIDTH).as_int())
+ accept;
+ chain.clear();
+endcode
+
+// ------------------------------------------------------------------
+
+subpattern tail
+arg shiftx
+arg shiftx_width
+
+match next
+ semioptional
+ select next->type.in($_DFF_N_, $_DFF_P_, $_DFFE_NN_, $_DFFE_NP_, $_DFFE_PN_, $_DFFE_PP_)
+ select !next->has_keep_attr()
+ select !port(next, \D)[0].wire->get_bool_attribute(\keep)
+ select nusers(port(next, \Q)) == 3
+ filter !output_bits.count(port(next, \Q))
+ index <IdString> next->type === chain.back()->type
+ index <SigBit> port(next, \Q) === port(chain.back(), \D)
+ index <SigBit> port(next, \Q) === port(shiftx, \A)[shiftx_width-1-GetSize(chain)]
+endmatch
+
+code
+ if (next) {
+ chain.push_back(next);
+ if (GetSize(chain) < shiftx_width)
+ subpattern(tail);
+ }
+endcode