diff options
-rw-r--r-- | passes/pmgen/ice40_dsp.cc | 63 | ||||
-rw-r--r-- | passes/pmgen/ice40_dsp.pmg | 122 |
2 files changed, 116 insertions, 69 deletions
diff --git a/passes/pmgen/ice40_dsp.cc b/passes/pmgen/ice40_dsp.cc index 7592593a6..f3cc83699 100644 --- a/passes/pmgen/ice40_dsp.cc +++ b/passes/pmgen/ice40_dsp.cc @@ -33,13 +33,13 @@ void create_ice40_dsp(ice40_dsp_pm &pm) log("\n"); log("ffA: %s %s %s\n", log_id(st.ffA, "--"), log_id(st.ffAcemux, "--"), log_id(st.ffArstmux, "--")); log("ffB: %s %s %s\n", log_id(st.ffB, "--"), log_id(st.ffBcemux, "--"), log_id(st.ffBrstmux, "--")); - log("ffCD: %s %s %s\n", log_id(st.ffCD, "--"), log_id(st.ffCDcemux, "--"), log_id(st.ffCDrstmux, "--")); + log("ffCD: %s %s\n", log_id(st.ffCD, "--"), log_id(st.ffCDcemux, "--")); log("mul: %s\n", log_id(st.mul, "--")); - log("ffFJKG: %s n/a %s\n", log_id(st.ffFJKG, "--"), log_id(st.ffFJKGrstmux, "--")); - log("ffH: %s n/a %s\n", log_id(st.ffH, "--"), log_id(st.ffHrstmux, "--")); + log("ffFJKG: %s\n", log_id(st.ffFJKG, "--")); + log("ffH: %s\n", log_id(st.ffH, "--")); log("add: %s\n", log_id(st.add, "--")); log("mux: %s\n", log_id(st.mux, "--")); - log("ffO: %s\n", log_id(st.ffO, "--")); + log("ffO: %s %s %s\n", log_id(st.ffO, "--"), log_id(st.ffOcemux, "--"), log_id(st.ffOrstmux, "--")); #endif log("Checking %s.%s for iCE40 DSP inference.\n", log_id(pm.module), log_id(st.mul)); @@ -98,13 +98,35 @@ void create_ice40_dsp(ice40_dsp_pm &pm) cell->setParam("\\C_REG", st.ffCD ? State::S1 : State::S0); cell->setParam("\\D_REG", st.ffCD ? State::S1 : State::S0); - cell->setPort("\\AHOLD", State::S0); - cell->setPort("\\BHOLD", State::S0); - cell->setPort("\\CHOLD", State::S0); - cell->setPort("\\DHOLD", State::S0); - - cell->setPort("\\IRSTTOP", State::S0); - cell->setPort("\\IRSTBOT", State::S0); + SigSpec AHOLD, BHOLD, CDHOLD; + if (st.ffAcemux) + AHOLD = st.ffAcepol ? pm.module->Not(NEW_ID, st.ffAcemux->getPort("\\S")) : st.ffAcemux->getPort("\\S"); + else + AHOLD = State::S0; + if (st.ffBcemux) + BHOLD = st.ffBcepol ? pm.module->Not(NEW_ID, st.ffBcemux->getPort("\\S")) : st.ffBcemux->getPort("\\S"); + else + BHOLD = State::S0; + if (st.ffCDcemux) + CDHOLD = st.ffCDcepol ? pm.module->Not(NEW_ID, st.ffCDcemux->getPort("\\S")) : st.ffCDcemux->getPort("\\S"); + else + CDHOLD = State::S0; + cell->setPort("\\AHOLD", AHOLD); + cell->setPort("\\BHOLD", BHOLD); + cell->setPort("\\CHOLD", CDHOLD); + cell->setPort("\\DHOLD", CDHOLD); + + SigSpec IRSTTOP, IRSTBOT; + if (st.ffArstmux) + IRSTTOP = st.ffArstpol ? st.ffArstmux->getPort("\\S") : pm.module->Not(NEW_ID, st.ffArstmux->getPort("\\S")); + else + IRSTTOP = State::S0; + if (st.ffBrstmux) + IRSTBOT = st.ffBrstpol ? st.ffBrstmux->getPort("\\S") : pm.module->Not(NEW_ID, st.ffBrstmux->getPort("\\S")); + else + IRSTBOT = State::S0; + cell->setPort("\\IRSTTOP", IRSTTOP); + cell->setPort("\\IRSTBOT", IRSTBOT); if (st.clock != SigBit()) { @@ -187,11 +209,21 @@ void create_ice40_dsp(ice40_dsp_pm &pm) cell->setPort("\\ADDSUBBOT", State::S0); } - cell->setPort("\\ORSTTOP", State::S0); - cell->setPort("\\ORSTBOT", State::S0); + SigSpec OHOLD; + if (st.ffOcemux) + OHOLD = st.ffOcemux ? pm.module->Not(NEW_ID, st.ffOcemux->getPort("\\S")) : st.ffOcemux->getPort("\\S"); + else + OHOLD = State::S0; + cell->setPort("\\OHOLDTOP", OHOLD); + cell->setPort("\\OHOLDBOT", OHOLD); - cell->setPort("\\OHOLDTOP", State::S0); - cell->setPort("\\OHOLDBOT", State::S0); + SigSpec ORST; + if (st.ffOrstmux) + ORST = st.ffOrstmux ? st.ffOrstmux->getPort("\\S") : pm.module->Not(NEW_ID, st.ffOrstmux->getPort("\\S")); + else + ORST = State::S0; + cell->setPort("\\ORSTTOP", ORST); + cell->setPort("\\ORSTBOT", ORST); SigSpec acc_reset = State::S0; if (st.mux) { @@ -200,7 +232,6 @@ void create_ice40_dsp(ice40_dsp_pm &pm) else acc_reset = pm.module->Not(NEW_ID, st.mux->getPort("\\S")); } - cell->setPort("\\OLOADTOP", acc_reset); cell->setPort("\\OLOADBOT", acc_reset); diff --git a/passes/pmgen/ice40_dsp.pmg b/passes/pmgen/ice40_dsp.pmg index 532995da7..01e344767 100644 --- a/passes/pmgen/ice40_dsp.pmg +++ b/passes/pmgen/ice40_dsp.pmg @@ -9,8 +9,8 @@ state <IdString> addAB muxAB state <bool> ffAcepol ffBcepol ffCDcepol ffOcepol state <bool> ffArstpol ffBrstpol ffCDrstpol ffOrstpol -state <Cell*> ffA ffAcemux ffArstmux ffB ffBcemux ffBrstmux ffCD ffCDcemux ffCDrstmux -state <Cell*> ffFJKG ffFJKGrstmux ffH ffHrstmux ffO ffOcemux ffOrstmux +state <Cell*> ffA ffAcemux ffArstmux ffB ffBcemux ffBrstmux ffCD ffCDcemux +state <Cell*> ffFJKG ffH ffO ffOcemux ffOrstmux // subpattern state <SigSpec> argQ argD @@ -105,75 +105,79 @@ code argQ ffB ffBcemux ffBrstmux ffBcepol ffBrstpol sigB clock clock_pol } endcode -code argD ffFJKG ffFJKGrstmux sigH sigO clock clock_pol +code argD ffFJKG sigH sigO clock clock_pol if (nusers(sigH) == 2 && (mul->type != \SB_MAC16 || (!param(mul, \TOP_8x8_MULT_REG).as_bool() && !param(mul, \BOT_8x8_MULT_REG).as_bool() && !param(mul, \PIPELINE_16x16_MULT_REG1).as_bool() && !param(mul, \PIPELINE_16x16_MULT_REG1).as_bool()))) { argD = sigH; subpattern(out_dffe); if (dff) { - ffFJKG = dff; - clock = dffclock; - clock_pol = dffclock_pol; - if (dffrstmux) - ffFJKGrstmux = dffrstmux; // F/J/K/G do not have a CE-like (hold) input if (dffcemux) - reject; + goto reject_ffFJKG; // Reset signal of F/J (IRSTTOP) and K/G (IRSTBOT) // shared with A and B - if ((ffArstmux != NULL) != (ffFJKGrstmux != NULL)) - reject; - if ((ffBrstmux != NULL) != (ffFJKGrstmux != NULL)) - reject; + if ((ffArstmux != NULL) != (dffrstmux != NULL)) + goto reject_ffFJKG; + if ((ffBrstmux != NULL) != (dffrstmux != NULL)) + goto reject_ffFJKG; if (ffArstmux) { - if (port(ffArstmux, \S) != port(ffFJKGrstmux, \S)) - reject; + if (port(ffArstmux, \S) != port(dffrstmux, \S)) + goto reject_ffFJKG; if (ffArstpol != dffrstpol) - reject; + goto reject_ffFJKG; } if (ffBrstmux) { - if (port(ffBrstmux, \S) != port(ffFJKGrstmux, \S)) - reject; + if (port(ffBrstmux, \S) != port(dffrstmux, \S)) + goto reject_ffFJKG; if (ffBrstpol != dffrstpol) - reject; + goto reject_ffFJKG; } + ffFJKG = dff; + clock = dffclock; + clock_pol = dffclock_pol; sigH = dffQ; } } + + if (0) { +reject_ffFJKG: ; + } endcode -code argD ffH ffHrstmux sigH sigO clock clock_pol - if (nusers(sigH) == 2 && +code argD ffH sigH sigO clock clock_pol + if (ffFJKG && nusers(sigH) == 2 && (mul->type != \SB_MAC16 || !param(mul, \PIPELINE_16x16_MULT_REG2).as_bool())) { argD = sigH; subpattern(out_dffe); if (dff) { - ffH = dff; - clock = dffclock; - clock_pol = dffclock_pol; - if (dffrstmux) - ffHrstmux = dffrstmux; // H does not have a CE-like (hold) input if (dffcemux) - reject; + goto reject_ffH; // Reset signal of H (IRSTBOT) shared with B - if ((ffBrstmux != NULL) != (ffHrstmux != NULL)) - reject; + if ((ffBrstmux != NULL) != (dffrstmux != NULL)) + goto reject_ffH; if (ffBrstmux) { - if (port(ffBrstmux, \S) != port(ffHrstmux, \S)) - reject; + if (port(ffBrstmux, \S) != port(dffrstmux, \S)) + goto reject_ffH; if (ffBrstpol != dffrstpol) - reject; + goto reject_ffH; } + ffH = dff; + clock = dffclock; + clock_pol = dffclock_pol; sigH = dffQ; } } + if (0) { +reject_ffH: ; + } + sigO = sigH; endcode @@ -274,26 +278,46 @@ code argD ffO ffOcemux ffOrstmux ffOcepol ffOrstpol sigO sigCD clock clock_pol c } endcode -code argQ ffCD ffCDcemux ffCDrstmux ffCDcepol ffCDrstpol sigCD clock clock_pol +code argQ ffCD ffCDcemux ffCDcepol ffCDrstpol sigCD clock clock_pol if (!sigCD.empty() && (mul->type != \SB_MAC16 || (!param(mul, \C_REG).as_bool() && !param(mul, \D_REG).as_bool()))) { argQ = sigCD; subpattern(in_dffe); if (dff) { - ffCD = dff; - clock = dffclock; - clock_pol = dffclock_pol; - if (dffrstmux) { - ffCDrstmux = dffrstmux; - ffCDrstpol = dffrstpol; - } if (dffcemux) { ffCDcemux = dffcemux; ffCDcepol = dffcepol; } + + // Reset signal of C (IRSTTOP) and D (IRSTBOT) + // shared with A and B + if ((ffArstmux != NULL) != (dffrstmux != NULL)) + goto reject_ffCD; + if ((ffBrstmux != NULL) != (dffrstmux != NULL)) + goto reject_ffCD; + if (ffArstmux) { + if (port(ffArstmux, \S) != port(dffrstmux, \S)) + goto reject_ffCD; + if (ffArstpol != dffrstpol) + goto reject_ffCD; + } + if (ffBrstmux) { + if (port(ffBrstmux, \S) != port(dffrstmux, \S)) + goto reject_ffCD; + if (ffBrstpol != dffrstpol) + goto reject_ffCD; + } + + ffCD = dff; + clock = dffclock; + clock_pol = dffclock_pol; sigCD = dffD; } } + + if (0) { +reject_ffCD: ; + } endcode code sigCD @@ -418,6 +442,9 @@ arg argD argQ clock clock_pol code dff = nullptr; + for (auto c : argD.chunks()) + if (c.wire->get_bool_attribute(\keep)) + reject; endcode match ffcemux @@ -434,7 +461,7 @@ match ffcemux index <SigBit> port(ffcemux, BA)[offset] === argD[0] // Check that the rest of argD is present - filter GetSize(BA) >= offset + GetSize(argD) + filter GetSize(port(ffcemux, BA)) >= offset + GetSize(argD) filter port(ffcemux, BA).extract(offset, GetSize(argD)) == argD set ffoffset offset @@ -448,12 +475,6 @@ code argD argQ dffcemux = ffcemux; if (ffcemux) { SigSpec BA = port(ffcemux, ffcepol ? \B : \A); - if (ffoffset + GetSize(argD) > GetSize(BA)) - reject; - for (int i = 1; i < GetSize(argD); i++) - if (BA[ffoffset+i] != argD[i]) - reject; - SigSpec Y = port(ffcemux, \Y); argQ = argD; argD.replace(BA, Y); @@ -480,7 +501,7 @@ match ffrstmux // Check that offset is consistent filter !ffcemux || ffoffset == offset // Check that the rest of argD is present - filter GetSize(AB) >= offset + GetSize(argD) + filter GetSize(port(ffrstmux, AB)) >= offset + GetSize(argD) filter port(ffrstmux, AB).extract(offset, GetSize(argD)) == argD set ffoffset offset @@ -519,8 +540,6 @@ match ff filter !ffcemux || port(ff, \Q).extract(offset, GetSize(argQ)) == argQ set ffoffset offset - - semioptional endmatch code argQ @@ -531,7 +550,6 @@ code argQ if (param(ff, \CLK_POLARITY).as_bool() != clock_pol) reject; } - SigSpec D = port(ff, \D); SigSpec Q = port(ff, \Q); if (!ffcemux) { @@ -540,8 +558,6 @@ code argQ } for (auto c : argQ.chunks()) { - if (c.wire->get_bool_attribute(\keep)) - reject; Const init = c.wire->attributes.at(\init, State::Sx); if (!init.is_fully_undef() && !init.is_fully_zero()) reject; |