Add support for load value into DSP48E1.P

This commit is contained in:
Eddie Hung 2019-09-03 15:53:10 -07:00
parent 682153de4b
commit 2d80866daf
2 changed files with 48 additions and 31 deletions

View File

@ -40,6 +40,7 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
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("addAB: %s\n", log_id(st.addAB, "--")); log("addAB: %s\n", log_id(st.addAB, "--"));
log("muxAB: %s\n", log_id(st.muxAB, "--"));
log("ffP: %s\n", log_id(st.ffP, "--")); log("ffP: %s\n", log_id(st.ffP, "--"));
//log("muxP: %s\n", log_id(st.muxP, "--")); //log("muxP: %s\n", log_id(st.muxP, "--"));
log("sigPused: %s\n", log_signal(st.sigPused)); log("sigPused: %s\n", log_signal(st.sigPused));
@ -58,7 +59,11 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
log(" adder %s (%s)\n", log_id(st.addAB), log_id(st.addAB->type)); log(" adder %s (%s)\n", log_id(st.addAB), log_id(st.addAB->type));
SigSpec &opmode = cell->connections_.at("\\OPMODE"); SigSpec &opmode = cell->connections_.at("\\OPMODE");
if (st.ffP && C == P) { if (st.ffP && st.muxAB) {
opmode[4] = st.muxAB->getPort("\\S");
pm.autoremove(st.muxAB);
}
else if (st.ffP && C == P) {
C = SigSpec(); C = SigSpec();
opmode[4] = State::S0; opmode[4] = State::S0;
} }

View File

@ -3,7 +3,7 @@ pattern xilinx_dsp
state <SigBit> clock state <SigBit> clock
state <std::set<SigBit>> sigAset sigBset state <std::set<SigBit>> sigAset sigBset
state <SigSpec> sigC sigM sigMused sigP sigPused state <SigSpec> sigC sigM sigMused sigP sigPused
state <Cell*> addAB state <Cell*> addAB muxAB
match dsp match dsp
select dsp->type.in(\DSP48E1) select dsp->type.in(\DSP48E1)
@ -172,34 +172,7 @@ match ffP
optional optional
endmatch endmatch
//// $mux cell left behind by dff2dffe code ffP sigP clock
//// would prefer not to run 'opt_expr -mux_undef'
//// since that would lose information helpful for
//// efficient wide-mux inference
//match muxP
// if !sigPused.empty() && !ffP
// select muxP->type.in($mux)
// select nusers(port(muxP, \B)) == 2
// select port(muxP, \A).is_fully_undef()
// filter param(muxP, \WIDTH).as_int() >= GetSize(sigPused)
// filter includes(port(muxP, \B).to_sigbit_set(), sigPused.to_sigbit_set())
// optional
//endmatch
//
//match ffY
// if muxP
// select ffY->type.in($dff, $dffe)
// select nusers(port(ffY, \D)) == 2
// // DSP48E1 does not support clock inversion
// select param(ffY, \CLK_POLARITY).as_bool()
// filter param(ffY, \WIDTH).as_int() >= GetSize(sigPused)
// filter includes(port(ffY, \D).to_sigbit_set(), port(muxP, \Y).to_sigbit_set())
//endmatch
code ffP clock
// if (ffY)
// ffP = ffY;
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))
@ -211,7 +184,46 @@ code ffP clock
reject; reject;
clock = c; clock = c;
}
sigP = port(ffP, \Q);
}
endcode
match muxA
if addAB
select muxA->type.in($mux)
select nusers(port(muxA, \Y)) == 2
index <SigSpec> port(muxA, \A) === sigP
index <SigSpec> port(muxA, \Y) === sigC
optional
endmatch
match muxB
if addAB
select muxB->type.in($mux)
select nusers(port(muxB, \Y)) == 2
index <SigSpec> port(muxB, \B) === sigP
index <SigSpec> port(muxB, \Y) === sigC
optional
endmatch
code sigC muxAB
if (muxA) {
muxAB = muxA;
sigC = port(muxAB, \B);
}
if (muxB) {
muxAB = muxB;
sigC = port(muxAB, \A);
}
if (muxAB) {
// Ensure that adder is not used
SigSpec opmodeZ = port(dsp, \OPMODE).extract(4,3);
if (!opmodeZ.is_fully_zero())
reject;
}
endcode
code
accept; accept;
endcode endcode