// This file describes the main pattern matcher setup (of three total) 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
//   ( 2) Match the driver of the 'A' input to a possible $dff cell (ADREG)
//        (attached to at most two $mux cells that implement clock-enable or
//         reset functionality, using a subpattern discussed below)
//        If ADREG matched, treat 'A' input as input of ADREG
//   ( 3) Match the driver of the 'A' and 'D' inputs for a possible $add cell
//       (pre-adder)
//   ( 4) If pre-adder was present, find match 'A' input for A2REG
//        If pre-adder was not present, move ADREG to A2REG
//        If A2REG, then match 'A' input for A1REG
//   ( 5) Match 'B' input for B2REG
//        If B2REG, then match 'B' input for B1REG
//   ( 6) Match 'D' input for DREG
//   ( 7) Match 'P' output that exclusively drives an MREG
//   ( 8) Match 'P' output that exclusively drives one of two inputs to an $add
//        cell (post-adder).
//        The other input to the adder is assumed to come in from the 'C' input
//        (note: 'P' -> 'C' connections that exist for accumulators are
//         recognised in xilinx_dsp.cc).
//   ( 9) Match 'P' output that exclusively drives a PREG
//   (10) If post-adder and PREG both present, match for a $mux cell driving
//        the 'C' input, where one of the $mux's inputs is the PREG output.
//        This indicates an accumulator situation, and one where a $mux exists
//        to override the accumulated value:
//             +--------------------------------+
//             |   ____                         |
//             +--|    \                        |
//                |$mux|-+                      |
//         'C' ---|____/ |                      |
//                       | /-------\   +----+   |
//            +----+     +-| post- |___|PREG|---+ 'P'
//            |MREG|------ | adder |   +----+
//            +----+       \-------/
//   (11) If PREG present, match for a greater-than-or-equal $ge cell attached
//        to the 'P' output where it is compared to a constant that is a
//        power-of-2: e.g. `assign overflow = (PREG >= 2**40);`
//        In this scenario, the pattern detector functionality of a DSP48E1 can
//        to implement this function
// Notes:
//   - The intention of this pattern matcher is for it to be compatible with
//     DSP48E1 cells inferred from multiply operations by Yosys, as well as for
//     user instantiations that may already contain the cells being packed...
//     (though the latter is currently untested)
//   - Since the $dff-with-optional-clock-enable-or-reset-mux pattern is used
//     for each *REG match, it has been factored out into two subpatterns:
//     in_dffe and out_dffe located at the bottom of this file.
//   - Matching for pattern detector features is currently incomplete. For
//     example, matching for underflow as well as overflow detection is
//     possible, as would auto-reset, enabling saturated arithmetic, detecting
//     custom patterns, etc.

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

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

// (1) Starting from a DSP48E1 cell
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);
		// This sigM could have no users if downstream sinks (e.g. $add) is
		//   narrower than $mul result, for example
		if (sigM.empty())
			reject;
	}
	else
		sigM = P;

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

// (2) Match the driver of the 'A' input to a possible $dff cell (ADREG)
//     (attached to at most two $mux cells that implement clock-enable or
//      reset functionality, using a subpattern discussed above)
//     If matched, treat 'A' input as input of ADREG
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

// (3) Match the driver of the 'A' and 'D' inputs for a possible $add cell
//     (pre-adder)
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);
	}
endcode

// (4) If pre-adder was present, find match 'A' input for A2REG
//     If pre-adder was not present, move ADREG to A2REG
//     Then match 'A' input for A1REG
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

// (5) Match 'B' input for B2REG
//     If B2REG, then match 'B' input for B1REG
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

// (6) Match 'D' input for DREG
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

// (7) Match 'P' output that exclusively drives an MREG
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

// (8) Match 'P' output that exclusively drives one of two inputs to an $add
//     cell (post-adder).
//     The other input to the adder is assumed to come in from the 'C' input
//     (note: 'P' -> 'C' connections that exist for accumulators are
//      recognised in xilinx_dsp.cc).
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

// (9) Match 'P' output that exclusively drives a PREG
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

// (10) If post-adder and PREG both present, match for a $mux cell driving
//      the 'C' input, where one of the $mux's inputs is the PREG output.
//      This indicates an accumulator situation, and one where a $mux exists
//      to override the accumulated value:
//           +--------------------------------+
//           |   ____                         |
//           +--|    \                        |
//              |$mux|-+                      |
//       'C' ---|____/ |                      |
//                     | /-------\   +----+   |
//          +----+     +-| post- |___|PREG|---+ 'P'
//          |MREG|------ | adder |   +----+
//          +----+       \-------/
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

// (11) If PREG present, match for a greater-than-or-equal $ge cell attached to
//      the 'P' output where it is compared to a constant that is a power-of-2:
//      e.g. `assign overflow = (PREG >= 2**40);`
//      In this scenario, the pattern detector functionality of a DSP48E1 can
//      to implement this function
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 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());
		if (!init.empty())
			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

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

// Subpattern for matching against output registers, based on knowledge of the
//   'D' input.
// At a high level:
//   (1) Starting from an optional $mux cell that implements clock enable
//       semantics --- one where the given 'D' argument (partially or fully)
//       drives one of its two inputs
//   (2) Starting from, or continuing onto, another optional $mux cell that
//       implements synchronous reset semantics --- one where the given 'D'
//       argument (or the clock enable $mux output) drives one of its two inputs
//       and where the other input is fully zero
//   (3) Match for a $dff cell (whose 'D' input is the 'D' argument, or the
//       output of the previous clock enable or reset $mux cells)
subpattern out_dffe
arg argD argQ clock

code
	dff = nullptr;
	for (auto c : argD.chunks())
		// Abandon matches when 'D' has the keep attribute set
		if (c.wire->get_bool_attribute(\keep))
			reject;
endcode

// (1) Starting from an optional $mux cell that implements clock enable
//     semantics --- one where the given 'D' argument (partially or fully)
//     drives one of its two inputs
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

// (2) Starting from, or continuing onto, another optional $mux cell that
//     implements synchronous reset semantics --- one where the given 'D'
//     argument (or the clock enable $mux output) drives one of its two inputs
//     and where the other input is fully zero
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

// (3) Match for a $dff cell (whose 'D' input is the 'D' argument, or the
//     output of the previous clock enable or reset $mux cells)
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

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

	set ffoffset offset
endmatch

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

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

	dff = ff;
	dffQ = argQ;
	dffclock = port(ff, \CLK);
endcode
