diff options
author | Eddie Hung <eddie@fpgeh.com> | 2019-09-11 13:48:45 -0700 |
---|---|---|
committer | Eddie Hung <eddie@fpgeh.com> | 2019-09-11 13:48:45 -0700 |
commit | 690b1a064d9c9c85260cbe841beecff538834833 (patch) | |
tree | 8b127c8661598d7609e274106014c501fbceb0f3 /passes | |
parent | c0f26c2da86af6283f6d8380313bd0ad90f1f917 (diff) | |
download | yosys-690b1a064d9c9c85260cbe841beecff538834833.tar.gz yosys-690b1a064d9c9c85260cbe841beecff538834833.tar.bz2 yosys-690b1a064d9c9c85260cbe841beecff538834833.zip |
Add PCOUT -> PCIN non-shifted cascading
Diffstat (limited to 'passes')
-rw-r--r-- | passes/pmgen/xilinx_dsp.cc | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/passes/pmgen/xilinx_dsp.cc b/passes/pmgen/xilinx_dsp.cc index d9d1bfea4..df3d60e09 100644 --- a/passes/pmgen/xilinx_dsp.cc +++ b/passes/pmgen/xilinx_dsp.cc @@ -272,7 +272,6 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm) log("Analysing %s.%s for Xilinx DSP packing.\n", log_id(pm.module), log_id(st.dsp)); Cell *cell = st.dsp; - bit_to_driver.insert(std::make_pair(cell->getPort("\\P")[17], cell)); if (st.preAdd) { log(" preadder %s (%s)\n", log_id(st.preAdd), log_id(st.preAdd->type)); @@ -317,10 +316,10 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm) opmode[5] = State::S1; if (opmode[4] != State::S0) { - if (st.postAddMuxAB == "\\A") - st.sigC.extend_u0(48, st.postAdd->getParam("\\B_SIGNED").as_bool()); - else - st.sigC.extend_u0(48, st.postAdd->getParam("\\A_SIGNED").as_bool()); + //if (st.postAddMuxAB == "\\A") + // st.sigC.extend_u0(48, st.postAdd->getParam("\\B_SIGNED").as_bool()); + //else + // st.sigC.extend_u0(48, st.postAdd->getParam("\\A_SIGNED").as_bool()); cell->setPort("\\C", st.sigC); } @@ -436,6 +435,9 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm) P.append(pm.module->addWire(NEW_ID, 48-GetSize(P))); cell->setPort("\\P", P); + bit_to_driver.insert(std::make_pair(P[0], cell)); + bit_to_driver.insert(std::make_pair(P[17], cell)); + pm.blacklist(cell); } @@ -489,6 +491,7 @@ struct XilinxDspPass : public Pass { auto f = [&bit_to_driver](xilinx_dsp_pm &pm){ pack_xilinx_dsp(bit_to_driver, pm); }; pm.run_xilinx_dsp(f); + auto &unextend = pm.ud_xilinx_dsp.unextend; // Look for ability to convert C input from another DSP into PCIN // NB: Needs to be done after pattern matcher has folded all // $add cells into the DSP @@ -500,22 +503,26 @@ struct XilinxDspPass : public Pass { SigSpec &opmode = cell->connections_.at("\\OPMODE"); if (opmode.extract(4,3) != Const::from_string("011")) continue; - SigSpec C = pm.sigmap(cell->getPort("\\C")); - if (C.has_const()) + SigSpec C = unextend(pm.sigmap(cell->getPort("\\C"))); + if (!C[0].wire) continue; auto it = bit_to_driver.find(C[0]); if (it == bit_to_driver.end()) continue; auto driver = it->second; - // Unextend C - int i; - for (i = GetSize(C)-1; i > 0; i--) - if (C[i] != C[i-1]) - break; - if (i > 48-17) - continue; - if (driver->getPort("\\P").extract(17, i) == C.extract(0, i)) { + SigSpec P = driver->getPort("\\P"); + if (GetSize(P) >= GetSize(C) && P.extract(0, GetSize(C)) == C) { + cell->setPort("\\C", Const(0, 48)); + Wire *cascade = module->addWire(NEW_ID, 48); + driver->setPort("\\PCOUT", cascade); + cell->setPort("\\PCIN", cascade); + opmode[6] = State::S0; + opmode[5] = State::S0; + opmode[4] = State::S1; + bit_to_driver.erase(it); + } + else if (GetSize(P) >= GetSize(C)+17 && P.extract(17, GetSize(C)) == C) { cell->setPort("\\C", Const(0, 48)); Wire *cascade = module->addWire(NEW_ID, 48); driver->setPort("\\PCOUT", cascade); |