More nusers() checks for A and B enable muxes

This commit is contained in:
Eddie Hung 2019-09-06 09:47:32 -07:00
parent dc10559f31
commit 4fe24b20f9
1 changed files with 27 additions and 14 deletions

View File

@ -1,7 +1,7 @@
pattern xilinx_dsp pattern xilinx_dsp
state <SigBit> clock state <SigBit> clock
state <SigSpec> sigA sigffAmux sigB sigffBmux sigC sigM sigP state <SigSpec> sigA sigffAmuxY sigB sigffBmuxY sigC sigM sigP
state <IdString> postAddAB postAddMuxAB state <IdString> postAddAB postAddMuxAB
state <bool> ffAenpol ffBenpol ffMenpol ffPenpol state <bool> ffAenpol ffBenpol ffMenpol ffPenpol
@ -9,7 +9,7 @@ match dsp
select dsp->type.in(\DSP48E1) select dsp->type.in(\DSP48E1)
endmatch endmatch
code sigA sigffAmux sigB sigffBmux sigM code sigA sigffAmuxY sigB sigffBmuxY sigM
sigA = port(dsp, \A); sigA = port(dsp, \A);
int i; int i;
for (i = GetSize(sigA)-1; i > 0; i--) for (i = GetSize(sigA)-1; i > 0; i--)
@ -38,6 +38,9 @@ code sigA sigffAmux sigB sigffBmux sigM
log_assert(nusers(P.extract_end(i)) <= 1); log_assert(nusers(P.extract_end(i)) <= 1);
//if (GetSize(sigM) <= 10) //if (GetSize(sigM) <= 10)
// reject; // reject;
sigffAmuxY = SigSpec();
sigffBmuxY = SigSpec();
endcode endcode
match ffA match ffA
@ -51,7 +54,7 @@ match ffA
optional optional
endmatch endmatch
code sigA sigffAmux clock code sigA sigffAmuxY clock
if (ffA) { if (ffA) {
for (auto b : port(ffA, \Q)) for (auto b : port(ffA, \Q))
if (b.wire->get_bool_attribute(\keep)) if (b.wire->get_bool_attribute(\keep))
@ -59,19 +62,25 @@ code sigA sigffAmux clock
clock = port(ffA, \CLK).as_bit(); clock = port(ffA, \CLK).as_bit();
sigffAmux = sigA; SigSpec A = sigA;
sigA.replace(port(ffA, \Q), port(ffA, \D)); A.replace(port(ffA, \Q), port(ffA, \D));
// Only search for ffAmux if ffA.Q has at
// least 3 users (ffA, dsp, ffAmux) and
// its ffA.D only has two (ffA, ffAmux)
if (nusers(sigA) >= 3 && nusers(A) == 2)
sigffAmuxY = sigA;
sigA = std::move(A);
} }
endcode endcode
match ffAmux match ffAmux
if ffA if !sigffAmuxY.empty()
select ffAmux->type.in($mux) select ffAmux->type.in($mux)
filter GetSize(port(ffAmux, \Y)) >= GetSize(sigA) filter GetSize(port(ffAmux, \Y)) >= GetSize(sigA)
slice offset GetSize(port(ffAmux, \Y)) slice offset GetSize(port(ffAmux, \Y))
filter offset+GetSize(sigA) <= GetSize(port(ffAmux, \Y)) && port(ffAmux, \Y).extract(offset, GetSize(sigA)) == sigA filter offset+GetSize(sigA) <= GetSize(port(ffAmux, \Y)) && port(ffAmux, \Y).extract(offset, GetSize(sigA)) == sigA
choice <IdString> BA {\B, \A} choice <IdString> BA {\B, \A}
filter offset+GetSize(sigffAmux) <= GetSize(port(ffAmux, \Y)) && port(ffAmux, BA).extract(offset, GetSize(sigffAmux)) == sigffAmux filter offset+GetSize(sigffAmuxY) <= GetSize(port(ffAmux, \Y)) && port(ffAmux, BA).extract(offset, GetSize(sigffAmuxY)) == sigffAmuxY
define <bool> pol (BA == \B) define <bool> pol (BA == \B)
set ffAenpol pol set ffAenpol pol
semioptional semioptional
@ -88,32 +97,36 @@ match ffB
optional optional
endmatch endmatch
code sigB sigffBmux clock code sigB sigffBmuxY clock
if (ffB) { if (ffB) {
for (auto b : port(ffB, \Q)) for (auto b : port(ffB, \Q))
if (b.wire->get_bool_attribute(\keep)) if (b.wire->get_bool_attribute(\keep))
reject; reject;
SigBit c = port(ffB, \CLK).as_bit(); SigBit c = port(ffB, \CLK).as_bit();
if (clock != SigBit() && c != clock) if (clock != SigBit() && c != clock)
reject; reject;
clock = c; clock = c;
sigffBmux = sigB; SigSpec B = sigB;
sigB.replace(port(ffB, \Q), port(ffB, \D)); B.replace(port(ffB, \Q), port(ffB, \D));
// Only search for ffBmux if ffB.Q has at
// least 3 users (ffB, dsp, ffBmux) and
// its ffB.D only has two (ffB, ffBmux)
if (nusers(sigB) >= 3 && nusers(B) == 2)
sigffBmuxY = sigB;
sigB = std::move(B);
} }
endcode endcode
match ffBmux match ffBmux
if ffB if !sigffBmuxY.empty()
select ffBmux->type.in($mux) select ffBmux->type.in($mux)
filter GetSize(port(ffBmux, \Y)) >= GetSize(sigB) filter GetSize(port(ffBmux, \Y)) >= GetSize(sigB)
slice offset GetSize(port(ffBmux, \Y)) slice offset GetSize(port(ffBmux, \Y))
filter offset+GetSize(sigB) <= GetSize(port(ffBmux, \Y)) && port(ffBmux, \Y).extract(offset, GetSize(sigB)) == sigB filter offset+GetSize(sigB) <= GetSize(port(ffBmux, \Y)) && port(ffBmux, \Y).extract(offset, GetSize(sigB)) == sigB
choice <IdString> BA {\B, \A} choice <IdString> BA {\B, \A}
filter offset+GetSize(sigffBmux) <= GetSize(port(ffBmux, \Y)) && port(ffBmux, BA).extract(offset, GetSize(sigffBmux)) == sigffBmux filter offset+GetSize(sigffBmuxY) <= GetSize(port(ffBmux, \Y)) && port(ffBmux, BA).extract(offset, GetSize(sigffBmuxY)) == sigffBmuxY
define <bool> pol (BA == \B) define <bool> pol (BA == \B)
set ffBenpol pol set ffBenpol pol
semioptional semioptional