mirror of https://github.com/YosysHQ/yosys.git
Fix ffPmux to cope with offset
This commit is contained in:
parent
fbf1b74946
commit
a945f6c7ef
|
@ -4,6 +4,7 @@ state <SigBit> clock
|
||||||
state <SigSpec> sigA sigffAmuxY sigB sigffBmuxY 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
|
||||||
|
state <int> ffPoffset
|
||||||
|
|
||||||
match dsp
|
match dsp
|
||||||
select dsp->type.in(\DSP48E1)
|
select dsp->type.in(\DSP48E1)
|
||||||
|
@ -139,6 +140,8 @@ match ffBmux
|
||||||
endmatch
|
endmatch
|
||||||
|
|
||||||
match ffMmux
|
match ffMmux
|
||||||
|
if param(dsp, \MREG).as_int() == 0
|
||||||
|
if nusers(sigM) == 2
|
||||||
select ffMmux->type.in($mux)
|
select ffMmux->type.in($mux)
|
||||||
choice <IdString> BA {\B, \A}
|
choice <IdString> BA {\B, \A}
|
||||||
// new-value net must have exactly two users: dsp and ffM
|
// new-value net must have exactly two users: dsp and ffM
|
||||||
|
@ -164,6 +167,7 @@ endcode
|
||||||
|
|
||||||
match ffM
|
match ffM
|
||||||
if param(dsp, \MREG).as_int() == 0
|
if param(dsp, \MREG).as_int() == 0
|
||||||
|
if nusers(sigM) == 2
|
||||||
select ffM->type.in($dff)
|
select ffM->type.in($dff)
|
||||||
// DSP48E1 does not support clock inversion
|
// DSP48E1 does not support clock inversion
|
||||||
select param(ffM, \CLK_POLARITY).as_bool()
|
select param(ffM, \CLK_POLARITY).as_bool()
|
||||||
|
@ -235,31 +239,47 @@ endcode
|
||||||
|
|
||||||
match ffPmux
|
match ffPmux
|
||||||
if param(dsp, \PREG).as_int() == 0
|
if param(dsp, \PREG).as_int() == 0
|
||||||
|
// new-value net must have exactly two users: dsp and ffP
|
||||||
if nusers(sigP) == 2
|
if nusers(sigP) == 2
|
||||||
select ffPmux->type.in($mux)
|
select ffPmux->type.in($mux)
|
||||||
choice <IdString> BA {\B, \A}
|
|
||||||
// new-value net must have exactly two users: dsp and ffP
|
|
||||||
select nusers(port(ffPmux, BA)) == 2
|
|
||||||
define <IdString> 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
|
// ffPmux output must have two users: ffPmux and ffP.D
|
||||||
select nusers(port(ffPmux, \Y)) == 2
|
select nusers(port(ffPmux, \Y)) == 2
|
||||||
filter GetSize(port(ffPmux, \Y)) <= GetSize(sigP)
|
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
|
choice <IdString> BA {\B, \A}
|
||||||
filter nusers(sigP.extract_end(GetSize(port(ffPmux, BA)))) <= 1
|
slice offset GetSize(port(ffPmux, \Y))
|
||||||
|
filter offset+GetSize(sigP) <= GetSize(port(ffPmux, \Y))
|
||||||
|
filter port(ffPmux, BA).extract(offset, GetSize(sigP)) == sigP
|
||||||
|
|
||||||
|
define <IdString> AB (BA == \B ? \A : \B)
|
||||||
|
// keep-last-value net must have at least three users: ffPmux, ffP, downstream sink(s)
|
||||||
|
filter nusers(port(ffPmux, AB)) >= 3
|
||||||
define <bool> pol (BA == \B)
|
define <bool> pol (BA == \B)
|
||||||
set ffPenpol pol
|
set ffPenpol pol
|
||||||
|
set ffPoffset offset
|
||||||
optional
|
optional
|
||||||
endmatch
|
endmatch
|
||||||
|
|
||||||
code sigP
|
code sigP
|
||||||
if (ffPmux)
|
if (ffPmux)
|
||||||
sigP.replace(port(ffPmux, ffPenpol ? \A : \B), port(ffPmux, \Y));
|
sigP.replace(port(ffPmux, ffPenpol ? \B : \A), port(ffPmux, \Y));
|
||||||
endcode
|
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 <SigSpec> port(ffP_enable, \D) === port(ffPmux, \Y)
|
||||||
|
index <SigSpec> 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
|
match ffP
|
||||||
|
if !ffP_enable
|
||||||
if param(dsp, \PREG).as_int() == 0
|
if param(dsp, \PREG).as_int() == 0
|
||||||
if nusers(sigP) == 2
|
if nusers(sigP) == 2
|
||||||
select ffP->type.in($dff)
|
select ffP->type.in($dff)
|
||||||
|
@ -269,12 +289,14 @@ match ffP
|
||||||
slice offset GetSize(port(ffP, \D))
|
slice offset GetSize(port(ffP, \D))
|
||||||
filter offset+GetSize(sigP) <= GetSize(port(ffP, \D))
|
filter offset+GetSize(sigP) <= GetSize(port(ffP, \D))
|
||||||
filter port(ffP, \D).extract(offset, GetSize(sigP)) == sigP
|
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
|
optional
|
||||||
endmatch
|
endmatch
|
||||||
|
|
||||||
code ffP sigP clock
|
code ffP sigP clock
|
||||||
|
if (ffP_enable) {
|
||||||
|
log_assert(!ffP);
|
||||||
|
ffP = ffP_enable;
|
||||||
|
}
|
||||||
if (ffP) {
|
if (ffP) {
|
||||||
for (auto b : port(ffP, \Q))
|
for (auto b : port(ffP, \Q))
|
||||||
if (b.wire->get_bool_attribute(\keep))
|
if (b.wire->get_bool_attribute(\keep))
|
||||||
|
|
Loading…
Reference in New Issue