From 5a14b6e1f6331d7587d566173e0d82e0c6c77f4c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 22 Jul 2019 13:01:49 -0700 Subject: [PATCH] Pack adders not just accumulators --- passes/pmgen/ice40_dsp.cc | 38 ++++++++++++++++++++++++++------------ passes/pmgen/ice40_dsp.pmg | 11 +++++++---- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/passes/pmgen/ice40_dsp.cc b/passes/pmgen/ice40_dsp.cc index f6a701540..7215ed473 100644 --- a/passes/pmgen/ice40_dsp.cc +++ b/passes/pmgen/ice40_dsp.cc @@ -80,17 +80,25 @@ void create_ice40_dsp(ice40_dsp_pm &pm) SigSpec B = st.sigB; B.extend_u0(16, b_signed); + // MAC only if ffS exists and adder's other input (sigS) + // is output of ffS + bool accum = (st.ffS && st.sigS == st.ffS->getPort("\\Q")); + SigSpec CD; - if (st.muxA) - CD = st.muxA->getPort("\\B"); - if (st.muxB) - CD = st.muxB->getPort("\\A"); + if (st.ffS) { + if (st.muxA) + CD = st.muxA->getPort("\\B"); + else if (st.muxB) + CD = st.muxB->getPort("\\A"); + } + else if (!accum) + CD = st.sigS.extend_u0(32, st.sigS_signed); CD.extend_u0(32, a_signed && b_signed); cell->setPort("\\A", A); cell->setPort("\\B", B); - cell->setPort("\\C", CD.extract(0, 16)); - cell->setPort("\\D", CD.extract(16, 16)); + cell->setPort("\\C", CD.extract(16, 16)); + cell->setPort("\\D", CD.extract(0, 16)); cell->setParam("\\A_REG", st.ffA ? State::S1 : State::S0); cell->setParam("\\B_REG", st.ffB ? State::S1 : State::S0); @@ -145,14 +153,19 @@ void create_ice40_dsp(ice40_dsp_pm &pm) // SB_MAC16 Output Interface - SigSpec O = st.ffS ? st.sigS : st.sigY; + if (st.addAB) log_cell(st.addAB); + SigSpec O = st.ffS ? st.sigS : (st.addAB ? st.addAB->getPort("\\Y") : st.sigY); if (GetSize(O) < 32) O.append(pm.module->addWire(NEW_ID, 32-GetSize(O))); cell->setPort("\\O", O); if (st.addAB) { - log(" accumulator %s (%s)\n", log_id(st.addAB), log_id(st.addAB->type)); + log_warning("sigS = %s\n", log_signal(st.sigS)); + if (accum) + log(" accumulator %s (%s)\n", log_id(st.addAB), log_id(st.addAB->type)); + else + log(" adder %s (%s)\n", log_id(st.addAB), log_id(st.addAB->type)); cell->setPort("\\ADDSUBTOP", st.addAB->type == "$add" ? State::S0 : State::S1); cell->setPort("\\ADDSUBBOT", st.addAB->type == "$add" ? State::S0 : State::S1); } else { @@ -185,14 +198,14 @@ void create_ice40_dsp(ice40_dsp_pm &pm) cell->setParam("\\PIPELINE_16x16_MULT_REG1", st.ffY ? State::S1 : State::S0); cell->setParam("\\PIPELINE_16x16_MULT_REG2", State::S0); - cell->setParam("\\TOPOUTPUT_SELECT", Const(st.ffS ? 1 : 3, 2)); + cell->setParam("\\TOPOUTPUT_SELECT", Const(st.ffS ? 1 : (st.addAB ? 0 : 3), 2)); cell->setParam("\\TOPADDSUB_LOWERINPUT", Const(2, 2)); - cell->setParam("\\TOPADDSUB_UPPERINPUT", State::S0); + cell->setParam("\\TOPADDSUB_UPPERINPUT", st.ffS ? State::S0 : State::S1); cell->setParam("\\TOPADDSUB_CARRYSELECT", Const(3, 2)); - cell->setParam("\\BOTOUTPUT_SELECT", Const(st.ffS ? 1 : 3, 2)); + cell->setParam("\\BOTOUTPUT_SELECT", Const(st.ffS ? 1 : (st.addAB ? 0 : 3), 2)); cell->setParam("\\BOTADDSUB_LOWERINPUT", Const(2, 2)); - cell->setParam("\\BOTADDSUB_UPPERINPUT", State::S0); + cell->setParam("\\BOTADDSUB_UPPERINPUT", st.ffS ? State::S0 : State::S1); cell->setParam("\\BOTADDSUB_CARRYSELECT", Const(0, 2)); cell->setParam("\\MODE_8x8", State::S0); @@ -201,6 +214,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm) pm.autoremove(st.mul); pm.autoremove(st.ffY); + pm.autoremove(st.addAB); pm.autoremove(st.ffS); } diff --git a/passes/pmgen/ice40_dsp.pmg b/passes/pmgen/ice40_dsp.pmg index e4c6238c5..a92cf8dd4 100644 --- a/passes/pmgen/ice40_dsp.pmg +++ b/passes/pmgen/ice40_dsp.pmg @@ -1,7 +1,7 @@ pattern ice40_dsp state clock -state clock_pol +state clock_pol sigS_signed state sigA sigB sigY sigS state addAB muxAB @@ -92,14 +92,16 @@ match addB optional endmatch -code addAB sigS +code addAB sigS sigS_signed if (addA) { addAB = addA; - sigS = port(addA, \B); + sigS = port(addAB, \B); + sigS_signed = param(addAB, \B_SIGNED).as_bool(); } if (addB) { addAB = addB; - sigS = port(addB, \A); + sigS = port(addAB, \A); + sigS_signed = param(addAB, \A_SIGNED).as_bool(); } if (addAB) { int natural_mul_width = GetSize(sigA) + GetSize(sigB); @@ -144,6 +146,7 @@ match ffS select nusers(port(ffS, \D)) == 2 index port(ffS, \D) === port(muxAB, \Y) index port(ffS, \Q) === sigS + optional endmatch code clock clock_pol -- 2.30.2