// This file describes the third of three pattern matcher setups that
//   forms the `xilinx_dsp` pass described in xilinx_dsp.cc
// At a high level, it works as follows:
//   (1) Starting from a DSP48E1 cell that (a) has the Z multiplexer
//       (controlled by OPMODE[6:4]) set to zero and (b) doesn't already
//       use the 'PCOUT' port
//   (2.1) Match another DSP48E1 cell that (a) does not have the CREG enabled,
//         (b) has its Z multiplexer output set to the 'C' port, which is
//         driven by the 'P' output of the previous DSP cell, and (c) has its
//         'PCIN' port unused
//   (2.2) Same as (2.1) but with the 'C' port driven by the 'P' output of the
//         previous DSP cell right-shifted by 17 bits
//   (3) For this subequent DSP48E1 match (i.e. PCOUT -> PCIN cascade exists)
//       if (a) the previous DSP48E1 uses either the A2REG or A1REG, (b) this
//       DSP48 does not use A2REG nor A1REG, (c) this DSP48E1 does not already
//       have an ACOUT -> ACIN cascade, (d) the previous DSP does not already
//       use its ACOUT port, then examine if an ACOUT -> ACIN cascade
//       opportunity exists by matching for a $dff-with-optional-clock-enable-
//       or-reset and checking that the 'D' input of this register is the same
//       as the 'A' input of the previous DSP
//   (4) Same as (3) but for BCOUT -> BCIN cascade
//   (5) Recursively go to (2.1) until no more matches possible, keeping track
//       of the longest possible chain found
//   (6) The longest chain is then divided into chunks of no more than
//       MAX_DSP_CASCADE in length (to prevent long cascades that exceed the
//       height of a DSP column) with each DSP in each chunk being rewritten
//       to use [ABP]COUT -> [ABP]CIN cascading as appropriate
// Notes:
//   - Currently, [AB]COUT -> [AB]COUT cascades (3 or 4) are only considered
//     if a PCOUT -> PCIN cascade is (2.1 or 2.2) first identified; this need
//     not be the case --- [AB] cascades can exist independently of a P cascade
//     (though all three cascades must come from the same DSP). This situation
//     is not handled currently.
//   - In addition, [AB]COUT -> [AB]COUT cascades (3 or 4) are currently
//     conservative in that they examine the situation where (a) the previous
//     DSP has [AB]2REG or [AB]1REG enabled, (b) that the downstream DSP has no
//     registers enabled, and (c) that there exists only one additional register
//     between the upstream and downstream DSPs. This can certainly be relaxed
//     to identify situations ranging from (i) neither DSP uses any registers,
//     to (ii) upstream DSP has 2 registers, downstream DSP has 2 registers, and
//     there exists a further 2 registers between them. This remains a TODO
//     item.

pattern xilinx_dsp_cascade

udata <std::function<SigSpec(const SigSpec&)>> unextend
udata <vector<std::tuple<Cell*,int,int,int>>> chain longest_chain
state <Cell*> next
state <SigSpec> clock
state <int> AREG BREG

// Variables used for subpatterns
state <SigSpec> argQ argD
state <bool> ffcepol ffrstpol
state <int> ffoffset
udata <SigSpec> dffD dffQ
udata <SigBit> dffclock
udata <Cell*> dff dffcemux dffrstmux
udata <bool> dffcepol dffrstpol

code
#define MAX_DSP_CASCADE 20
endcode

// (1) Starting from a DSP48E1 cell that (a) has the Z multiplexer
//     (controlled by OPMODE[6:4]) set to zero and (b) doesn't already
//     use the 'PCOUT' port
match first
	select first->type.in(\DSP48E1)
	select port(first, \OPMODE, Const(0, 7)).extract(4,3) == Const::from_string("000")
	select nusers(port(first, \PCOUT, SigSpec())) <= 1
endmatch

// (6) The longest chain is then divided into chunks of no more than
//     MAX_DSP_CASCADE in length (to prevent long cascades that exceed the
//     height of a DSP column) with each DSP in each chunk being rewritten
//     to use [ABP]COUT -> [ABP]CIN cascading as appropriate
code
	longest_chain.clear();
	chain.emplace_back(first, -1, -1, -1);
	subpattern(tail);
finally
	chain.pop_back();
	log_assert(chain.empty());
	if (GetSize(longest_chain) > 1) {
		Cell *dsp = std::get<0>(longest_chain.front());

		Cell *dsp_pcin;
		int P, AREG, BREG;
		for (int i = 1; i < GetSize(longest_chain); i++) {
			std::tie(dsp_pcin,P,AREG,BREG) = longest_chain[i];

			if (i % MAX_DSP_CASCADE > 0) {
				if (P >= 0) {
					Wire *cascade = module->addWire(NEW_ID, 48);
					dsp_pcin->setPort(ID(C), Const(0, 48));
					dsp_pcin->setPort(ID(PCIN), cascade);
					dsp->setPort(ID(PCOUT), cascade);
					add_siguser(cascade, dsp_pcin);
					add_siguser(cascade, dsp);

					SigSpec opmode = port(dsp_pcin, \OPMODE, Const(0, 7));
					if (P == 17)
						opmode[6] = State::S1;
					else if (P == 0)
						opmode[6] = State::S0;
					else log_abort();

					opmode[5] = State::S0;
					opmode[4] = State::S1;
					dsp_pcin->setPort(\OPMODE, opmode);

					log_debug("PCOUT -> PCIN cascade for %s -> %s\n", log_id(dsp), log_id(dsp_pcin));
				}
				if (AREG >= 0) {
					Wire *cascade = module->addWire(NEW_ID, 30);
					dsp_pcin->setPort(ID(A), Const(0, 30));
					dsp_pcin->setPort(ID(ACIN), cascade);
					dsp->setPort(ID(ACOUT), cascade);
					add_siguser(cascade, dsp_pcin);
					add_siguser(cascade, dsp);

					dsp->setParam(ID(ACASCREG), AREG);
					dsp_pcin->setParam(ID(A_INPUT), Const("CASCADE"));

					log_debug("ACOUT -> ACIN cascade for %s -> %s\n", log_id(dsp), log_id(dsp_pcin));
				}
				if (BREG >= 0) {
					Wire *cascade = module->addWire(NEW_ID, 18);
					dsp_pcin->setPort(ID(B), Const(0, 18));
					dsp_pcin->setPort(ID(BCIN), cascade);
					dsp->setPort(ID(BCOUT), cascade);
					add_siguser(cascade, dsp_pcin);
					add_siguser(cascade, dsp);

					dsp->setParam(ID(BCASCREG), BREG);
					dsp_pcin->setParam(ID(B_INPUT), Const("CASCADE"));

					log_debug("BCOUT -> BCIN cascade for %s -> %s\n", log_id(dsp), log_id(dsp_pcin));
				}
			}
			else {
				log_debug("  Blocking %s -> %s cascade (exceeds max: %d)\n", log_id(dsp), log_id(dsp_pcin), MAX_DSP_CASCADE);
			}

			dsp = dsp_pcin;
		}

		accept;
	}
endcode

// ------------------------------------------------------------------

subpattern tail
arg first
arg next

// (2.1) Match another DSP48E1 cell that (a) does not have the CREG enabled,
//       (b) has its Z multiplexer output set to the 'C' port, which is
//       driven by the 'P' output of the previous DSP cell, and (c) has its
//       'PCIN' port unused
match nextP
	select nextP->type.in(\DSP48E1)
	select !param(nextP, \CREG, State::S1).as_bool()
	select port(nextP, \OPMODE, Const(0, 7)).extract(4,3) == Const::from_string("011")
	select nusers(port(nextP, \C, SigSpec())) > 1
	select nusers(port(nextP, \PCIN, SigSpec())) == 0
	index <SigBit> port(nextP, \C)[0] === port(std::get<0>(chain.back()), \P)[0]
	semioptional
endmatch

// (2.2) Same as (2.1) but with the 'C' port driven by the 'P' output of the
//       previous DSP cell right-shifted by 17 bits
match nextP_shift17
	if !nextP
	select nextP_shift17->type.in(\DSP48E1)
	select !param(nextP_shift17, \CREG, State::S1).as_bool()
	select port(nextP_shift17, \OPMODE, Const(0, 7)).extract(4,3) == Const::from_string("011")
	select nusers(port(nextP_shift17, \C, SigSpec())) > 1
	select nusers(port(nextP_shift17, \PCIN, SigSpec())) == 0
	index <SigBit> port(nextP_shift17, \C)[0] === port(std::get<0>(chain.back()), \P)[17]
	semioptional
endmatch

code next
	next = nextP;
	if (!nextP)
		next = nextP_shift17;
	if (next) {
		unextend = [](const SigSpec &sig) {
			int i;
			for (i = GetSize(sig)-1; i > 0; i--)
				if (sig[i] != sig[i-1])
					break;
			// Do not remove non-const sign bit
			if (sig[i].wire)
				++i;
			return sig.extract(0, i);
		};
	}
endcode

// (3) For this subequent DSP48E1 match (i.e. PCOUT -> PCIN cascade exists)
//     if (a) the previous DSP48E1 uses either the A2REG or A1REG, (b) this
//     DSP48 does not use A2REG nor A1REG, (c) this DSP48E1 does not already
//     have an ACOUT -> ACIN cascade, (d) the previous DSP does not already
//     use its ACOUT port, then examine if an ACOUT -> ACIN cascade
//     opportunity exists by matching for a $dff-with-optional-clock-enable-
//     or-reset and checking that the 'D' input of this register is the same
//     as the 'A' input of the previous DSP
code argQ clock AREG
	AREG = -1;
	if (next) {
		Cell *prev = std::get<0>(chain.back());
		if (param(prev, \AREG, 2).as_int() > 0 &&
				param(next, \AREG, 2).as_int() > 0 &&
				param(next, \A_INPUT, Const("DIRECT")).decode_string() == "DIRECT" &&
				nusers(port(prev, \ACOUT, SigSpec())) <= 1) {
			argQ = unextend(port(next, \A));
			clock = port(prev, \CLK);
			subpattern(in_dffe);
			if (dff) {
				if (!dffrstmux && port(prev, \RSTA, State::S0) != State::S0)
					goto reject_AREG;
				if (dffrstmux && port(dffrstmux, \S) != port(prev, \RSTA, State::S0))
					goto reject_AREG;
				if (!dffcemux && port(prev, \CEA2, State::S0) != State::S0)
					goto reject_AREG;
				if (dffcemux && port(dffcemux, \S) != port(prev, \CEA2, State::S0))
					goto reject_AREG;
				if (dffD == unextend(port(prev, \A)))
					AREG = 1;
reject_AREG:			;
			}
		}
	}
endcode

// (4) Same as (3) but for BCOUT -> BCIN cascade
code argQ clock BREG
	BREG = -1;
	if (next) {
		Cell *prev = std::get<0>(chain.back());
		if (param(prev, \BREG, 2).as_int() > 0 &&
				param(next, \BREG, 2).as_int() > 0 &&
				param(next, \B_INPUT, Const("DIRECT")).decode_string() == "DIRECT" &&
				port(next, \BCIN, SigSpec()).is_fully_zero() &&
				nusers(port(prev, \BCOUT, SigSpec())) <= 1) {
			argQ = unextend(port(next, \B));
			clock = port(prev, \CLK);
			subpattern(in_dffe);
			if (dff) {
				if (!dffrstmux && port(prev, \RSTB, State::S0) != State::S0)
					goto reject_BREG;
				if (dffrstmux && port(dffrstmux, \S) != port(prev, \RSTB, State::S0))
					goto reject_BREG;
				if (!dffcemux && port(prev, \CEB2, State::S0) != State::S0)
					goto reject_BREG;
				if (dffcemux && port(dffcemux, \S) != port(prev, \CEB2, State::S0))
					goto reject_BREG;
				if (dffD == unextend(port(prev, \B)))
					BREG = 1;
reject_BREG:			;
			}
		}
	}
endcode

// (5) Recursively go to (2.1) until no more matches possible, recording the
//     longest possible chain
code
	if (next) {
		chain.emplace_back(next, nextP_shift17 ? 17 : nextP ? 0 : -1, AREG, BREG);

		SigSpec sigC = unextend(port(next, \C));

		if (nextP_shift17) {
			if (GetSize(sigC)+17 <= GetSize(port(std::get<0>(chain.back()), \P)) &&
					port(std::get<0>(chain.back()), \P).extract(17, GetSize(sigC)) != sigC)
				subpattern(tail);
		}
		else {
			if (GetSize(sigC) <= GetSize(port(std::get<0>(chain.back()), \P)) &&
					port(std::get<0>(chain.back()), \P).extract(0, GetSize(sigC)) != sigC)
				subpattern(tail);

		}
	} else {
		if (GetSize(chain) > GetSize(longest_chain))
			longest_chain = chain;
	}
finally
	if (next)
		chain.pop_back();
endcode

// #######################

// Subpattern for matching against input registers, based on knowledge of the
//   'Q' input. Typically, identifying registers with clock-enable and reset
//   capability would be a task would be handled by other Yosys passes such as
//   dff2dffe, but since DSP inference happens much before this, these patterns
//   have to be manually identified.
// At a high level:
//   (1) Starting from a $dff cell that (partially or fully) drives the given
//       'Q' argument
//   (2) Match for a $mux cell implementing synchronous reset semantics ---
//       one that exclusively drives the 'D' input of the $dff, with one of its
//       $mux inputs being fully zero
//   (3) Match for a $mux cell implement clock enable semantics --- one that
//       exclusively drives the 'D' input of the $dff (or the other input of
//       the reset $mux) and where one of this $mux's inputs is connected to
//       the 'Q' output of the $dff
subpattern in_dffe
arg argD argQ clock

code
	dff = nullptr;
	for (const auto &c : argQ.chunks()) {
		// Abandon matches when 'Q' is a constant
		if (!c.wire)
			reject;
		// Abandon matches when 'Q' has the keep attribute set
		if (c.wire->get_bool_attribute(\keep))
			reject;
		// Abandon matches when 'Q' has a non-zero init attribute set
		// (not supported by DSP48E1)
		Const init = c.wire->attributes.at(\init, Const());
		for (auto b : init.extract(c.offset, c.width))
			if (b != State::Sx && b != State::S0)
				reject;
	}
endcode

// (1) Starting from a $dff cell that (partially or fully) drives the given
//     'Q' argument
match ff
	select ff->type.in($dff)
	// DSP48E1 does not support clock inversion
	select param(ff, \CLK_POLARITY).as_bool()

	slice offset GetSize(port(ff, \D))
	index <SigBit> port(ff, \Q)[offset] === argQ[0]

	// Check that the rest of argQ is present
	filter GetSize(port(ff, \Q)) >= offset + GetSize(argQ)
	filter port(ff, \Q).extract(offset, GetSize(argQ)) == argQ

	filter clock == SigBit() || port(ff, \CLK) == clock

	set ffoffset offset
endmatch

code argQ argD
	SigSpec Q = port(ff, \Q);
	dff = ff;
	dffclock = port(ff, \CLK);
	dffD = argQ;
	argD = port(ff, \D);
	argQ = Q;
	dffD.replace(argQ, argD);
	// Only search for ffrstmux if dffD only
	//   has two (ff, ffrstmux) users
	if (nusers(dffD) > 2)
		argD = SigSpec();
endcode

// (2) Match for a $mux cell implementing synchronous reset semantics ---
//     exclusively drives the 'D' input of the $dff, with one of the $mux
//     inputs being fully zero
match ffrstmux
	if !argD.empty()
	select ffrstmux->type.in($mux)
	index <SigSpec> port(ffrstmux, \Y) === argD

	choice <IdString> BA {\B, \A}
	// DSP48E1 only supports reset to zero
	select port(ffrstmux, BA).is_fully_zero()

	define <bool> pol (BA == \B)
	set ffrstpol pol
	semioptional
endmatch

code argD
	if (ffrstmux) {
		dffrstmux = ffrstmux;
		dffrstpol = ffrstpol;
		argD = port(ffrstmux, ffrstpol ? \A : \B);
		dffD.replace(port(ffrstmux, \Y), argD);

		// Only search for ffcemux if argQ has at
		//   least 3 users (ff, <upstream>, ffrstmux) and
		//   dffD only has two (ff, ffrstmux)
		if (!(nusers(argQ) >= 3 && nusers(dffD) == 2))
			argD = SigSpec();
	}
	else
		dffrstmux = nullptr;
endcode

// (3) Match for a $mux cell implement clock enable semantics --- one that
//     exclusively drives the 'D' input of the $dff (or the other input of
//     the reset $mux) and where one of this $mux's inputs is connected to
//     the 'Q' output of the $dff
match ffcemux
	if !argD.empty()
	select ffcemux->type.in($mux)
	index <SigSpec> port(ffcemux, \Y) === argD
	choice <IdString> AB {\A, \B}
	index <SigSpec> port(ffcemux, AB) === argQ
	define <bool> pol (AB == \A)
	set ffcepol pol
	semioptional
endmatch

code argD
	if (ffcemux) {
		dffcemux = ffcemux;
		dffcepol = ffcepol;
		argD = port(ffcemux, ffcepol ? \B : \A);
		dffD.replace(port(ffcemux, \Y), argD);
	}
	else
		dffcemux = nullptr;
endcode
