3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-13 04:28:18 +00:00

Add support for CEB, remove check on nusers

This commit is contained in:
Eddie Hung 2019-09-05 10:46:33 -07:00
parent 0166e02e78
commit 05282afc25
2 changed files with 33 additions and 16 deletions

View file

@ -34,6 +34,7 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
log("ffA: %s\n", log_id(st.ffA, "--")); log("ffA: %s\n", log_id(st.ffA, "--"));
log("ffAmux: %s\n", log_id(st.ffAmux, "--")); log("ffAmux: %s\n", log_id(st.ffAmux, "--"));
log("ffB: %s\n", log_id(st.ffB, "--")); log("ffB: %s\n", log_id(st.ffB, "--"));
log("ffBmux: %s\n", log_id(st.ffBmux, "--"));
log("dsp: %s\n", log_id(st.dsp, "--")); log("dsp: %s\n", log_id(st.dsp, "--"));
log("ffM: %s\n", log_id(st.ffM, "--")); log("ffM: %s\n", log_id(st.ffM, "--"));
log("ffMmux: %s\n", log_id(st.ffMmux, "--")); log("ffMmux: %s\n", log_id(st.ffMmux, "--"));
@ -81,8 +82,6 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
SigSpec D = st.ffA->getPort("\\D"); SigSpec D = st.ffA->getPort("\\D");
SigSpec Q = pm.sigmap(st.ffA->getPort("\\Q")); SigSpec Q = pm.sigmap(st.ffA->getPort("\\Q"));
A.replace(Q, D); A.replace(Q, D);
cell->setParam("\\AREG", 1);
if (st.ffAmux) { if (st.ffAmux) {
SigSpec Y = st.ffAmux->getPort("\\Y"); SigSpec Y = st.ffAmux->getPort("\\Y");
SigSpec AB = st.ffAmux->getPort(st.ffAmuxAB == "\\A" ? "\\B" : "\\A"); SigSpec AB = st.ffAmux->getPort(st.ffAmuxAB == "\\A" ? "\\B" : "\\A");
@ -92,19 +91,25 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
else else
cell->setPort("\\CEA2", State::S1); cell->setPort("\\CEA2", State::S1);
cell->setPort("\\A", A); cell->setPort("\\A", A);
cell->setParam("\\AREG", 1);
} }
if (st.ffB) { if (st.ffB) {
SigSpec B = cell->getPort("\\B"); SigSpec B = cell->getPort("\\B");
SigSpec D = st.ffB->getPort("\\D"); SigSpec D = st.ffB->getPort("\\D");
SigSpec Q = st.ffB->getPort("\\Q"); SigSpec Q = st.ffB->getPort("\\Q");
B.replace(Q, D); B.replace(Q, D);
cell->setPort("\\B", B); if (st.ffBmux) {
cell->setParam("\\BREG", 1); SigSpec Y = st.ffBmux->getPort("\\Y");
if (st.ffB->type == "$dff") SigSpec AB = st.ffBmux->getPort(st.ffBmuxAB == "\\A" ? "\\B" : "\\A");
B.replace(Y, AB);
cell->setPort("\\CEB2", st.ffBmux->getPort("\\S"));
}
else
cell->setPort("\\CEB2", State::S1); cell->setPort("\\CEB2", State::S1);
//else if (st.ffB->type == "$dffe") cell->setPort("\\B", B);
// cell->setPort("\\CEB2", st.ffB->getPort("\\EN"));
else log_abort(); cell->setParam("\\BREG", 1);
} }
if (st.ffM) { if (st.ffM) {
SigSpec D = st.ffM->getPort("\\D"); SigSpec D = st.ffM->getPort("\\D");

View file

@ -1,14 +1,14 @@
pattern xilinx_dsp pattern xilinx_dsp
state <SigBit> clock state <SigBit> clock
state <SigSpec> sigA sigffAmux sigB sigC sigM sigP state <SigSpec> sigA sigffAmux sigB sigffBmux sigC sigM sigP
state <IdString> ffAmuxAB ffMmuxAB postAddAB postAddMuxAB state <IdString> ffAmuxAB ffBmuxAB ffMmuxAB postAddAB postAddMuxAB
match dsp match dsp
select dsp->type.in(\DSP48E1) select dsp->type.in(\DSP48E1)
endmatch endmatch
code sigA sigffAmux sigB sigM code sigA sigffAmux sigB sigffBmux 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--)
@ -46,7 +46,6 @@ match ffA
select param(ffA, \CLK_POLARITY).as_bool() select param(ffA, \CLK_POLARITY).as_bool()
filter GetSize(port(ffA, \Q)) >= GetSize(sigA) filter GetSize(port(ffA, \Q)) >= GetSize(sigA)
slice offset GetSize(port(ffA, \Q)) slice offset GetSize(port(ffA, \Q))
filter offset+GetSize(sigA) <= GetSize(port(ffA, \Q)) && nusers(port(ffA, \Q).extract(offset, GetSize(sigA))) <= 3
filter offset+GetSize(sigA) <= GetSize(port(ffA, \Q)) && port(ffA, \Q).extract(offset, GetSize(sigA)) == sigA filter offset+GetSize(sigA) <= GetSize(port(ffA, \Q)) && port(ffA, \Q).extract(offset, GetSize(sigA)) == sigA
optional optional
endmatch endmatch
@ -59,19 +58,19 @@ code sigA sigffAmux clock
clock = port(ffA, \CLK).as_bit(); clock = port(ffA, \CLK).as_bit();
if (nusers(sigA) == 3) sigffAmux = sigA;
sigffAmux = sigA;
sigA.replace(port(ffA, \Q), port(ffA, \D)); sigA.replace(port(ffA, \Q), port(ffA, \D));
} }
endcode endcode
match ffAmux match ffAmux
if sigffAmux != SigSpec() if ffA
select ffAmux->type.in($mux) select ffAmux->type.in($mux)
choice <IdString> AB {\A, \B} choice <IdString> AB {\A, \B}
index <SigSpec> port(ffAmux, \Y) === sigA index <SigSpec> port(ffAmux, \Y) === sigA
index <SigSpec> port(ffAmux, AB) === sigffAmux index <SigSpec> port(ffAmux, AB) === sigffAmux
set ffAmuxAB AB set ffAmuxAB AB
semioptional
endmatch endmatch
match ffB match ffB
@ -85,7 +84,7 @@ match ffB
optional optional
endmatch endmatch
code clock code sigB sigffBmux 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))
@ -97,9 +96,22 @@ code clock
reject; reject;
clock = c; clock = c;
sigffBmux = sigB;
sigB.replace(port(ffB, \Q), port(ffB, \D));
} }
endcode endcode
match ffBmux
if ffB
select ffBmux->type.in($mux)
choice <IdString> AB {\A, \B}
index <SigSpec> port(ffBmux, \Y) === sigB
index <SigSpec> port(ffBmux, AB) === sigffBmux
set ffBmuxAB AB
semioptional
endmatch
match ffMmux match ffMmux
select ffMmux->type.in($mux) select ffMmux->type.in($mux)
select nusers(port(ffMmux, \Y)) == 2 select nusers(port(ffMmux, \Y)) == 2