mirror of https://github.com/YosysHQ/yosys.git
More nusers() checks for A and B enable muxes
This commit is contained in:
parent
dc10559f31
commit
4fe24b20f9
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue