From a945f6c7ef43258504f8c9c5a9c2d2e03fbfe0fe Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 6 Sep 2019 11:58:56 -0700 Subject: [PATCH] Fix ffPmux to cope with offset --- passes/pmgen/xilinx_dsp.pmg | 46 +++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/passes/pmgen/xilinx_dsp.pmg b/passes/pmgen/xilinx_dsp.pmg index a9e2ebf86..58ffcfedf 100644 --- a/passes/pmgen/xilinx_dsp.pmg +++ b/passes/pmgen/xilinx_dsp.pmg @@ -4,6 +4,7 @@ state clock state sigA sigffAmuxY sigB sigffBmuxY sigC sigM sigP state postAddAB postAddMuxAB state ffAenpol ffBenpol ffMenpol ffPenpol +state ffPoffset match dsp select dsp->type.in(\DSP48E1) @@ -139,6 +140,8 @@ match ffBmux endmatch match ffMmux + if param(dsp, \MREG).as_int() == 0 + if nusers(sigM) == 2 select ffMmux->type.in($mux) choice BA {\B, \A} // new-value net must have exactly two users: dsp and ffM @@ -164,6 +167,7 @@ endcode match ffM if param(dsp, \MREG).as_int() == 0 + if nusers(sigM) == 2 select ffM->type.in($dff) // DSP48E1 does not support clock inversion select param(ffM, \CLK_POLARITY).as_bool() @@ -235,31 +239,47 @@ endcode match ffPmux if param(dsp, \PREG).as_int() == 0 + // new-value net must have exactly two users: dsp and ffP if nusers(sigP) == 2 select ffPmux->type.in($mux) + // ffPmux output must have two users: ffPmux and ffP.D + select nusers(port(ffPmux, \Y)) == 2 + filter GetSize(port(ffPmux, \Y)) >= GetSize(sigP) + choice BA {\B, \A} - // new-value net must have exactly two users: dsp and ffP - select nusers(port(ffPmux, BA)) == 2 + slice offset GetSize(port(ffPmux, \Y)) + filter offset+GetSize(sigP) <= GetSize(port(ffPmux, \Y)) + filter port(ffPmux, BA).extract(offset, GetSize(sigP)) == sigP + define AB (BA == \B ? \A : \B) // keep-last-value net must have at least three users: ffPmux, ffP, downstream sink(s) - select nusers(port(ffPmux, AB)) >= 3 - // ffPmux output must have two users: ffPmux and ffP.D - select nusers(port(ffPmux, \Y)) == 2 - filter GetSize(port(ffPmux, \Y)) <= GetSize(sigP) - filter port(ffPmux, BA) == sigP.extract(0, GetSize(port(ffPmux, \Y))) - // Remaining bits on sigP must not have any other users - filter nusers(sigP.extract_end(GetSize(port(ffPmux, BA)))) <= 1 + filter nusers(port(ffPmux, AB)) >= 3 define pol (BA == \B) set ffPenpol pol + set ffPoffset offset optional endmatch code sigP if (ffPmux) - sigP.replace(port(ffPmux, ffPenpol ? \A : \B), port(ffPmux, \Y)); + sigP.replace(port(ffPmux, ffPenpol ? \B : \A), port(ffPmux, \Y)); endcode +match ffP_enable + if ffPmux + if nusers(sigP) == 2 + select ffP_enable->type.in($dff) + // DSP48E1 does not support clock inversion + select param(ffP_enable, \CLK_POLARITY).as_bool() + index port(ffP_enable, \D) === port(ffPmux, \Y) + index port(ffP_enable, \Q) === port(ffPmux, ffPenpol ? \A : \B) + filter GetSize(port(ffP_enable, \D)) >= GetSize(sigP) + filter ffPoffset+GetSize(sigP) <= GetSize(port(ffP_enable, \D)) + filter port(ffP_enable, \D).extract(ffPoffset, GetSize(sigP)) == sigP +endmatch + match ffP + if !ffP_enable if param(dsp, \PREG).as_int() == 0 if nusers(sigP) == 2 select ffP->type.in($dff) @@ -269,12 +289,14 @@ match ffP slice offset GetSize(port(ffP, \D)) filter offset+GetSize(sigP) <= GetSize(port(ffP, \D)) filter port(ffP, \D).extract(offset, GetSize(sigP)) == sigP - // Check ffPmux (when present) is a $dff enable mux - filter !ffPmux || port(ffP, \Q) == port(ffPmux, ffPenpol ? \A : \B) optional endmatch code ffP sigP clock + if (ffP_enable) { + log_assert(!ffP); + ffP = ffP_enable; + } if (ffP) { for (auto b : port(ffP, \Q)) if (b.wire->get_bool_attribute(\keep)) -- 2.30.2