pattern xilinx_dsp_pack

state <SigBit> clock
state <SigSpec> sigA sigB sigC sigD sigM sigP
state <IdString> postAddAB postAddMuxAB
state <bool> ffA1cepol ffA2cepol ffADcepol ffB1cepol ffB2cepol ffDcepol ffMcepol ffPcepol
state <bool> ffArstpol ffADrstpol ffBrstpol ffDrstpol ffMrstpol ffPrstpol

state <Cell*> ffAD ffADcemux ffADrstmux ffA1 ffA1cemux ffA1rstmux ffA2 ffA2cemux ffA2rstmux
state <Cell*> ffB1 ffB1cemux ffB1rstmux ffB2 ffB2cemux ffB2rstmux
state <Cell*> ffD ffDcemux ffDrstmux ffM ffMcemux ffMrstmux ffP ffPcemux ffPrstmux

// subpattern
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

match dsp
	select dsp->type.in(\DSP48E1)
endmatch

code sigA sigB sigC sigD sigM clock
	auto 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);
	};
	sigA = unextend(port(dsp, \A));
	sigB = unextend(port(dsp, \B));

	sigC = port(dsp, \C, SigSpec());
	sigD = port(dsp, \D, SigSpec());

	SigSpec P = port(dsp, \P);
	if (param(dsp, \USE_MULT, Const("MULTIPLY")).decode_string() == "MULTIPLY") {
		// Only care about those bits that are used
		int i;
		for (i = 0; i < GetSize(P); i++) {
			if (nusers(P[i]) <= 1)
				break;
			sigM.append(P[i]);
		}
		log_assert(nusers(P.extract_end(i)) <= 1);
	}
	else
		sigM = P;
	// This sigM could have no users if downstream $add
	//   is narrower than $mul result, for example
	if (sigM.empty())
		reject;

	clock = port(dsp, \CLK, SigBit());
endcode

code argQ ffAD ffADcemux ffADrstmux ffADcepol ffADrstpol sigA clock
	if (param(dsp, \ADREG).as_int() == 0) {
		argQ = sigA;
		subpattern(in_dffe);
		if (dff) {
			ffAD = dff;
			clock = dffclock;
			if (dffrstmux) {
				ffADrstmux = dffrstmux;
				ffADrstpol = dffrstpol;
			}
			if (dffcemux) {
				ffADcemux = dffcemux;
				ffADcepol = dffcepol;
			}
			sigA = dffD;
		}
	}
endcode

match preAdd
	if sigD.empty() || sigD.is_fully_zero()
	// Ensure that preAdder not already used
	if param(dsp, \USE_DPORT, Const("FALSE")).decode_string() == "FALSE"
	if port(dsp, \INMODE, Const(0, 5)).is_fully_zero()

	select preAdd->type.in($add)
	// Output has to be 25 bits or less
	select GetSize(port(preAdd, \Y)) <= 25
	select nusers(port(preAdd, \Y)) == 2
	choice <IdString> AB {\A, \B}
	// A port has to be 30 bits or less
	select GetSize(port(preAdd, AB)) <= 30
	define <IdString> BA (AB == \A ? \B : \A)
	// D port has to be 25 bits or less
	select GetSize(port(preAdd, BA)) <= 25
	index <SigSpec> port(preAdd, \Y) === sigA

	optional
endmatch

code sigA sigD
	if (preAdd) {
		sigA = port(preAdd, \A);
		sigD = port(preAdd, \B);
		if (GetSize(sigA) < GetSize(sigD))
			std::swap(sigA, sigD);
	}
endcode

code argQ ffAD ffADcemux ffADrstmux ffADcepol ffADrstpol sigA clock ffA2 ffA2cemux ffA2rstmux ffA2cepol ffArstpol ffA1 ffA1cemux ffA1rstmux ffA1cepol
	// Only search for ffA2 if there was a pre-adder
	//   (otherwise ffA2 would have been matched as ffAD)
	if (preAdd) {
		if (param(dsp, \AREG).as_int() == 0) {
			argQ = sigA;
			subpattern(in_dffe);
			if (dff) {
				ffA2 = dff;
				clock = dffclock;
				if (dffrstmux) {
					ffA2rstmux = dffrstmux;
					ffArstpol = dffrstpol;
				}
				if (dffcemux) {
					ffA2cepol = dffcepol;
					ffA2cemux = dffcemux;
				}
				sigA = dffD;
			}
		}
	}
	// And if there wasn't a pre-adder,
	//   move AD register to A
	else if (ffAD) {
		log_assert(!ffA2 && !ffA2cemux && !ffA2rstmux);
		std::swap(ffA2, ffAD);
		std::swap(ffA2cemux, ffADcemux);
		std::swap(ffA2rstmux, ffADrstmux);
		ffA2cepol = ffADcepol;
		ffArstpol = ffADrstpol;
	}

	// Now attempt to match A1
	if (ffA2) {
		argQ = sigA;
		subpattern(in_dffe);
		if (dff) {
			if ((ffA2rstmux != nullptr) ^ (dffrstmux != nullptr))
				goto ffA1_end;
			if (dffrstmux) {
				if (ffArstpol != dffrstpol)
					goto ffA1_end;
				if (port(ffA2rstmux, \S) != port(dffrstmux, \S))
					goto ffA1_end;
				ffA1rstmux = dffrstmux;
			}

			ffA1 = dff;
			clock = dffclock;

			if (dffcemux) {
				ffA1cemux = dffcemux;
				ffA1cepol = dffcepol;
			}
			sigA = dffD;

ffA1_end:		;
		}
	}
endcode

code argQ ffB2 ffB2cemux ffB2rstmux ffB2cepol ffBrstpol sigB clock ffB1 ffB1cemux ffB1rstmux ffB1cepol
	if (param(dsp, \BREG).as_int() == 0) {
		argQ = sigB;
		subpattern(in_dffe);
		if (dff) {
			ffB2 = dff;
			clock = dffclock;
			if (dffrstmux) {
				ffB2rstmux = dffrstmux;
				ffBrstpol = dffrstpol;
			}
			if (dffcemux) {
				ffB2cemux = dffcemux;
				ffB2cepol = dffcepol;
			}
			sigB = dffD;

			// Now attempt to match B1
			if (ffB2) {
				argQ = sigB;
				subpattern(in_dffe);
				if (dff) {
					if ((ffB2rstmux != nullptr) ^ (dffrstmux != nullptr))
						goto ffB1_end;
					if (dffrstmux) {
						if (ffBrstpol != dffrstpol)
							goto ffB1_end;
						if (port(ffB2rstmux, \S) != port(dffrstmux, \S))
							goto ffB1_end;
						ffB1rstmux = dffrstmux;
					}

					ffB1 = dff;
					clock = dffclock;

					if (dffcemux) {
						ffB1cemux = dffcemux;
						ffB1cepol = dffcepol;
					}
					sigB = dffD;

ffB1_end:				;
				}
			}

		}
	}
endcode

code argQ ffD ffDcemux ffDrstmux ffDcepol ffDrstpol sigD clock
	if (param(dsp, \DREG).as_int() == 0) {
		argQ = sigD;
		subpattern(in_dffe);
		if (dff) {
			ffD = dff;
			clock = dffclock;
			if (dffrstmux) {
				ffDrstmux = dffrstmux;
				ffDrstpol = dffrstpol;
			}
			if (dffcemux) {
				ffDcemux = dffcemux;
				ffDcepol = dffcepol;
			}
			sigD = dffD;
		}
	}
endcode

code argD ffM ffMcemux ffMrstmux ffMcepol ffMrstpol sigM sigP clock
	if (param(dsp, \MREG).as_int() == 0 && nusers(sigM) == 2) {
		argD = sigM;
		subpattern(out_dffe);
		if (dff) {
			ffM = dff;
			clock = dffclock;
			if (dffrstmux) {
				ffMrstmux = dffrstmux;
				ffMrstpol = dffrstpol;
			}
			if (dffcemux) {
				ffMcemux = dffcemux;
				ffMcepol = dffcepol;
			}
			sigM = dffQ;
		}
	}
	sigP = sigM;
endcode

match postAdd
	// Ensure that Z mux is not already used
	if port(dsp, \OPMODE, SigSpec()).extract(4,3).is_fully_zero()

	select postAdd->type.in($add)
	select GetSize(port(postAdd, \Y)) <= 48
	choice <IdString> AB {\A, \B}
	select nusers(port(postAdd, AB)) <= 3
	filter ffMcemux || nusers(port(postAdd, AB)) == 2
	filter !ffMcemux || nusers(port(postAdd, AB)) == 3

	index <SigBit> port(postAdd, AB)[0] === sigP[0]
	filter GetSize(port(postAdd, AB)) >= GetSize(sigP)
	filter port(postAdd, AB).extract(0, GetSize(sigP)) == sigP
	// Check that remainder of AB is a sign-extension
	define <bool> AB_SIGNED (param(postAdd, AB == \A ? \A_SIGNED : \B_SIGNED).as_bool())
	filter port(postAdd, AB).extract_end(GetSize(sigP)) == SigSpec(AB_SIGNED ? sigP[GetSize(sigP)-1] : State::S0, GetSize(port(postAdd, AB))-GetSize(sigP))
	set postAddAB AB
	optional
endmatch

code sigC sigP
	if (postAdd) {
		sigC = port(postAdd, postAddAB == \A ? \B : \A);
		sigP = port(postAdd, \Y);
	}
endcode

code argD ffP ffPcemux ffPrstmux ffPcepol ffPrstpol sigP clock
	if (param(dsp, \PREG).as_int() == 0) {
		int users = 2;
		// If ffMcemux and no postAdd new-value net must have three users: ffMcemux, ffM and ffPcemux
		if (ffMcemux && !postAdd) users++;
		if (nusers(sigP) == users) {
			argD = sigP;
			subpattern(out_dffe);
			if (dff) {
				ffP = dff;
				clock = dffclock;
				if (dffrstmux) {
					ffPrstmux = dffrstmux;
					ffPrstpol = dffrstpol;
				}
				if (dffcemux) {
					ffPcemux = dffcemux;
					ffPcepol = dffcepol;
				}
				sigP = dffQ;
			}
		}
	}
endcode

match postAddMux
	if postAdd
	if ffP
	select postAddMux->type.in($mux)
	select nusers(port(postAddMux, \Y)) == 2
	choice <IdString> AB {\A, \B}
	index <SigSpec> port(postAddMux, AB) === sigP
	index <SigSpec> port(postAddMux, \Y) === sigC
	set postAddMuxAB AB
	optional
endmatch

code sigC
	if (postAddMux)
		sigC = port(postAddMux, postAddMuxAB == \A ? \B : \A);
endcode

match overflow
	if ffP
	if param(dsp, \USE_PATTERN_DETECT, Const("NO_PATDET")).decode_string() == "NO_PATDET"
	select overflow->type.in($ge)
	select GetSize(port(overflow, \Y)) <= 48
	select port(overflow, \B).is_fully_const()
	define <Const> B port(overflow, \B).as_const()
	select std::count(B.bits.begin(), B.bits.end(), State::S1) == 1
	index <SigSpec> port(overflow, \A) === sigP
	optional
endmatch

code
	accept;
endcode

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

subpattern in_dffe
arg argD argQ clock

code
	dff = nullptr;
	for (auto c : argQ.chunks()) {
		if (!c.wire)
			reject;
		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;
	}
endcode

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

	set ffoffset offset
endmatch

code argQ argD
{
	if (clock != SigBit() && port(ff, \CLK) != clock)
		reject;

	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

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

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

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

subpattern out_dffe
arg argD argQ clock

code
	dff = nullptr;
	for (auto c : argD.chunks())
		if (c.wire->get_bool_attribute(\keep))
			reject;
endcode

match ffcemux
	select ffcemux->type.in($mux)
	// ffcemux output must have two users: ffcemux and ff.D
	select nusers(port(ffcemux, \Y)) == 2

	choice <IdString> AB {\A, \B}
	// keep-last-value net must have at least three users: ffcemux, ff, downstream sink(s)
	select nusers(port(ffcemux, AB)) >= 3

	slice offset GetSize(port(ffcemux, \Y))
	define <IdString> BA (AB == \A ? \B : \A)
	index <SigBit> port(ffcemux, BA)[offset] === argD[0]

	// Check that the rest of argD is present
	filter GetSize(port(ffcemux, BA)) >= offset + GetSize(argD)
	filter port(ffcemux, BA).extract(offset, GetSize(argD)) == argD

	set ffoffset offset
	define <bool> pol (AB == \A)
	set ffcepol pol

	semioptional
endmatch

code argD argQ
	dffcemux = ffcemux;
	if (ffcemux) {
		SigSpec BA = port(ffcemux, ffcepol ? \B : \A);
		SigSpec Y = port(ffcemux, \Y);
		argQ = argD;
		argD.replace(BA, Y);
		argQ.replace(BA, port(ffcemux, ffcepol ? \A : \B));

		dffcemux = ffcemux;
		dffcepol = ffcepol;
	}
endcode

match ffrstmux
	select ffrstmux->type.in($mux)
	// ffrstmux output must have two users: ffrstmux and ff.D
	select nusers(port(ffrstmux, \Y)) == 2

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

	slice offset GetSize(port(ffrstmux, \Y))
	define <IdString> AB (BA == \B ? \A : \B)
	index <SigBit> port(ffrstmux, AB)[offset] === argD[0]

	// Check that offset is consistent
	filter !ffcemux || ffoffset == offset
	// Check that the rest of argD is present
	filter GetSize(port(ffrstmux, AB)) >= offset + GetSize(argD)
	filter port(ffrstmux, AB).extract(offset, GetSize(argD)) == argD

	set ffoffset offset
	define <bool> pol (AB == \A)
	set ffrstpol pol

	semioptional
endmatch

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

		dffrstmux = ffrstmux;
		dffrstpol = ffrstpol;
	}
endcode

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, \D)[offset] === argD[0]

	// Check that offset is consistent
	filter (!ffcemux && !ffrstmux) || ffoffset == offset
	// Check that the rest of argD is present
	filter GetSize(port(ff, \D)) >= offset + GetSize(argD)
	filter port(ff, \D).extract(offset, GetSize(argD)) == argD
	// Check that FF.Q is connected to CE-mux
	filter !ffcemux || port(ff, \Q).extract(offset, GetSize(argQ)) == argQ

	set ffoffset offset
endmatch

code argQ
	if (ff) {
		if (clock != SigBit() && port(ff, \CLK) != clock)
			reject;

		SigSpec D = port(ff, \D);
		SigSpec Q = port(ff, \Q);
		if (!ffcemux) {
			argQ = argD;
			argQ.replace(D, Q);
		}

		for (auto c : argQ.chunks()) {
			Const init = c.wire->attributes.at(\init, State::Sx);
			if (!init.is_fully_undef() && !init.is_fully_zero())
				reject;
		}

		dff = ff;
		dffQ = argQ;
		dffclock = port(ff, \CLK);
	}
	// No enable/reset mux possible without flop
	else if (dffcemux || dffrstmux)
		reject;
endcode
