diff options
Diffstat (limited to 'passes/pmgen/xilinx_srl.pmg')
-rw-r--r-- | passes/pmgen/xilinx_srl.pmg | 66 |
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 |