pattern fixed

state <IdString> clk_port en_port
udata <vector<Cell*>> chain longest_chain
udata <pool<Cell*>> non_first_cells
udata <int> minlen

code
	non_first_cells.clear();
	subpattern(setup);
endcode

match first
	select first->type.in($_DFF_N_, $_DFF_P_, $_DFFE_NN_, $_DFFE_NP_, $_DFFE_PN_, $_DFFE_PP_, \FDRE, \FDRE_1)
	select !first->has_keep_attr()
	select !first->type.in(\FDRE) || !param(first, \IS_R_INVERTED, State::S0).as_bool()
	select !first->type.in(\FDRE) || !param(first, \IS_D_INVERTED, State::S0).as_bool()
	select !first->type.in(\FDRE, \FDRE_1) || port(first, \R, State::S0).is_fully_zero()
	filter !non_first_cells.count(first)
generate
	SigSpec C = module->addWire(NEW_ID);
	SigSpec D = module->addWire(NEW_ID);
	SigSpec Q = module->addWire(NEW_ID);
	auto r = rng(8);
	Cell* cell;
	switch (r)
	{
	case 0:
	case 1:
		cell = module->addCell(NEW_ID, \FDRE);
		cell->setPort(\C, C);
		cell->setPort(\D, D);
		cell->setPort(\Q, Q);
		cell->setPort(\CE, module->addWire(NEW_ID));
		if (r & 1)
			cell->setPort(\R, module->addWire(NEW_ID));
		else {
			if (rng(2) == 0)
				cell->setPort(\R, State::S0);
		}
		break;
	case 2:
	case 3:
		cell = module->addDffGate(NEW_ID, C, D, Q, r & 1);
		break;
	case 4:
	case 5:
	case 6:
	case 7:
		cell = module->addDffeGate(NEW_ID, C, module->addWire(NEW_ID), D, Q, r & 1, r & 2);
		break;
	default: log_abort();
	}
endmatch

code clk_port en_port
	if (first->type.in($_DFF_N_, $_DFF_P_, $_DFFE_NN_, $_DFFE_NP_, $_DFFE_PN_, $_DFFE_PP_, \FDRE, \FDRE_1))
		clk_port = \C;
	else log_abort();
	if (first->type.in($_DFF_N_, $_DFF_P_))
		en_port = IdString();
	else if (first->type.in($_DFFE_NN_, $_DFFE_NP_, $_DFFE_PN_, $_DFFE_PP_))
		en_port = \E;
	else if (first->type.in(\FDRE, \FDRE_1))
		en_port = \CE;
	else log_abort();

	longest_chain.clear();
	chain.push_back(first);
	subpattern(tail);
finally
	chain.pop_back();
	log_assert(chain.empty());
	if (GetSize(longest_chain) >= minlen)
		accept;
endcode

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

subpattern setup
arg clk_port
arg en_port

match first
	select first->type.in($_DFF_N_, $_DFF_P_, $_DFFE_NN_, $_DFFE_NP_, $_DFFE_PN_, $_DFFE_PP_, \FDRE, \FDRE_1)
	select !first->has_keep_attr()
	select !first->type.in(\FDRE) || !param(first, \IS_R_INVERTED, State::S0).as_bool()
	select !first->type.in(\FDRE) || !param(first, \IS_D_INVERTED, State::S0).as_bool()
	select !first->type.in(\FDRE, \FDRE_1) || port(first, \R, State::S0).is_fully_zero()
endmatch

code clk_port en_port
	if (first->type.in($_DFF_N_, $_DFF_P_, $_DFFE_NN_, $_DFFE_NP_, $_DFFE_PN_, $_DFFE_PP_, \FDRE, \FDRE_1))
		clk_port = \C;
	else log_abort();
	if (first->type.in($_DFF_N_, $_DFF_P_))
		en_port = IdString();
	else if (first->type.in($_DFFE_NN_, $_DFFE_NP_, $_DFFE_PN_, $_DFFE_PP_))
		en_port = \E;
	else if (first->type.in(\FDRE, \FDRE_1))
		en_port = \CE;
	else log_abort();
endcode

match next
	select next->type.in($_DFF_N_, $_DFF_P_, $_DFFE_NN_, $_DFFE_NP_, $_DFFE_PN_, $_DFFE_PP_, \FDRE, \FDRE_1)
	select !next->has_keep_attr()
	select port(next, \D)[0].wire && !port(next, \D)[0].wire->get_bool_attribute(\keep)
	select nusers(port(next, \Q)) == 2
	index <IdString> next->type === first->type
	index <SigBit> port(next, \Q) === port(first, \D)
	filter port(next, clk_port) == port(first, clk_port)
	filter en_port == IdString() || port(next, en_port) == port(first, en_port)
	filter !first->type.in(\FDRE) || param(next, \IS_C_INVERTED, State::S0).as_bool() == param(first, \IS_C_INVERTED, State::S0).as_bool()
	filter !first->type.in(\FDRE) || param(next, \IS_D_INVERTED, State::S0).as_bool() == param(first, \IS_D_INVERTED, State::S0).as_bool()
	filter !first->type.in(\FDRE) || param(next, \IS_R_INVERTED, State::S0).as_bool() == param(first, \IS_R_INVERTED, State::S0).as_bool()
	filter !first->type.in(\FDRE, \FDRE_1) || port(next, \R, State::S0).is_fully_zero()
endmatch

code
	non_first_cells.insert(next);
endcode

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

subpattern tail
arg first
arg clk_port
arg en_port

match next
	semioptional
	select next->type.in($_DFF_N_, $_DFF_P_, $_DFFE_NN_, $_DFFE_NP_, $_DFFE_PN_, $_DFFE_PP_, \FDRE, \FDRE_1)
	select !next->has_keep_attr()
	select port(next, \D)[0].wire && !port(next, \D)[0].wire->get_bool_attribute(\keep)
	select nusers(port(next, \Q)) == 2
	index <IdString> next->type === chain.back()->type
	index <SigBit> port(next, \Q) === port(chain.back(), \D)
	filter port(next, clk_port) == port(first, clk_port)
	filter en_port == IdString() || port(next, en_port) == port(first, en_port)
	filter !first->type.in(\FDRE) || param(next, \IS_C_INVERTED, State::S0).as_bool() == param(first, \IS_C_INVERTED, State::S0).as_bool()
	filter !first->type.in(\FDRE) || param(next, \IS_D_INVERTED, State::S0).as_bool() == param(first, \IS_D_INVERTED, State::S0).as_bool()
	filter !first->type.in(\FDRE) || param(next, \IS_R_INVERTED, State::S0).as_bool() == param(first, \IS_R_INVERTED, State::S0).as_bool()
	filter !first->type.in(\FDRE, \FDRE_1) || port(next, \R, State::S0).is_fully_zero()
generate
	Cell *cell = module->addCell(NEW_ID, chain.back()->type);
	cell->setPort(\C, chain.back()->getPort(\C));
	cell->setPort(\D, module->addWire(NEW_ID));
	cell->setPort(\Q, chain.back()->getPort(\D));
	if (cell->type == \FDRE) {
		if (rng(2) == 0)
			cell->setPort(\R, port(chain.back(), \R, State::S0));
		cell->setPort(\CE, chain.back()->getPort(\CE));
	}
	else if (cell->type.begins_with("$_DFFE_"))
		cell->setPort(\E, chain.back()->getPort(\E));
endmatch

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

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

pattern variable

state <IdString> clk_port en_port
state <int> shiftx_width
state <int> slice
udata <int> minlen
udata <vector<pair<Cell*,int>>> chain
udata <pool<SigBit>> chain_bits

code
	chain_bits.clear();
endcode

match shiftx
	select shiftx->type.in($shiftx)
	select !shiftx->has_keep_attr()
	select param(shiftx, \Y_WIDTH).as_int() == 1
	filter param(shiftx, \A_WIDTH).as_int() >= minlen
generate
	minlen = 3;
	module->addShiftx(NEW_ID, module->addWire(NEW_ID, rng(6)+minlen), module->addWire(NEW_ID, 3), module->addWire(NEW_ID));
endmatch

code shiftx_width
	shiftx_width = param(shiftx, \A_WIDTH).as_int();
endcode

match first
	select first->type.in($_DFF_N_, $_DFF_P_, $_DFFE_NN_, $_DFFE_NP_, $_DFFE_PN_, $_DFFE_PP_, $dff, $dffe)
	select !first->has_keep_attr()
	select port(first, \Q)[0].wire && !port(first, \Q)[0].wire->get_bool_attribute(\keep)
	slice idx GetSize(port(first, \Q))
	select nusers(port(first, \Q)[idx]) <= 2
	index <SigBit> port(first, \Q)[idx] === port(shiftx, \A)[shiftx_width-1]
	set slice idx
generate
	SigSpec C = module->addWire(NEW_ID);
	auto WIDTH = rng(3)+1;
	SigSpec D = module->addWire(NEW_ID, WIDTH);
	SigSpec Q = module->addWire(NEW_ID, WIDTH);
	auto r = rng(8);
	Cell *cell = nullptr;
	switch (r)
	{
	case 0:
	case 1:
		cell = module->addDff(NEW_ID, C, D, Q, r & 1);
		break;
	case 2:
	case 3:
	case 4:
	case 5:
		//cell = module->addDffe(NEW_ID, C, module->addWire(NEW_ID), D, Q, r & 1, r & 4);
		//break;
	case 6:
	case 7:
		WIDTH = 1;
		cell = module->addDffGate(NEW_ID, C, D[0], Q[0], r & 1);
		break;
	default: log_abort();
	}
	shiftx->connections_.at(\A)[shiftx_width-1] = port(cell, \Q)[rng(WIDTH)];
endmatch

code clk_port en_port
	if (first->type.in($_DFF_N_, $_DFF_P_, $_DFFE_NN_, $_DFFE_NP_, $_DFFE_PN_, $_DFFE_PP_))
		clk_port = \C;
	else if (first->type.in($dff, $dffe))
		clk_port = \CLK;
	else log_abort();
	if (first->type.in($_DFF_N_, $_DFF_P_, $dff))
		en_port = IdString();
	else if (first->type.in($_DFFE_NN_, $_DFFE_NP_, $_DFFE_PN_, $_DFFE_PP_))
		en_port = \E;
	else if (first->type.in($dffe))
		en_port = \EN;
	else log_abort();

	chain_bits.insert(port(first, \Q)[slice]);
	chain.emplace_back(first, slice);
	subpattern(tail);
finally
	if (GetSize(chain) == shiftx_width)
		accept;
	chain.clear();
endcode

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

subpattern tail
arg first
arg shiftx
arg shiftx_width
arg slice
arg clk_port
arg en_port

match next
	semioptional
	select next->type.in($_DFF_N_, $_DFF_P_, $_DFFE_NN_, $_DFFE_NP_, $_DFFE_PN_, $_DFFE_PP_, $dff, $dffe)
	select !next->has_keep_attr()
	select port(next, \D)[0].wire && !port(next, \D)[0].wire->get_bool_attribute(\keep)
	slice idx GetSize(port(next, \Q))
	select nusers(port(next, \Q)[idx]) <= 3
	index <IdString> next->type === chain.back().first->type
	index <SigBit> port(next, \Q)[idx] === port(chain.back().first, \D)[chain.back().second]
	index <SigBit> port(next, \Q)[idx] === port(shiftx, \A)[shiftx_width-1-GetSize(chain)]
	filter port(next, clk_port) == port(first, clk_port)
	filter en_port == IdString() || port(next, en_port) == port(first, en_port)
	filter !next->type.in($dff, $dffe) || param(next, \CLK_POLARITY).as_bool() == param(first, \CLK_POLARITY).as_bool()
	filter !next->type.in($dffe) || param(next, \EN_POLARITY).as_bool() == param(first, \EN_POLARITY).as_bool()
	filter !chain_bits.count(port(next, \D)[idx])
	set slice idx
generate
	if (GetSize(chain) < shiftx_width) {
		auto back = chain.back().first;
		auto slice = chain.back().second;
		if (back->type.in($dff, $dffe)) {
			auto WIDTH = GetSize(port(back, \D));
			if (rng(2) == 0 && slice < WIDTH-1) {
				auto new_slice = slice + rng(WIDTH-1-slice);
				back->connections_.at(\D)[slice] = port(back, \Q)[new_slice];
			}
			else {
				auto D = module->addWire(NEW_ID, WIDTH);
				if (back->type == $dff)
					module->addDff(NEW_ID, port(back, \CLK), D, port(back, \D), param(back, \CLK_POLARITY).as_bool());
				else if (back->type == $dffe)
					module->addDffe(NEW_ID, port(back, \CLK), port(back, \EN), D, port(back, \D), param(back, \CLK_POLARITY).as_bool(), param(back, \EN_POLARITY).as_bool());
				else
					log_abort();
			}
		}
		else if (back->type.begins_with("$_DFF_")) {
			Cell *cell = module->addCell(NEW_ID, back->type);
			cell->setPort(\C, back->getPort(\C));
			cell->setPort(\D, module->addWire(NEW_ID));
			cell->setPort(\Q, back->getPort(\D));
		}
		else
			log_abort();
		shiftx->connections_.at(\A)[shiftx_width-1-GetSize(chain)] = port(back, \D)[slice];
	}
endmatch

code
	if (next) {
		chain_bits.insert(port(next, \Q)[slice]);
		chain.emplace_back(next, slice);
		if (GetSize(chain) < shiftx_width)
			subpattern(tail);
	}
endcode
