diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/cellaigs.cc | 196 | ||||
| -rw-r--r-- | kernel/celledges.cc | 42 | ||||
| -rw-r--r-- | kernel/celltypes.h | 264 | ||||
| -rw-r--r-- | kernel/consteval.h | 91 | ||||
| -rw-r--r-- | kernel/cost.h | 124 | ||||
| -rw-r--r-- | kernel/driver.cc | 6 | ||||
| -rw-r--r-- | kernel/log.h | 2 | ||||
| -rw-r--r-- | kernel/macc.h | 62 | ||||
| -rw-r--r-- | kernel/register.cc | 131 | ||||
| -rw-r--r-- | kernel/rtlil.cc | 1187 | ||||
| -rw-r--r-- | kernel/rtlil.h | 163 | ||||
| -rw-r--r-- | kernel/satgen.h | 526 | ||||
| -rw-r--r-- | kernel/yosys.cc | 75 | ||||
| -rw-r--r-- | kernel/yosys.h | 18 | 
14 files changed, 1568 insertions, 1319 deletions
| diff --git a/kernel/cellaigs.cc b/kernel/cellaigs.cc index 26c625f89..02854edb2 100644 --- a/kernel/cellaigs.cc +++ b/kernel/cellaigs.cc @@ -268,9 +268,9 @@ Aig::Aig(Cell *cell)  	cell->parameters.sort();  	for (auto p : cell->parameters)  	{ -		if (p.first == "\\A_WIDTH" && mkname_a_signed) { +		if (p.first == ID(A_WIDTH) && mkname_a_signed) {  			name = mkname_last + stringf(":%d%c", p.second.as_int(), mkname_is_signed ? 'S' : 'U'); -		} else if (p.first == "\\B_WIDTH" && mkname_b_signed) { +		} else if (p.first == ID(B_WIDTH) && mkname_b_signed) {  			name = mkname_last + stringf(":%d%c", p.second.as_int(), mkname_is_signed ? 'S' : 'U');  		} else {  			mkname_last = name; @@ -280,181 +280,183 @@ Aig::Aig(Cell *cell)  		mkname_a_signed = false;  		mkname_b_signed = false;  		mkname_is_signed = false; -		if (p.first == "\\A_SIGNED") { +		if (p.first == ID(A_SIGNED)) {  			mkname_a_signed = true;  			mkname_is_signed = p.second.as_bool();  		} -		if (p.first == "\\B_SIGNED") { +		if (p.first == ID(B_SIGNED)) {  			mkname_b_signed = true;  			mkname_is_signed = p.second.as_bool();  		}  	} -	if (cell->type.in("$not", "$_NOT_", "$pos", "$_BUF_")) +	if (cell->type.in(ID($not), ID($_NOT_), ID($pos), ID($_BUF_)))  	{ -		for (int i = 0; i < GetSize(cell->getPort("\\Y")); i++) { -			int A = mk.inport("\\A", i); -			int Y = cell->type.in("$not", "$_NOT_") ? mk.not_gate(A) : A; -			mk.outport(Y, "\\Y", i); +		for (int i = 0; i < GetSize(cell->getPort(ID::Y)); i++) { +			int A = mk.inport(ID::A, i); +			int Y = cell->type.in(ID($not), ID($_NOT_)) ? mk.not_gate(A) : A; +			mk.outport(Y, ID::Y, i);  		}  		goto optimize;  	} -	if (cell->type.in("$and", "$_AND_", "$_NAND_", "$or", "$_OR_", "$_NOR_", "$xor", "$xnor", "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_")) -	{ -		for (int i = 0; i < GetSize(cell->getPort("\\Y")); i++) { -			int A = mk.inport("\\A", i); -			int B = mk.inport("\\B", i); -			int Y = cell->type.in("$and", "$_AND_")   ? mk.and_gate(A, B) : -			        cell->type.in("$_NAND_")          ? mk.nand_gate(A, B) : -			        cell->type.in("$or", "$_OR_")     ? mk.or_gate(A, B) : -			        cell->type.in("$_NOR_")           ? mk.nor_gate(A, B) : -			        cell->type.in("$xor", "$_XOR_")   ? mk.xor_gate(A, B) : -			        cell->type.in("$xnor", "$_XNOR_") ? mk.xnor_gate(A, B) : -			        cell->type.in("$_ANDNOT_")        ? mk.andnot_gate(A, B) : -			        cell->type.in("$_ORNOT_")         ? mk.ornot_gate(A, B) : -1; -			mk.outport(Y, "\\Y", i); +	if (cell->type.in(ID($and), ID($_AND_), ID($_NAND_), ID($or), ID($_OR_), ID($_NOR_), ID($xor), ID($xnor), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_))) +	{ +		for (int i = 0; i < GetSize(cell->getPort(ID::Y)); i++) { +			int A = mk.inport(ID::A, i); +			int B = mk.inport(ID::B, i); +			int Y = cell->type.in(ID($and), ID($_AND_))   ? mk.and_gate(A, B) : +			        cell->type.in(ID($_NAND_))          ? mk.nand_gate(A, B) : +			        cell->type.in(ID($or), ID($_OR_))     ? mk.or_gate(A, B) : +			        cell->type.in(ID($_NOR_))           ? mk.nor_gate(A, B) : +			        cell->type.in(ID($xor), ID($_XOR_))   ? mk.xor_gate(A, B) : +			        cell->type.in(ID($xnor), ID($_XNOR_)) ? mk.xnor_gate(A, B) : +			        cell->type.in(ID($_ANDNOT_))        ? mk.andnot_gate(A, B) : +			        cell->type.in(ID($_ORNOT_))         ? mk.ornot_gate(A, B) : -1; +			mk.outport(Y, ID::Y, i);  		}  		goto optimize;  	} -	if (cell->type.in("$mux", "$_MUX_")) +	if (cell->type.in(ID($mux), ID($_MUX_)))  	{ -		int S = mk.inport("\\S"); -		for (int i = 0; i < GetSize(cell->getPort("\\Y")); i++) { -			int A = mk.inport("\\A", i); -			int B = mk.inport("\\B", i); +		int S = mk.inport(ID(S)); +		for (int i = 0; i < GetSize(cell->getPort(ID::Y)); i++) { +			int A = mk.inport(ID::A, i); +			int B = mk.inport(ID::B, i);  			int Y = mk.mux_gate(A, B, S); -			mk.outport(Y, "\\Y", i); +			if (cell->type == ID($_NMUX_)) +				Y = mk.not_gate(Y); +			mk.outport(Y, ID::Y, i);  		}  		goto optimize;  	} -	if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool")) +	if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool)))  	{ -		int Y = mk.inport("\\A", 0); -		for (int i = 1; i < GetSize(cell->getPort("\\A")); i++) { -			int A = mk.inport("\\A", i); -			if (cell->type == "$reduce_and")  Y = mk.and_gate(A, Y); -			if (cell->type == "$reduce_or")   Y = mk.or_gate(A, Y); -			if (cell->type == "$reduce_bool") Y = mk.or_gate(A, Y); -			if (cell->type == "$reduce_xor")  Y = mk.xor_gate(A, Y); -			if (cell->type == "$reduce_xnor") Y = mk.xor_gate(A, Y); +		int Y = mk.inport(ID::A, 0); +		for (int i = 1; i < GetSize(cell->getPort(ID::A)); i++) { +			int A = mk.inport(ID::A, i); +			if (cell->type == ID($reduce_and))  Y = mk.and_gate(A, Y); +			if (cell->type == ID($reduce_or))   Y = mk.or_gate(A, Y); +			if (cell->type == ID($reduce_bool)) Y = mk.or_gate(A, Y); +			if (cell->type == ID($reduce_xor))  Y = mk.xor_gate(A, Y); +			if (cell->type == ID($reduce_xnor)) Y = mk.xor_gate(A, Y);  		} -		if (cell->type == "$reduce_xnor") +		if (cell->type == ID($reduce_xnor))  			Y = mk.not_gate(Y); -		mk.outport(Y, "\\Y", 0); -		for (int i = 1; i < GetSize(cell->getPort("\\Y")); i++) -			mk.outport(mk.bool_node(false), "\\Y", i); +		mk.outport(Y, ID::Y, 0); +		for (int i = 1; i < GetSize(cell->getPort(ID::Y)); i++) +			mk.outport(mk.bool_node(false), ID::Y, i);  		goto optimize;  	} -	if (cell->type.in("$logic_not", "$logic_and", "$logic_or")) +	if (cell->type.in(ID($logic_not), ID($logic_and), ID($logic_or)))  	{ -		int A = mk.inport("\\A", 0), Y = -1; -		for (int i = 1; i < GetSize(cell->getPort("\\A")); i++) -			A = mk.or_gate(mk.inport("\\A", i), A); -		if (cell->type.in("$logic_and", "$logic_or")) { -			int B = mk.inport("\\B", 0); -			for (int i = 1; i < GetSize(cell->getPort("\\B")); i++) -				B = mk.or_gate(mk.inport("\\B", i), B); -			if (cell->type == "$logic_and") Y = mk.and_gate(A, B); -			if (cell->type == "$logic_or")  Y = mk.or_gate(A, B); +		int A = mk.inport(ID::A, 0), Y = -1; +		for (int i = 1; i < GetSize(cell->getPort(ID::A)); i++) +			A = mk.or_gate(mk.inport(ID::A, i), A); +		if (cell->type.in(ID($logic_and), ID($logic_or))) { +			int B = mk.inport(ID::B, 0); +			for (int i = 1; i < GetSize(cell->getPort(ID::B)); i++) +				B = mk.or_gate(mk.inport(ID::B, i), B); +			if (cell->type == ID($logic_and)) Y = mk.and_gate(A, B); +			if (cell->type == ID($logic_or))  Y = mk.or_gate(A, B);  		} else { -			if (cell->type == "$logic_not") Y = mk.not_gate(A); +			if (cell->type == ID($logic_not)) Y = mk.not_gate(A);  		} -		mk.outport_bool(Y, "\\Y"); +		mk.outport_bool(Y, ID::Y);  		goto optimize;  	} -	if (cell->type.in("$add", "$sub")) +	if (cell->type.in(ID($add), ID($sub)))  	{ -		int width = GetSize(cell->getPort("\\Y")); -		vector<int> A = mk.inport_vec("\\A", width); -		vector<int> B = mk.inport_vec("\\B", width); +		int width = GetSize(cell->getPort(ID::Y)); +		vector<int> A = mk.inport_vec(ID::A, width); +		vector<int> B = mk.inport_vec(ID::B, width);  		int carry = mk.bool_node(false); -		if (cell->type == "$sub") { +		if (cell->type == ID($sub)) {  			for (auto &n : B)  				n = mk.not_gate(n);  			carry = mk.not_gate(carry);  		}  		vector<int> Y = mk.adder(A, B, carry); -		mk.outport_vec(Y, "\\Y"); +		mk.outport_vec(Y, ID::Y);  		goto optimize;  	} -	if (cell->type == "$alu") +	if (cell->type == ID($alu))  	{ -		int width = GetSize(cell->getPort("\\Y")); -		vector<int> A = mk.inport_vec("\\A", width); -		vector<int> B = mk.inport_vec("\\B", width); -		int carry = mk.inport("\\CI"); -		int binv = mk.inport("\\BI"); +		int width = GetSize(cell->getPort(ID::Y)); +		vector<int> A = mk.inport_vec(ID::A, width); +		vector<int> B = mk.inport_vec(ID::B, width); +		int carry = mk.inport(ID(CI)); +		int binv = mk.inport(ID(BI));  		for (auto &n : B)  			n = mk.xor_gate(n, binv);  		vector<int> X(width), CO(width);  		vector<int> Y = mk.adder(A, B, carry, &X, &CO);  		for (int i = 0; i < width; i++)  			X[i] = mk.xor_gate(A[i], B[i]); -		mk.outport_vec(Y, "\\Y"); -		mk.outport_vec(X, "\\X"); -		mk.outport_vec(CO, "\\CO"); +		mk.outport_vec(Y, ID::Y); +		mk.outport_vec(X, ID(X)); +		mk.outport_vec(CO, ID(CO));  		goto optimize;  	} -	if (cell->type.in("$eq", "$ne")) +	if (cell->type.in(ID($eq), ID($ne)))  	{ -		int width = max(GetSize(cell->getPort("\\A")), GetSize(cell->getPort("\\B"))); -		vector<int> A = mk.inport_vec("\\A", width); -		vector<int> B = mk.inport_vec("\\B", width); +		int width = max(GetSize(cell->getPort(ID::A)), GetSize(cell->getPort(ID::B))); +		vector<int> A = mk.inport_vec(ID::A, width); +		vector<int> B = mk.inport_vec(ID::B, width);  		int Y = mk.bool_node(false);  		for (int i = 0; i < width; i++)  			Y = mk.or_gate(Y, mk.xor_gate(A[i], B[i])); -		if (cell->type == "$eq") +		if (cell->type == ID($eq))  			Y = mk.not_gate(Y); -		mk.outport_bool(Y, "\\Y"); +		mk.outport_bool(Y, ID::Y);  		goto optimize;  	} -	if (cell->type == "$_AOI3_") +	if (cell->type == ID($_AOI3_))  	{ -		int A = mk.inport("\\A"); -		int B = mk.inport("\\B"); -		int C = mk.inport("\\C"); +		int A = mk.inport(ID::A); +		int B = mk.inport(ID::B); +		int C = mk.inport(ID(C));  		int Y = mk.nor_gate(mk.and_gate(A, B), C); -		mk.outport(Y, "\\Y"); +		mk.outport(Y, ID::Y);  		goto optimize;  	} -	if (cell->type == "$_OAI3_") +	if (cell->type == ID($_OAI3_))  	{ -		int A = mk.inport("\\A"); -		int B = mk.inport("\\B"); -		int C = mk.inport("\\C"); +		int A = mk.inport(ID::A); +		int B = mk.inport(ID::B); +		int C = mk.inport(ID(C));  		int Y = mk.nand_gate(mk.or_gate(A, B), C); -		mk.outport(Y, "\\Y"); +		mk.outport(Y, ID::Y);  		goto optimize;  	} -	if (cell->type == "$_AOI4_") +	if (cell->type == ID($_AOI4_))  	{ -		int A = mk.inport("\\A"); -		int B = mk.inport("\\B"); -		int C = mk.inport("\\C"); -		int D = mk.inport("\\D"); +		int A = mk.inport(ID::A); +		int B = mk.inport(ID::B); +		int C = mk.inport(ID(C)); +		int D = mk.inport(ID(D));  		int Y = mk.nor_gate(mk.and_gate(A, B), mk.and_gate(C, D)); -		mk.outport(Y, "\\Y"); +		mk.outport(Y, ID::Y);  		goto optimize;  	} -	if (cell->type == "$_OAI4_") +	if (cell->type == ID($_OAI4_))  	{ -		int A = mk.inport("\\A"); -		int B = mk.inport("\\B"); -		int C = mk.inport("\\C"); -		int D = mk.inport("\\D"); +		int A = mk.inport(ID::A); +		int B = mk.inport(ID::B); +		int C = mk.inport(ID(C)); +		int D = mk.inport(ID(D));  		int Y = mk.nand_gate(mk.or_gate(A, B), mk.or_gate(C, D)); -		mk.outport(Y, "\\Y"); +		mk.outport(Y, ID::Y);  		goto optimize;  	} diff --git a/kernel/celledges.cc b/kernel/celledges.cc index 556e8b826..d0bb99e83 100644 --- a/kernel/celledges.cc +++ b/kernel/celledges.cc @@ -24,9 +24,9 @@ PRIVATE_NAMESPACE_BEGIN  void bitwise_unary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)  { -	IdString A = "\\A", Y = "\\Y"; +	IdString A = ID::A, Y = ID::Y; -	bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); +	bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();  	int a_width = GetSize(cell->getPort(A));  	int y_width = GetSize(cell->getPort(Y)); @@ -41,14 +41,14 @@ void bitwise_unary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)  void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)  { -	IdString A = "\\A", B = "\\B", Y = "\\Y"; +	IdString A = ID::A, B = ID::B, Y = ID::Y; -	bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); +	bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();  	int a_width = GetSize(cell->getPort(A));  	int b_width = GetSize(cell->getPort(B));  	int y_width = GetSize(cell->getPort(Y)); -	if (cell->type == "$and" && !is_signed) { +	if (cell->type == ID($and) && !is_signed) {  		if (a_width > b_width)  			a_width = b_width;  		else @@ -71,9 +71,9 @@ void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)  void arith_neg_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)  { -	IdString A = "\\A", Y = "\\Y"; +	IdString A = ID::A, Y = ID::Y; -	bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); +	bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();  	int a_width = GetSize(cell->getPort(A));  	int y_width = GetSize(cell->getPort(Y)); @@ -87,14 +87,14 @@ void arith_neg_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)  void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)  { -	IdString A = "\\A", B = "\\B", Y = "\\Y"; +	IdString A = ID::A, B = ID::B, Y = ID::Y; -	bool is_signed = cell->getParam("\\A_SIGNED").as_bool(); +	bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();  	int a_width = GetSize(cell->getPort(A));  	int b_width = GetSize(cell->getPort(B));  	int y_width = GetSize(cell->getPort(Y)); -	if (!is_signed && cell->type != "$sub") { +	if (!is_signed && cell->type != ID($sub)) {  		int ab_width = std::max(a_width, b_width);  		y_width = std::min(y_width, ab_width+1);  	} @@ -114,7 +114,7 @@ void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)  void reduce_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)  { -	IdString A = "\\A", Y = "\\Y"; +	IdString A = ID::A, Y = ID::Y;  	int a_width = GetSize(cell->getPort(A)); @@ -124,7 +124,7 @@ void reduce_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)  void compare_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)  { -	IdString A = "\\A", B = "\\B", Y = "\\Y"; +	IdString A = ID::A, B = ID::B, Y = ID::Y;  	int a_width = GetSize(cell->getPort(A));  	int b_width = GetSize(cell->getPort(B)); @@ -138,7 +138,7 @@ void compare_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)  void mux_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)  { -	IdString A = "\\A", B = "\\B", S = "\\S", Y = "\\Y"; +	IdString A = ID::A, B = ID::B, S = ID(S), Y = ID::Y;  	int a_width = GetSize(cell->getPort(A));  	int b_width = GetSize(cell->getPort(B)); @@ -160,43 +160,43 @@ PRIVATE_NAMESPACE_END  bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL::Cell *cell)  { -	if (cell->type.in("$not", "$pos")) { +	if (cell->type.in(ID($not), ID($pos))) {  		bitwise_unary_op(this, cell);  		return true;  	} -	if (cell->type.in("$and", "$or", "$xor", "$xnor")) { +	if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor))) {  		bitwise_binary_op(this, cell);  		return true;  	} -	if (cell->type == "$neg") { +	if (cell->type == ID($neg)) {  		arith_neg_op(this, cell);  		return true;  	} -	if (cell->type.in("$add", "$sub")) { +	if (cell->type.in(ID($add), ID($sub))) {  		arith_binary_op(this, cell);  		return true;  	} -	if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool", "$logic_not")) { +	if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($logic_not))) {  		reduce_op(this, cell);  		return true;  	}  	// FIXME: -	// if (cell->type.in("$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx")) { +	// if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) {  	// 	shift_op(this, cell);  	// 	return true;  	// } -	if (cell->type.in("$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt")) { +	if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt))) {  		compare_op(this, cell);  		return true;  	} -	if (cell->type.in("$mux", "$pmux")) { +	if (cell->type.in(ID($mux), ID($pmux))) {  		mux_op(this, cell);  		return true;  	} diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 758661c02..bc96fd602 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -84,46 +84,46 @@ struct CellTypes  	{  		setup_internals_eval(); -		IdString A = "\\A", B = "\\B", EN = "\\EN", Y = "\\Y"; -		IdString SRC = "\\SRC", DST = "\\DST", DAT = "\\DAT"; -		IdString EN_SRC = "\\EN_SRC", EN_DST = "\\EN_DST"; - -		setup_type("$tribuf", {A, EN}, {Y}, true); - -		setup_type("$assert", {A, EN}, pool<RTLIL::IdString>(), true); -		setup_type("$assume", {A, EN}, pool<RTLIL::IdString>(), true); -		setup_type("$live", {A, EN}, pool<RTLIL::IdString>(), true); -		setup_type("$fair", {A, EN}, pool<RTLIL::IdString>(), true); -		setup_type("$cover", {A, EN}, pool<RTLIL::IdString>(), true); -		setup_type("$initstate", pool<RTLIL::IdString>(), {Y}, true); -		setup_type("$anyconst", pool<RTLIL::IdString>(), {Y}, true); -		setup_type("$anyseq", pool<RTLIL::IdString>(), {Y}, true); -		setup_type("$allconst", pool<RTLIL::IdString>(), {Y}, true); -		setup_type("$allseq", pool<RTLIL::IdString>(), {Y}, true); -		setup_type("$equiv", {A, B}, {Y}, true); -		setup_type("$specify2", {EN, SRC, DST}, pool<RTLIL::IdString>(), true); -		setup_type("$specify3", {EN, SRC, DST, DAT}, pool<RTLIL::IdString>(), true); -		setup_type("$specrule", {EN_SRC, EN_DST, SRC, DST}, pool<RTLIL::IdString>(), true); +		IdString A = ID::A, B = ID::B, EN = ID(EN), Y = ID::Y; +		IdString SRC = ID(SRC), DST = ID(DST), DAT = ID(DAT); +		IdString EN_SRC = ID(EN_SRC), EN_DST = ID(EN_DST); + +		setup_type(ID($tribuf), {A, EN}, {Y}, true); + +		setup_type(ID($assert), {A, EN}, pool<RTLIL::IdString>(), true); +		setup_type(ID($assume), {A, EN}, pool<RTLIL::IdString>(), true); +		setup_type(ID($live), {A, EN}, pool<RTLIL::IdString>(), true); +		setup_type(ID($fair), {A, EN}, pool<RTLIL::IdString>(), true); +		setup_type(ID($cover), {A, EN}, pool<RTLIL::IdString>(), true); +		setup_type(ID($initstate), pool<RTLIL::IdString>(), {Y}, true); +		setup_type(ID($anyconst), pool<RTLIL::IdString>(), {Y}, true); +		setup_type(ID($anyseq), pool<RTLIL::IdString>(), {Y}, true); +		setup_type(ID($allconst), pool<RTLIL::IdString>(), {Y}, true); +		setup_type(ID($allseq), pool<RTLIL::IdString>(), {Y}, true); +		setup_type(ID($equiv), {A, B}, {Y}, true); +		setup_type(ID($specify2), {EN, SRC, DST}, pool<RTLIL::IdString>(), true); +		setup_type(ID($specify3), {EN, SRC, DST, DAT}, pool<RTLIL::IdString>(), true); +		setup_type(ID($specrule), {EN_SRC, EN_DST, SRC, DST}, pool<RTLIL::IdString>(), true);  	}  	void setup_internals_eval()  	{  		std::vector<RTLIL::IdString> unary_ops = { -			"$not", "$pos", "$neg", -			"$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool", -			"$logic_not", "$slice", "$lut", "$sop" +			ID($not), ID($pos), ID($neg), +			ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), +			ID($logic_not), ID($slice), ID($lut), ID($sop)  		};  		std::vector<RTLIL::IdString> binary_ops = { -			"$and", "$or", "$xor", "$xnor", -			"$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", -			"$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt", -			"$add", "$sub", "$mul", "$div", "$mod", "$pow", -			"$logic_and", "$logic_or", "$concat", "$macc" +			ID($and), ID($or), ID($xor), ID($xnor), +			ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx), +			ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt), +			ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow), +			ID($logic_and), ID($logic_or), ID($concat), ID($macc)  		}; -		IdString A = "\\A", B = "\\B", S = "\\S", Y = "\\Y"; -		IdString P = "\\P", G = "\\G", C = "\\C", X = "\\X"; -		IdString BI = "\\BI", CI = "\\CI", CO = "\\CO", EN = "\\EN"; +		IdString A = ID::A, B = ID::B, S = ID(S), Y = ID::Y; +		IdString P = ID(P), G = ID(G), C = ID(C), X = ID(X); +		IdString BI = ID(BI), CI = ID(CI), CO = ID(CO), EN = ID(EN);  		for (auto type : unary_ops)  			setup_type(type, {A}, {Y}, true); @@ -131,81 +131,91 @@ struct CellTypes  		for (auto type : binary_ops)  			setup_type(type, {A, B}, {Y}, true); -		for (auto type : std::vector<RTLIL::IdString>({"$mux", "$pmux"})) +		for (auto type : std::vector<RTLIL::IdString>({ID($mux), ID($pmux)}))  			setup_type(type, {A, B, S}, {Y}, true); -		setup_type("$lcu", {P, G, CI}, {CO}, true); -		setup_type("$alu", {A, B, CI, BI}, {X, Y, CO}, true); -		setup_type("$fa", {A, B, C}, {X, Y}, true); +		setup_type(ID($lcu), {P, G, CI}, {CO}, true); +		setup_type(ID($alu), {A, B, CI, BI}, {X, Y, CO}, true); +		setup_type(ID($fa), {A, B, C}, {X, Y}, true); +	} + +	void setup_internals_ff() +	{ +		IdString SET = ID(SET), CLR = ID(CLR), CLK = ID(CLK), ARST = ID(ARST), EN = ID(EN); +		IdString Q = ID(Q), D = ID(D); + +		setup_type(ID($sr), {SET, CLR}, {Q}); +		setup_type(ID($ff), {D}, {Q}); +		setup_type(ID($dff), {CLK, D}, {Q}); +		setup_type(ID($dffe), {CLK, EN, D}, {Q}); +		setup_type(ID($dffsr), {CLK, SET, CLR, D}, {Q}); +		setup_type(ID($adff), {CLK, ARST, D}, {Q}); +		setup_type(ID($dlatch), {EN, D}, {Q}); +		setup_type(ID($dlatchsr), {EN, SET, CLR, D}, {Q}); +  	}  	void setup_internals_mem()  	{ -		IdString SET = "\\SET", CLR = "\\CLR", CLK = "\\CLK", ARST = "\\ARST", EN = "\\EN"; -		IdString Q = "\\Q", D = "\\D", ADDR = "\\ADDR", DATA = "\\DATA", RD_EN = "\\RD_EN"; -		IdString RD_CLK = "\\RD_CLK", RD_ADDR = "\\RD_ADDR", WR_CLK = "\\WR_CLK", WR_EN = "\\WR_EN"; -		IdString WR_ADDR = "\\WR_ADDR", WR_DATA = "\\WR_DATA", RD_DATA = "\\RD_DATA"; -		IdString CTRL_IN = "\\CTRL_IN", CTRL_OUT = "\\CTRL_OUT"; - -		setup_type("$sr", {SET, CLR}, {Q}); -		setup_type("$ff", {D}, {Q}); -		setup_type("$dff", {CLK, D}, {Q}); -		setup_type("$dffe", {CLK, EN, D}, {Q}); -		setup_type("$dffsr", {CLK, SET, CLR, D}, {Q}); -		setup_type("$adff", {CLK, ARST, D}, {Q}); -		setup_type("$dlatch", {EN, D}, {Q}); -		setup_type("$dlatchsr", {EN, SET, CLR, D}, {Q}); - -		setup_type("$memrd", {CLK, EN, ADDR}, {DATA}); -		setup_type("$memwr", {CLK, EN, ADDR, DATA}, pool<RTLIL::IdString>()); -		setup_type("$meminit", {ADDR, DATA}, pool<RTLIL::IdString>()); -		setup_type("$mem", {RD_CLK, RD_EN, RD_ADDR, WR_CLK, WR_EN, WR_ADDR, WR_DATA}, {RD_DATA}); - -		setup_type("$fsm", {CLK, ARST, CTRL_IN}, {CTRL_OUT}); +		setup_internals_ff(); + +		IdString CLK = ID(CLK), ARST = ID(ARST), EN = ID(EN); +		IdString ADDR = ID(ADDR), DATA = ID(DATA), RD_EN = ID(RD_EN); +		IdString RD_CLK = ID(RD_CLK), RD_ADDR = ID(RD_ADDR), WR_CLK = ID(WR_CLK), WR_EN = ID(WR_EN); +		IdString WR_ADDR = ID(WR_ADDR), WR_DATA = ID(WR_DATA), RD_DATA = ID(RD_DATA); +		IdString CTRL_IN = ID(CTRL_IN), CTRL_OUT = ID(CTRL_OUT); + +		setup_type(ID($memrd), {CLK, EN, ADDR}, {DATA}); +		setup_type(ID($memwr), {CLK, EN, ADDR, DATA}, pool<RTLIL::IdString>()); +		setup_type(ID($meminit), {ADDR, DATA}, pool<RTLIL::IdString>()); +		setup_type(ID($mem), {RD_CLK, RD_EN, RD_ADDR, WR_CLK, WR_EN, WR_ADDR, WR_DATA}, {RD_DATA}); + +		setup_type(ID($fsm), {CLK, ARST, CTRL_IN}, {CTRL_OUT});  	}  	void setup_stdcells()  	{  		setup_stdcells_eval(); -		IdString A = "\\A", E = "\\E", Y = "\\Y"; +		IdString A = ID::A, E = ID(E), Y = ID::Y; -		setup_type("$_TBUF_", {A, E}, {Y}, true); +		setup_type(ID($_TBUF_), {A, E}, {Y}, true);  	}  	void setup_stdcells_eval()  	{ -		IdString A = "\\A", B = "\\B", C = "\\C", D = "\\D"; -		IdString E = "\\E", F = "\\F", G = "\\G", H = "\\H"; -		IdString I = "\\I", J = "\\J", K = "\\K", L = "\\L"; -		IdString M = "\\M", N = "\\N", O = "\\O", P = "\\P"; -		IdString S = "\\S", T = "\\T", U = "\\U", V = "\\V"; -		IdString Y = "\\Y"; - -		setup_type("$_BUF_", {A}, {Y}, true); -		setup_type("$_NOT_", {A}, {Y}, true); -		setup_type("$_AND_", {A, B}, {Y}, true); -		setup_type("$_NAND_", {A, B}, {Y}, true); -		setup_type("$_OR_",  {A, B}, {Y}, true); -		setup_type("$_NOR_",  {A, B}, {Y}, true); -		setup_type("$_XOR_", {A, B}, {Y}, true); -		setup_type("$_XNOR_", {A, B}, {Y}, true); -		setup_type("$_ANDNOT_", {A, B}, {Y}, true); -		setup_type("$_ORNOT_", {A, B}, {Y}, true); -		setup_type("$_MUX_", {A, B, S}, {Y}, true); -		setup_type("$_MUX4_", {A, B, C, D, S, T}, {Y}, true); -		setup_type("$_MUX8_", {A, B, C, D, E, F, G, H, S, T, U}, {Y}, true); -		setup_type("$_MUX16_", {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V}, {Y}, true); -		setup_type("$_AOI3_", {A, B, C}, {Y}, true); -		setup_type("$_OAI3_", {A, B, C}, {Y}, true); -		setup_type("$_AOI4_", {A, B, C, D}, {Y}, true); -		setup_type("$_OAI4_", {A, B, C, D}, {Y}, true); +		IdString A = ID::A, B = ID::B, C = ID(C), D = ID(D); +		IdString E = ID(E), F = ID(F), G = ID(G), H = ID(H); +		IdString I = ID(I), J = ID(J), K = ID(K), L = ID(L); +		IdString M = ID(M), N = ID(N), O = ID(O), P = ID(P); +		IdString S = ID(S), T = ID(T), U = ID(U), V = ID(V); +		IdString Y = ID::Y; + +		setup_type(ID($_BUF_), {A}, {Y}, true); +		setup_type(ID($_NOT_), {A}, {Y}, true); +		setup_type(ID($_AND_), {A, B}, {Y}, true); +		setup_type(ID($_NAND_), {A, B}, {Y}, true); +		setup_type(ID($_OR_),  {A, B}, {Y}, true); +		setup_type(ID($_NOR_),  {A, B}, {Y}, true); +		setup_type(ID($_XOR_), {A, B}, {Y}, true); +		setup_type(ID($_XNOR_), {A, B}, {Y}, true); +		setup_type(ID($_ANDNOT_), {A, B}, {Y}, true); +		setup_type(ID($_ORNOT_), {A, B}, {Y}, true); +		setup_type(ID($_MUX_), {A, B, S}, {Y}, true); +		setup_type(ID($_NMUX_), {A, B, S}, {Y}, true); +		setup_type(ID($_MUX4_), {A, B, C, D, S, T}, {Y}, true); +		setup_type(ID($_MUX8_), {A, B, C, D, E, F, G, H, S, T, U}, {Y}, true); +		setup_type(ID($_MUX16_), {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V}, {Y}, true); +		setup_type(ID($_AOI3_), {A, B, C}, {Y}, true); +		setup_type(ID($_OAI3_), {A, B, C}, {Y}, true); +		setup_type(ID($_AOI4_), {A, B, C, D}, {Y}, true); +		setup_type(ID($_OAI4_), {A, B, C, D}, {Y}, true);  	}  	void setup_stdcells_mem()  	{ -		IdString S = "\\S", R = "\\R", C = "\\C"; -		IdString D = "\\D", Q = "\\Q", E = "\\E"; +		IdString S = ID(S), R = ID(R), C = ID(C); +		IdString D = ID(D), Q = ID(Q), E = ID(E);  		std::vector<char> list_np = {'N', 'P'}, list_01 = {'0', '1'}; @@ -213,7 +223,7 @@ struct CellTypes  		for (auto c2 : list_np)  			setup_type(stringf("$_SR_%c%c_", c1, c2), {S, R}, {Q}); -		setup_type("$_FF_", {D}, {Q}); +		setup_type(ID($_FF_), {D}, {Q});  		for (auto c1 : list_np)  			setup_type(stringf("$_DFF_%c_", c1), {C, D}, {Q}); @@ -272,20 +282,20 @@ struct CellTypes  	static RTLIL::Const eval_not(RTLIL::Const v)  	{  		for (auto &bit : v.bits) -			if (bit == RTLIL::S0) bit = RTLIL::S1; -			else if (bit == RTLIL::S1) bit = RTLIL::S0; +			if (bit == State::S0) bit = State::S1; +			else if (bit == State::S1) bit = State::S0;  		return v;  	}  	static RTLIL::Const eval(RTLIL::IdString type, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len, bool *errp = nullptr)  	{ -		if (type == "$sshr" && !signed1) -			type = "$shr"; -		if (type == "$sshl" && !signed1) -			type = "$shl"; +		if (type == ID($sshr) && !signed1) +			type = ID($shr); +		if (type == ID($sshl) && !signed1) +			type = ID($shl); -		if (type != "$sshr" && type != "$sshl" && type != "$shr" && type != "$shl" && type != "$shift" && type != "$shiftx" && -				type != "$pos" && type != "$neg" && type != "$not") { +		if (type != ID($sshr) && type != ID($sshl) && type != ID($shr) && type != ID($shl) && type != ID($shift) && type != ID($shiftx) && +				type != ID($pos) && type != ID($neg) && type != ID($not)) {  			if (!signed1 || !signed2)  				signed1 = false, signed2 = false;  		} @@ -328,25 +338,25 @@ struct CellTypes  		HANDLE_CELL_TYPE(neg)  #undef HANDLE_CELL_TYPE -		if (type == "$_BUF_") +		if (type == ID($_BUF_))  			return arg1; -		if (type == "$_NOT_") +		if (type == ID($_NOT_))  			return eval_not(arg1); -		if (type == "$_AND_") +		if (type == ID($_AND_))  			return const_and(arg1, arg2, false, false, 1); -		if (type == "$_NAND_") +		if (type == ID($_NAND_))  			return eval_not(const_and(arg1, arg2, false, false, 1)); -		if (type == "$_OR_") +		if (type == ID($_OR_))  			return const_or(arg1, arg2, false, false, 1); -		if (type == "$_NOR_") +		if (type == ID($_NOR_))  			return eval_not(const_or(arg1, arg2, false, false, 1)); -		if (type == "$_XOR_") +		if (type == ID($_XOR_))  			return const_xor(arg1, arg2, false, false, 1); -		if (type == "$_XNOR_") +		if (type == ID($_XNOR_))  			return const_xnor(arg1, arg2, false, false, 1); -		if (type == "$_ANDNOT_") +		if (type == ID($_ANDNOT_))  			return const_and(arg1, eval_not(arg2), false, false, 1); -		if (type == "$_ORNOT_") +		if (type == ID($_ORNOT_))  			return const_or(arg1, eval_not(arg2), false, false, 1);  		if (errp != nullptr) { @@ -359,35 +369,35 @@ struct CellTypes  	static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool *errp = nullptr)  	{ -		if (cell->type == "$slice") { +		if (cell->type == ID($slice)) {  			RTLIL::Const ret; -			int width = cell->parameters.at("\\Y_WIDTH").as_int(); -			int offset = cell->parameters.at("\\OFFSET").as_int(); +			int width = cell->parameters.at(ID(Y_WIDTH)).as_int(); +			int offset = cell->parameters.at(ID(OFFSET)).as_int();  			ret.bits.insert(ret.bits.end(), arg1.bits.begin()+offset, arg1.bits.begin()+offset+width);  			return ret;  		} -		if (cell->type == "$concat") { +		if (cell->type == ID($concat)) {  			RTLIL::Const ret = arg1;  			ret.bits.insert(ret.bits.end(), arg2.bits.begin(), arg2.bits.end());  			return ret;  		} -		if (cell->type == "$lut") +		if (cell->type == ID($lut))  		{ -			int width = cell->parameters.at("\\WIDTH").as_int(); +			int width = cell->parameters.at(ID(WIDTH)).as_int(); -			std::vector<RTLIL::State> t = cell->parameters.at("\\LUT").bits; +			std::vector<RTLIL::State> t = cell->parameters.at(ID(LUT)).bits;  			while (GetSize(t) < (1 << width)) -				t.push_back(RTLIL::S0); +				t.push_back(State::S0);  			t.resize(1 << width);  			for (int i = width-1; i >= 0; i--) {  				RTLIL::State sel = arg1.bits.at(i);  				std::vector<RTLIL::State> new_t; -				if (sel == RTLIL::S0) +				if (sel == State::S0)  					new_t = std::vector<RTLIL::State>(t.begin(), t.begin() + GetSize(t)/2); -				else if (sel == RTLIL::S1) +				else if (sel == State::S1)  					new_t = std::vector<RTLIL::State>(t.begin() + GetSize(t)/2, t.end());  				else  					for (int j = 0; j < GetSize(t)/2; j++) @@ -399,14 +409,14 @@ struct CellTypes  			return t;  		} -		if (cell->type == "$sop") +		if (cell->type == ID($sop))  		{ -			int width = cell->parameters.at("\\WIDTH").as_int(); -			int depth = cell->parameters.at("\\DEPTH").as_int(); -			std::vector<RTLIL::State> t = cell->parameters.at("\\TABLE").bits; +			int width = cell->parameters.at(ID(WIDTH)).as_int(); +			int depth = cell->parameters.at(ID(DEPTH)).as_int(); +			std::vector<RTLIL::State> t = cell->parameters.at(ID(TABLE)).bits;  			while (GetSize(t) < width*depth*2) -				t.push_back(RTLIL::S0); +				t.push_back(State::S0);  			RTLIL::State default_ret = State::S0; @@ -437,15 +447,15 @@ struct CellTypes  			return default_ret;  		} -		bool signed_a = cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters["\\A_SIGNED"].as_bool(); -		bool signed_b = cell->parameters.count("\\B_SIGNED") > 0 && cell->parameters["\\B_SIGNED"].as_bool(); -		int result_len = cell->parameters.count("\\Y_WIDTH") > 0 ? cell->parameters["\\Y_WIDTH"].as_int() : -1; +		bool signed_a = cell->parameters.count(ID(A_SIGNED)) > 0 && cell->parameters[ID(A_SIGNED)].as_bool(); +		bool signed_b = cell->parameters.count(ID(B_SIGNED)) > 0 && cell->parameters[ID(B_SIGNED)].as_bool(); +		int result_len = cell->parameters.count(ID(Y_WIDTH)) > 0 ? cell->parameters[ID(Y_WIDTH)].as_int() : -1;  		return eval(cell->type, arg1, arg2, signed_a, signed_b, result_len, errp);  	}  	static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, bool *errp = nullptr)  	{ -		if (cell->type.in("$mux", "$pmux", "$_MUX_")) { +		if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_))) {  			RTLIL::Const ret = arg1;  			for (size_t i = 0; i < arg3.bits.size(); i++)  				if (arg3.bits[i] == RTLIL::State::S1) { @@ -455,9 +465,9 @@ struct CellTypes  			return ret;  		} -		if (cell->type == "$_AOI3_") +		if (cell->type == ID($_AOI3_))  			return eval_not(const_or(const_and(arg1, arg2, false, false, 1), arg3, false, false, 1)); -		if (cell->type == "$_OAI3_") +		if (cell->type == ID($_OAI3_))  			return eval_not(const_and(const_or(arg1, arg2, false, false, 1), arg3, false, false, 1));  		log_assert(arg3.bits.size() == 0); @@ -466,9 +476,9 @@ struct CellTypes  	static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, const RTLIL::Const &arg4, bool *errp = nullptr)  	{ -		if (cell->type == "$_AOI4_") +		if (cell->type == ID($_AOI4_))  			return eval_not(const_or(const_and(arg1, arg2, false, false, 1), const_and(arg3, arg4, false, false, 1), false, false, 1)); -		if (cell->type == "$_OAI4_") +		if (cell->type == ID($_OAI4_))  			return eval_not(const_and(const_or(arg1, arg2, false, false, 1), const_or(arg3, arg4, false, false, 1), false, false, 1));  		log_assert(arg4.bits.size() == 0); diff --git a/kernel/consteval.h b/kernel/consteval.h index 154373a8d..7a83d28e7 100644 --- a/kernel/consteval.h +++ b/kernel/consteval.h @@ -89,12 +89,12 @@ struct ConstEval  	bool eval(RTLIL::Cell *cell, RTLIL::SigSpec &undef)  	{ -		if (cell->type == "$lcu") +		if (cell->type == ID($lcu))  		{ -			RTLIL::SigSpec sig_p = cell->getPort("\\P"); -			RTLIL::SigSpec sig_g = cell->getPort("\\G"); -			RTLIL::SigSpec sig_ci = cell->getPort("\\CI"); -			RTLIL::SigSpec sig_co = values_map(assign_map(cell->getPort("\\CO"))); +			RTLIL::SigSpec sig_p = cell->getPort(ID(P)); +			RTLIL::SigSpec sig_g = cell->getPort(ID(G)); +			RTLIL::SigSpec sig_ci = cell->getPort(ID(CI)); +			RTLIL::SigSpec sig_co = values_map(assign_map(cell->getPort(ID(CO))));  			if (sig_co.is_fully_const())  				return true; @@ -114,8 +114,8 @@ struct ConstEval  				bool carry = sig_ci.as_bool();  				for (int i = 0; i < GetSize(coval); i++) { -					carry = (sig_g[i] == RTLIL::S1) || (sig_p[i] == RTLIL::S1 && carry); -					coval.bits[i] = carry ? RTLIL::S1 : RTLIL::S0; +					carry = (sig_g[i] == State::S1) || (sig_p[i] == RTLIL::S1 && carry); +					coval.bits[i] = carry ? State::S1 : State::S0;  				}  				set(sig_co, coval); @@ -128,24 +128,24 @@ struct ConstEval  		RTLIL::SigSpec sig_a, sig_b, sig_s, sig_y; -		log_assert(cell->hasPort("\\Y")); -		sig_y = values_map(assign_map(cell->getPort("\\Y"))); +		log_assert(cell->hasPort(ID::Y)); +		sig_y = values_map(assign_map(cell->getPort(ID::Y)));  		if (sig_y.is_fully_const())  			return true; -		if (cell->hasPort("\\S")) { -			sig_s = cell->getPort("\\S"); +		if (cell->hasPort(ID(S))) { +			sig_s = cell->getPort(ID(S));  			if (!eval(sig_s, undef, cell))  				return false;  		} -		if (cell->hasPort("\\A")) -			sig_a = cell->getPort("\\A"); +		if (cell->hasPort(ID::A)) +			sig_a = cell->getPort(ID::A); -		if (cell->hasPort("\\B")) -			sig_b = cell->getPort("\\B"); +		if (cell->hasPort(ID::B)) +			sig_b = cell->getPort(ID::B); -		if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$_MUX_") +		if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_), ID($_NMUX_)))  		{  			std::vector<RTLIL::SigSpec> y_candidates;  			int count_maybe_set_s_bits = 0; @@ -175,7 +175,10 @@ struct ConstEval  			for (auto &yc : y_candidates) {  				if (!eval(yc, undef, cell))  					return false; -				y_values.push_back(yc.as_const()); +				if (cell->type == ID($_NMUX_)) +					y_values.push_back(RTLIL::const_not(yc.as_const(), Const(), false, false, GetSize(yc))); +				else +					y_values.push_back(yc.as_const());  			}  			if (y_values.size() > 1) @@ -195,10 +198,10 @@ struct ConstEval  			else  				set(sig_y, y_values.front());  		} -		else if (cell->type == "$fa") +		else if (cell->type == ID($fa))  		{ -			RTLIL::SigSpec sig_c = cell->getPort("\\C"); -			RTLIL::SigSpec sig_x = cell->getPort("\\X"); +			RTLIL::SigSpec sig_c = cell->getPort(ID(C)); +			RTLIL::SigSpec sig_x = cell->getPort(ID(X));  			int width = GetSize(sig_c);  			if (!eval(sig_a, undef, cell)) @@ -224,13 +227,13 @@ struct ConstEval  			set(sig_y, val_y);  			set(sig_x, val_x);  		} -		else if (cell->type == "$alu") +		else if (cell->type == ID($alu))  		{ -			bool signed_a = cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters["\\A_SIGNED"].as_bool(); -			bool signed_b = cell->parameters.count("\\B_SIGNED") > 0 && cell->parameters["\\B_SIGNED"].as_bool(); +			bool signed_a = cell->parameters.count(ID(A_SIGNED)) > 0 && cell->parameters[ID(A_SIGNED)].as_bool(); +			bool signed_b = cell->parameters.count(ID(B_SIGNED)) > 0 && cell->parameters[ID(B_SIGNED)].as_bool(); -			RTLIL::SigSpec sig_ci = cell->getPort("\\CI"); -			RTLIL::SigSpec sig_bi = cell->getPort("\\BI"); +			RTLIL::SigSpec sig_ci = cell->getPort(ID(CI)); +			RTLIL::SigSpec sig_bi = cell->getPort(ID(BI));  			if (!eval(sig_a, undef, cell))  				return false; @@ -244,15 +247,15 @@ struct ConstEval  			if (!eval(sig_bi, undef, cell))  				return false; -			RTLIL::SigSpec sig_x = cell->getPort("\\X"); -			RTLIL::SigSpec sig_co = cell->getPort("\\CO"); +			RTLIL::SigSpec sig_x = cell->getPort(ID(X)); +			RTLIL::SigSpec sig_co = cell->getPort(ID(CO));  			bool any_input_undef = !(sig_a.is_fully_def() && sig_b.is_fully_def() && sig_ci.is_fully_def() && sig_bi.is_fully_def());  			sig_a.extend_u0(GetSize(sig_y), signed_a);  			sig_b.extend_u0(GetSize(sig_y), signed_b); -			bool carry = sig_ci[0] == RTLIL::S1; -			bool b_inv = sig_bi[0] == RTLIL::S1; +			bool carry = sig_ci[0] == State::S1; +			bool b_inv = sig_bi[0] == State::S1;  			for (int i = 0; i < GetSize(sig_y); i++)  			{ @@ -261,26 +264,26 @@ struct ConstEval  				if (!x_inputs.is_fully_def()) {  					set(sig_x[i], RTLIL::Sx);  				} else { -					bool bit_a = sig_a[i] == RTLIL::S1; -					bool bit_b = (sig_b[i] == RTLIL::S1) != b_inv; +					bool bit_a = sig_a[i] == State::S1; +					bool bit_b = (sig_b[i] == State::S1) != b_inv;  					bool bit_x = bit_a != bit_b; -					set(sig_x[i], bit_x ? RTLIL::S1 : RTLIL::S0); +					set(sig_x[i], bit_x ? State::S1 : State::S0);  				}  				if (any_input_undef) {  					set(sig_y[i], RTLIL::Sx);  					set(sig_co[i], RTLIL::Sx);  				} else { -					bool bit_a = sig_a[i] == RTLIL::S1; -					bool bit_b = (sig_b[i] == RTLIL::S1) != b_inv; +					bool bit_a = sig_a[i] == State::S1; +					bool bit_b = (sig_b[i] == State::S1) != b_inv;  					bool bit_y = (bit_a != bit_b) != carry;  					carry = (bit_a && bit_b) || (bit_a && carry) || (bit_b && carry); -					set(sig_y[i], bit_y ? RTLIL::S1 : RTLIL::S0); -					set(sig_co[i], carry ? RTLIL::S1 : RTLIL::S0); +					set(sig_y[i], bit_y ? State::S1 : State::S0); +					set(sig_co[i], carry ? State::S1 : State::S0);  				}  			}  		} -		else if (cell->type == "$macc") +		else if (cell->type == ID($macc))  		{  			Macc macc;  			macc.from_cell(cell); @@ -295,21 +298,21 @@ struct ConstEval  					return false;  			} -			RTLIL::Const result(0, GetSize(cell->getPort("\\Y"))); +			RTLIL::Const result(0, GetSize(cell->getPort(ID::Y)));  			if (!macc.eval(result))  				log_abort(); -			set(cell->getPort("\\Y"), result); +			set(cell->getPort(ID::Y), result);  		}  		else  		{  			RTLIL::SigSpec sig_c, sig_d; -			if (cell->type.in("$_AOI3_", "$_OAI3_", "$_AOI4_", "$_OAI4_")) { -				if (cell->hasPort("\\C")) -					sig_c = cell->getPort("\\C"); -				if (cell->hasPort("\\D")) -					sig_d = cell->getPort("\\D"); +			if (cell->type.in(ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_))) { +				if (cell->hasPort(ID(C))) +					sig_c = cell->getPort(ID(C)); +				if (cell->hasPort(ID(D))) +					sig_d = cell->getPort(ID(D));  			}  			if (sig_a.size() > 0 && !eval(sig_a, undef, cell)) diff --git a/kernel/cost.h b/kernel/cost.h index 41a09eb63..ea2a4c1f0 100644 --- a/kernel/cost.h +++ b/kernel/cost.h @@ -24,62 +24,92 @@  YOSYS_NAMESPACE_BEGIN -int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr); - -inline int get_cell_cost(RTLIL::IdString type, const dict<RTLIL::IdString, RTLIL::Const> ¶meters = dict<RTLIL::IdString, RTLIL::Const>(), -		RTLIL::Design *design = nullptr, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr) +struct CellCosts  { -	static dict<RTLIL::IdString, int> gate_cost = { -		{ "$_BUF_",    1 }, -		{ "$_NOT_",    2 }, -		{ "$_AND_",    4 }, -		{ "$_NAND_",   4 }, -		{ "$_OR_",     4 }, -		{ "$_NOR_",    4 }, -		{ "$_ANDNOT_", 4 }, -		{ "$_ORNOT_",  4 }, -		{ "$_XOR_",    8 }, -		{ "$_XNOR_",   8 }, -		{ "$_AOI3_",   6 }, -		{ "$_OAI3_",   6 }, -		{ "$_AOI4_",   8 }, -		{ "$_OAI4_",   8 }, -		{ "$_MUX_",    4 } -	}; - -	if (gate_cost.count(type)) -		return gate_cost.at(type); - -	if (parameters.empty() && design && design->module(type)) +	static const dict<RTLIL::IdString, int>& default_gate_cost() { +		static const dict<RTLIL::IdString, int> db = { +			{ ID($_BUF_),    1 }, +			{ ID($_NOT_),    2 }, +			{ ID($_AND_),    4 }, +			{ ID($_NAND_),   4 }, +			{ ID($_OR_),     4 }, +			{ ID($_NOR_),    4 }, +			{ ID($_ANDNOT_), 4 }, +			{ ID($_ORNOT_),  4 }, +			{ ID($_XOR_),    5 }, +			{ ID($_XNOR_),   5 }, +			{ ID($_AOI3_),   6 }, +			{ ID($_OAI3_),   6 }, +			{ ID($_AOI4_),   7 }, +			{ ID($_OAI4_),   7 }, +			{ ID($_MUX_),    4 }, +			{ ID($_NMUX_),   4 } +		}; +		return db; +	} + +	static const dict<RTLIL::IdString, int>& cmos_gate_cost() { +		static const dict<RTLIL::IdString, int> db = { +			{ ID($_BUF_),     1 }, +			{ ID($_NOT_),     2 }, +			{ ID($_AND_),     6 }, +			{ ID($_NAND_),    4 }, +			{ ID($_OR_),      6 }, +			{ ID($_NOR_),     4 }, +			{ ID($_ANDNOT_),  6 }, +			{ ID($_ORNOT_),   6 }, +			{ ID($_XOR_),    12 }, +			{ ID($_XNOR_),   12 }, +			{ ID($_AOI3_),    6 }, +			{ ID($_OAI3_),    6 }, +			{ ID($_AOI4_),    8 }, +			{ ID($_OAI4_),    8 }, +			{ ID($_MUX_),    12 }, +			{ ID($_NMUX_),   10 } +		}; +		return db; +	} + +	dict<RTLIL::IdString, int> mod_cost_cache; +	const dict<RTLIL::IdString, int> *gate_cost = nullptr; +	Design *design = nullptr; + +	int get(RTLIL::IdString type) const  	{ -		RTLIL::Module *mod = design->module(type); +		if (gate_cost && gate_cost->count(type)) +			return gate_cost->at(type); -		if (mod->attributes.count("\\cost")) -			return mod->attributes.at("\\cost").as_int(); +		log_warning("Can't determine cost of %s cell.\n", log_id(type)); +		return 1; +	} -		dict<RTLIL::IdString, int> local_mod_cost_cache; -		if (mod_cost_cache == nullptr) -			mod_cost_cache = &local_mod_cost_cache; +	int get(RTLIL::Cell *cell) +	{ +		if (gate_cost && gate_cost->count(cell->type)) +			return gate_cost->at(cell->type); -		if (mod_cost_cache->count(mod->name)) -			return mod_cost_cache->at(mod->name); +		if (design && design->module(cell->type) && cell->parameters.empty()) +		{ +			RTLIL::Module *mod = design->module(cell->type); -		int module_cost = 1; -		for (auto c : mod->cells()) -			module_cost += get_cell_cost(c, mod_cost_cache); +			if (mod->attributes.count(ID(cost))) +				return mod->attributes.at(ID(cost)).as_int(); -		(*mod_cost_cache)[mod->name] = module_cost; -		return module_cost; -	} +			if (mod_cost_cache.count(mod->name)) +				return mod_cost_cache.at(mod->name); -	log_warning("Can't determine cost of %s cell (%d parameters).\n", log_id(type), GetSize(parameters)); -	return 1; -} +			int module_cost = 1; +			for (auto c : mod->cells()) +				module_cost += get(c); -inline int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache) -{ -	return get_cell_cost(cell->type, cell->parameters, cell->module->design, mod_cost_cache); -} +			mod_cost_cache[mod->name] = module_cost; +			return module_cost; +		} + +		log_warning("Can't determine cost of %s cell (%d parameters).\n", log_id(cell->type), GetSize(cell->parameters)); +		return 1; +	} +};  YOSYS_NAMESPACE_END diff --git a/kernel/driver.cc b/kernel/driver.cc index f273057dd..70a97c4b9 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -522,6 +522,12 @@ int main(int argc, char **argv)  	if (!backend_command.empty())  		run_backend(output_filename, backend_command); +	yosys_design->check(); +	for (auto it : saved_designs) +		it.second->check(); +	for (auto it : pushed_designs) +		it->check(); +  	if (!depsfile.empty())  	{  		FILE *f = fopen(depsfile.c_str(), "wt"); diff --git a/kernel/log.h b/kernel/log.h index 3e1facae8..5f53f533a 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -91,7 +91,7 @@ YS_NORETURN void log_cmd_error(const char *format, ...) YS_ATTRIBUTE(format(prin  static inline bool ys_debug(int n = 0) { if (log_force_debug) return true; log_debug_suppressed += n; return false; }  #  define log_debug(...) do { if (ys_debug(1)) log(__VA_ARGS__); } while (0)  #else -static inline bool ys_debug(int n = 0) { return false; } +static inline bool ys_debug(int = 0) { return false; }  #  define log_debug(_fmt, ...) do { } while (0)  #endif diff --git a/kernel/macc.h b/kernel/macc.h index 286ce567f..371f6737d 100644 --- a/kernel/macc.h +++ b/kernel/macc.h @@ -70,9 +70,9 @@ struct Macc  				while (GetSize(port.in_b) > 1 && port.in_b[GetSize(port.in_b)-1] == port.in_b[GetSize(port.in_b)-2])  					port.in_b.remove(GetSize(port.in_b)-1);  			} else { -				while (GetSize(port.in_a) > 1 && port.in_a[GetSize(port.in_a)-1] == RTLIL::S0) +				while (GetSize(port.in_a) > 1 && port.in_a[GetSize(port.in_a)-1] == State::S0)  					port.in_a.remove(GetSize(port.in_a)-1); -				while (GetSize(port.in_b) > 1 && port.in_b[GetSize(port.in_b)-1] == RTLIL::S0) +				while (GetSize(port.in_b) > 1 && port.in_b[GetSize(port.in_b)-1] == State::S0)  					port.in_b.remove(GetSize(port.in_b)-1);  			} @@ -80,9 +80,9 @@ struct Macc  		}  		for (auto &bit : bit_ports) -			if (bit == RTLIL::S1) +			if (bit == State::S1)  				off = const_add(off, RTLIL::Const(1, width), false, false, width); -			else if (bit != RTLIL::S0) +			else if (bit != State::S0)  				new_bit_ports.append(bit);  		if (off.as_bool()) { @@ -99,24 +99,24 @@ struct Macc  	void from_cell(RTLIL::Cell *cell)  	{ -		RTLIL::SigSpec port_a = cell->getPort("\\A"); +		RTLIL::SigSpec port_a = cell->getPort(ID::A);  		ports.clear(); -		bit_ports = cell->getPort("\\B"); +		bit_ports = cell->getPort(ID::B); -		std::vector<RTLIL::State> config_bits = cell->getParam("\\CONFIG").bits; +		std::vector<RTLIL::State> config_bits = cell->getParam(ID(CONFIG)).bits;  		int config_cursor = 0;  #ifndef NDEBUG -		int config_width = cell->getParam("\\CONFIG_WIDTH").as_int(); +		int config_width = cell->getParam(ID(CONFIG_WIDTH)).as_int();  		log_assert(GetSize(config_bits) >= config_width);  #endif  		int num_bits = 0; -		if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 1; -		if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 2; -		if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 4; -		if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 8; +		if (config_bits[config_cursor++] == State::S1) num_bits |= 1; +		if (config_bits[config_cursor++] == State::S1) num_bits |= 2; +		if (config_bits[config_cursor++] == State::S1) num_bits |= 4; +		if (config_bits[config_cursor++] == State::S1) num_bits |= 8;  		int port_a_cursor = 0;  		while (port_a_cursor < GetSize(port_a)) @@ -124,12 +124,12 @@ struct Macc  			log_assert(config_cursor + 2 + 2*num_bits <= config_width);  			port_t this_port; -			this_port.is_signed = config_bits[config_cursor++] == RTLIL::S1; -			this_port.do_subtract = config_bits[config_cursor++] == RTLIL::S1; +			this_port.is_signed = config_bits[config_cursor++] == State::S1; +			this_port.do_subtract = config_bits[config_cursor++] == State::S1;  			int size_a = 0;  			for (int i = 0; i < num_bits; i++) -				if (config_bits[config_cursor++] == RTLIL::S1) +				if (config_bits[config_cursor++] == State::S1)  					size_a |= 1 << i;  			this_port.in_a = port_a.extract(port_a_cursor, size_a); @@ -137,7 +137,7 @@ struct Macc  			int size_b = 0;  			for (int i = 0; i < num_bits; i++) -				if (config_bits[config_cursor++] == RTLIL::S1) +				if (config_bits[config_cursor++] == State::S1)  					size_b |= 1 << i;  			this_port.in_b = port_a.extract(port_a_cursor, size_b); @@ -166,43 +166,43 @@ struct Macc  			num_bits++, max_size /= 2;  		log_assert(num_bits < 16); -		config_bits.push_back(num_bits & 1 ? RTLIL::S1 : RTLIL::S0); -		config_bits.push_back(num_bits & 2 ? RTLIL::S1 : RTLIL::S0); -		config_bits.push_back(num_bits & 4 ? RTLIL::S1 : RTLIL::S0); -		config_bits.push_back(num_bits & 8 ? RTLIL::S1 : RTLIL::S0); +		config_bits.push_back(num_bits & 1 ? State::S1 : State::S0); +		config_bits.push_back(num_bits & 2 ? State::S1 : State::S0); +		config_bits.push_back(num_bits & 4 ? State::S1 : State::S0); +		config_bits.push_back(num_bits & 8 ? State::S1 : State::S0);  		for (auto &port : ports)  		{  			if (GetSize(port.in_a) == 0)  				continue; -			config_bits.push_back(port.is_signed ? RTLIL::S1 : RTLIL::S0); -			config_bits.push_back(port.do_subtract ? RTLIL::S1 : RTLIL::S0); +			config_bits.push_back(port.is_signed ? State::S1 : State::S0); +			config_bits.push_back(port.do_subtract ? State::S1 : State::S0);  			int size_a = GetSize(port.in_a);  			for (int i = 0; i < num_bits; i++) -				config_bits.push_back(size_a & (1 << i) ? RTLIL::S1 : RTLIL::S0); +				config_bits.push_back(size_a & (1 << i) ? State::S1 : State::S0);  			int size_b = GetSize(port.in_b);  			for (int i = 0; i < num_bits; i++) -				config_bits.push_back(size_b & (1 << i) ? RTLIL::S1 : RTLIL::S0); +				config_bits.push_back(size_b & (1 << i) ? State::S1 : State::S0);  			port_a.append(port.in_a);  			port_a.append(port.in_b);  		} -		cell->setPort("\\A", port_a); -		cell->setPort("\\B", bit_ports); -		cell->setParam("\\CONFIG", config_bits); -		cell->setParam("\\CONFIG_WIDTH", GetSize(config_bits)); -		cell->setParam("\\A_WIDTH", GetSize(port_a)); -		cell->setParam("\\B_WIDTH", GetSize(bit_ports)); +		cell->setPort(ID::A, port_a); +		cell->setPort(ID::B, bit_ports); +		cell->setParam(ID(CONFIG), config_bits); +		cell->setParam(ID(CONFIG_WIDTH), GetSize(config_bits)); +		cell->setParam(ID(A_WIDTH), GetSize(port_a)); +		cell->setParam(ID(B_WIDTH), GetSize(bit_ports));  	}  	bool eval(RTLIL::Const &result) const  	{  		for (auto &bit : result.bits) -			bit = RTLIL::S0; +			bit = State::S0;  		for (auto &port : ports)  		{ diff --git a/kernel/register.cc b/kernel/register.cc index 26da96b95..1fd1bad1d 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -25,6 +25,65 @@  #include <stdio.h>  #include <errno.h> +#ifdef YOSYS_ENABLE_ZLIB +#include <zlib.h> + +PRIVATE_NAMESPACE_BEGIN +#define GZ_BUFFER_SIZE 8192 +void decompress_gzip(const std::string &filename, std::stringstream &out) +{ +	char buffer[GZ_BUFFER_SIZE]; +	int bytes_read; +	gzFile gzf = gzopen(filename.c_str(), "rb"); +	while(!gzeof(gzf)) { +		bytes_read = gzread(gzf, reinterpret_cast<void *>(buffer), GZ_BUFFER_SIZE); +		out.write(buffer, bytes_read); +	} +	gzclose(gzf); +} + +/* +An output stream that uses a stringbuf to buffer data internally, +using zlib to write gzip-compressed data every time the stream is flushed. +*/ +class gzip_ostream : public std::ostream  { +public: +	gzip_ostream() +	{ +		rdbuf(&outbuf); +	} +	bool open(const std::string &filename) +	{ +		return outbuf.open(filename); +	} +private: +	class gzip_streambuf : public std::stringbuf { +	public: +		gzip_streambuf() { }; +		bool open(const std::string &filename) +		{ +			gzf = gzopen(filename.c_str(), "wb"); +			return gzf != nullptr; +		} +		virtual int sync() override +		{ +			gzwrite(gzf, reinterpret_cast<const void *>(str().c_str()), unsigned(str().size())); +			str(""); +			return 0; +		} +		~gzip_streambuf() +		{ +			sync(); +			gzclose(gzf); +		} +	private: +		gzFile gzf = nullptr; +	} outbuf; +}; +PRIVATE_NAMESPACE_END + +#endif +  YOSYS_NAMESPACE_BEGIN  #define MAX_REG_COUNT 1000 @@ -141,7 +200,7 @@ void Pass::extra_args(std::vector<std::string> args, size_t argidx, RTLIL::Desig  	{  		std::string arg = args[argidx]; -		if (arg.substr(0, 1) == "-") +		if (arg.compare(0, 1, "-") == 0)  			cmd_error(args, argidx, "Unknown option or option in arguments.");  		if (!select) @@ -236,8 +295,6 @@ void Pass::call(RTLIL::Design *design, std::vector<std::string> args)  	pass_register[args[0]]->post_execute(state);  	while (design->selection_stack.size() > orig_sel_stack_pos)  		design->selection_stack.pop_back(); - -	design->check();  }  void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &selection, std::string command) @@ -319,8 +376,10 @@ void ScriptPass::run(std::string command, std::string info)  			log("        %s\n", command.c_str());  		else  			log("        %s    %s\n", command.c_str(), info.c_str()); -	} else +	} else {  		Pass::call(active_design, command); +		active_design->check(); +	}  }  void ScriptPass::run_script(RTLIL::Design *design, std::string run_from, std::string run_to) @@ -390,7 +449,7 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<s  	{  		std::string arg = args[argidx]; -		if (arg.substr(0, 1) == "-") +		if (arg.compare(0, 1, "-") == 0)  			cmd_error(args, argidx, "Unknown option or option in arguments.");  		if (f != NULL)  			cmd_error(args, argidx, "Extra filename argument in direct file mode."); @@ -398,7 +457,7 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<s  		filename = arg;  		if (filename == "<<" && argidx+1 < args.size())  			filename += args[++argidx]; -		if (filename.substr(0, 2) == "<<") { +		if (filename.compare(0, 2, "<<") == 0) {  			if (Frontend::current_script_file == NULL)  				log_error("Unexpected here document '%s' outside of script!\n", filename.c_str());  			if (filename.size() <= 2) @@ -416,7 +475,7 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<s  						break;  				}  				size_t indent = buffer.find_first_not_of(" \t\r\n"); -				if (indent != std::string::npos && buffer.substr(indent, eot_marker.size()) == eot_marker) +				if (indent != std::string::npos && buffer.compare(indent, eot_marker.size(), eot_marker) == 0)  					break;  				last_here_document += buffer;  			} @@ -436,12 +495,34 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<s  				delete ff;  			else  				f = ff; +			if (f != NULL) { +				// Check for gzip magic +				unsigned char magic[3]; +				int n = readsome(*ff, reinterpret_cast<char*>(magic), 3); +				if (n == 3 && magic[0] == 0x1f && magic[1] == 0x8b) { +	#ifdef YOSYS_ENABLE_ZLIB +					log("Found gzip magic in file `%s', decompressing using zlib.\n", filename.c_str()); +					if (magic[2] != 8) +						log_cmd_error("gzip file `%s' uses unsupported compression type %02x\n", +							filename.c_str(), unsigned(magic[2])); +					delete ff; +					std::stringstream *df = new std::stringstream(); +					decompress_gzip(filename, *df); +					f = df; +	#else +					log_cmd_error("File `%s' is a gzip file, but Yosys is compiled without zlib.\n", filename.c_str()); +	#endif +				} else { +					ff->clear(); +					ff->seekg(0, std::ios::beg); +				} +			}  		}  		if (f == NULL)  			log_cmd_error("Can't open input file `%s' for reading: %s\n", filename.c_str(), strerror(errno));  		for (size_t i = argidx+1; i < args.size(); i++) -			if (args[i].substr(0, 1) == "-") +			if (args[i].compare(0, 1, "-") == 0)  				cmd_error(args, i, "Found option, expected arguments.");  		if (argidx+1 < args.size()) { @@ -492,8 +573,6 @@ void Frontend::frontend_call(RTLIL::Design *design, std::istream *f, std::string  			args.push_back(filename);  		frontend_register[args[0]]->execute(args, design);  	} - -	design->check();  }  Backend::Backend(std::string name, std::string short_help) : @@ -533,7 +612,7 @@ void Backend::extra_args(std::ostream *&f, std::string &filename, std::vector<st  	{  		std::string arg = args[argidx]; -		if (arg.substr(0, 1) == "-" && arg != "-") +		if (arg.compare(0, 1, "-") == 0 && arg != "-")  			cmd_error(args, argidx, "Unknown option or option in arguments.");  		if (f != NULL)  			cmd_error(args, argidx, "Extra filename argument in direct file mode."); @@ -546,14 +625,28 @@ void Backend::extra_args(std::ostream *&f, std::string &filename, std::vector<st  		filename = arg;  		rewrite_filename(filename); -		std::ofstream *ff = new std::ofstream; -		ff->open(filename.c_str(), std::ofstream::trunc); -		yosys_output_files.insert(filename); -		if (ff->fail()) { -			delete ff; -			log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno)); +		if (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".gz") == 0) { +#ifdef YOSYS_ENABLE_ZLIB +			gzip_ostream *gf = new gzip_ostream; +			if (!gf->open(filename)) { +				delete gf; +				log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno)); +			} +			yosys_output_files.insert(filename); +			f = gf; +#else +			log_cmd_error("Yosys is compiled without zlib support, unable to write gzip output.\n"); +#endif +		} else { +			std::ofstream *ff = new std::ofstream; +			ff->open(filename.c_str(), std::ofstream::trunc); +			yosys_output_files.insert(filename); +			if (ff->fail()) { +				delete ff; +				log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno)); +			} +			f = ff;  		} -		f = ff;  	}  	if (called_with_fp) @@ -603,8 +696,6 @@ void Backend::backend_call(RTLIL::Design *design, std::ostream *f, std::string f  	while (design->selection_stack.size() > orig_sel_stack_pos)  		design->selection_stack.pop_back(); - -	design->check();  }  static struct CellHelpMessages { diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index a09f4a0d1..1d380135b 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -29,12 +29,23 @@  YOSYS_NAMESPACE_BEGIN  RTLIL::IdString::destruct_guard_t RTLIL::IdString::destruct_guard; -std::vector<int> RTLIL::IdString::global_refcount_storage_;  std::vector<char*> RTLIL::IdString::global_id_storage_;  dict<char*, int, hash_cstr_ops> RTLIL::IdString::global_id_index_; +#ifndef YOSYS_NO_IDS_REFCNT +std::vector<int> RTLIL::IdString::global_refcount_storage_;  std::vector<int> RTLIL::IdString::global_free_idx_list_; +#endif +#ifdef YOSYS_USE_STICKY_IDS  int RTLIL::IdString::last_created_idx_[8];  int RTLIL::IdString::last_created_idx_ptr_; +#endif + +IdString RTLIL::ID::A; +IdString RTLIL::ID::B; +IdString RTLIL::ID::Y; +IdString RTLIL::ID::keep; +IdString RTLIL::ID::whitebox; +IdString RTLIL::ID::blackbox;  RTLIL::Const::Const()  { @@ -47,7 +58,7 @@ RTLIL::Const::Const(std::string str)  	for (int i = str.size()-1; i >= 0; i--) {  		unsigned char ch = str[i];  		for (int j = 0; j < 8; j++) { -			bits.push_back((ch & 1) != 0 ? RTLIL::S1 : RTLIL::S0); +			bits.push_back((ch & 1) != 0 ? State::S1 : State::S0);  			ch = ch >> 1;  		}  	} @@ -57,7 +68,7 @@ RTLIL::Const::Const(int val, int width)  {  	flags = RTLIL::CONST_FLAG_NONE;  	for (int i = 0; i < width; i++) { -		bits.push_back((val & 1) != 0 ? RTLIL::S1 : RTLIL::S0); +		bits.push_back((val & 1) != 0 ? State::S1 : State::S0);  		val = val >> 1;  	}  } @@ -73,7 +84,7 @@ RTLIL::Const::Const(const std::vector<bool> &bits)  {  	flags = RTLIL::CONST_FLAG_NONE;  	for (auto b : bits) -		this->bits.push_back(b ? RTLIL::S1 : RTLIL::S0); +		this->bits.push_back(b ? State::S1 : State::S0);  }  RTLIL::Const::Const(const RTLIL::Const &c) @@ -106,7 +117,7 @@ bool RTLIL::Const::operator !=(const RTLIL::Const &other) const  bool RTLIL::Const::as_bool() const  {  	for (size_t i = 0; i < bits.size(); i++) -		if (bits[i] == RTLIL::S1) +		if (bits[i] == State::S1)  			return true;  	return false;  } @@ -115,9 +126,9 @@ int RTLIL::Const::as_int(bool is_signed) const  {  	int32_t ret = 0;  	for (size_t i = 0; i < bits.size() && i < 32; i++) -		if (bits[i] == RTLIL::S1) +		if (bits[i] == State::S1)  			ret |= 1 << i; -	if (is_signed && bits.back() == RTLIL::S1) +	if (is_signed && bits.back() == State::S1)  		for (size_t i = bits.size(); i < 32; i++)  			ret |= 1 << i;  	return ret; @@ -264,16 +275,16 @@ pool<string> RTLIL::AttrObject::get_strpool_attribute(RTLIL::IdString id) const  void RTLIL::AttrObject::set_src_attribute(const std::string &src)  {  	if (src.empty()) -		attributes.erase("\\src"); +		attributes.erase(ID(src));  	else -		attributes["\\src"] = src; +		attributes[ID(src)] = src;  }  std::string RTLIL::AttrObject::get_src_attribute() const  {  	std::string src; -	if (attributes.count("\\src")) -		src = attributes.at("\\src").decode_string(); +	if (attributes.count(ID(src))) +		src = attributes.at(ID(src)).decode_string();  	return src;  } @@ -417,7 +428,7 @@ RTLIL::Module *RTLIL::Design::top_module()  	int module_count = 0;  	for (auto mod : selected_modules()) { -		if (mod->get_bool_attribute("\\top")) +		if (mod->get_bool_attribute(ID(top)))  			return mod;  		module_count++;  		module = mod; @@ -706,7 +717,7 @@ void RTLIL::Module::makeblackbox()  	processes.clear();  	remove(delwires); -	set_bool_attribute("\\blackbox"); +	set_bool_attribute(ID::blackbox);  }  void RTLIL::Module::reprocess_module(RTLIL::Design *, dict<RTLIL::IdString, RTLIL::Module *>) @@ -754,7 +765,7 @@ namespace {  					cell->name.c_str(), cell->type.c_str(), __FILE__, linenr, buf.str().c_str());  		} -		int param(const char *name) +		int param(RTLIL::IdString name)  		{  			if (cell->parameters.count(name) == 0)  				error(__LINE__); @@ -762,7 +773,7 @@ namespace {  			return cell->parameters.at(name).as_int();  		} -		int param_bool(const char *name) +		int param_bool(RTLIL::IdString name)  		{  			int v = param(name);  			if (cell->parameters.at(name).bits.size() > 32) @@ -772,14 +783,14 @@ namespace {  			return v;  		} -		void param_bits(const char *name, int width) +		void param_bits(RTLIL::IdString name, int width)  		{  			param(name);  			if (int(cell->parameters.at(name).bits.size()) != width)  				error(__LINE__);  		} -		void port(const char *name, int width) +		void port(RTLIL::IdString name, int width)  		{  			if (!cell->hasPort(name))  				error(__LINE__); @@ -797,9 +808,9 @@ namespace {  				if (expected_ports.count(conn.first) == 0)  					error(__LINE__); -			if (expected_params.count("\\A_SIGNED") != 0 && expected_params.count("\\B_SIGNED") && check_matched_sign) { -				bool a_is_signed = param("\\A_SIGNED") != 0; -				bool b_is_signed = param("\\B_SIGNED") != 0; +			if (expected_params.count(ID(A_SIGNED)) != 0 && expected_params.count(ID(B_SIGNED)) && check_matched_sign) { +				bool a_is_signed = param(ID(A_SIGNED)) != 0; +				bool b_is_signed = param(ID(B_SIGNED)) != 0;  				if (a_is_signed != b_is_signed)  					error(__LINE__);  			} @@ -828,481 +839,482 @@ namespace {  		void check()  		{ -			if (cell->type.substr(0, 1) != "$" || cell->type.substr(0, 3) == "$__" || cell->type.substr(0, 8) == "$paramod" || cell->type.substr(0,10) == "$fmcombine" || -					cell->type.substr(0, 9) == "$verific$" || cell->type.substr(0, 7) == "$array:" || cell->type.substr(0, 8) == "$extern:") +			if (!cell->type.begins_with("$") || cell->type.begins_with("$__") || cell->type.begins_with("$paramod") || cell->type.begins_with("$fmcombine") || +					cell->type.begins_with("$verific$") || cell->type.begins_with("$array:") || cell->type.begins_with("$extern:"))  				return; -			if (cell->type.in("$not", "$pos", "$neg")) { -				param_bool("\\A_SIGNED"); -				port("\\A", param("\\A_WIDTH")); -				port("\\Y", param("\\Y_WIDTH")); +			if (cell->type.in(ID($not), ID($pos), ID($neg))) { +				param_bool(ID(A_SIGNED)); +				port(ID::A, param(ID(A_WIDTH))); +				port(ID::Y, param(ID(Y_WIDTH)));  				check_expected();  				return;  			} -			if (cell->type.in("$and", "$or", "$xor", "$xnor")) { -				param_bool("\\A_SIGNED"); -				param_bool("\\B_SIGNED"); -				port("\\A", param("\\A_WIDTH")); -				port("\\B", param("\\B_WIDTH")); -				port("\\Y", param("\\Y_WIDTH")); +			if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor))) { +				param_bool(ID(A_SIGNED)); +				param_bool(ID(B_SIGNED)); +				port(ID::A, param(ID(A_WIDTH))); +				port(ID::B, param(ID(B_WIDTH))); +				port(ID::Y, param(ID(Y_WIDTH)));  				check_expected();  				return;  			} -			if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool")) { -				param_bool("\\A_SIGNED"); -				port("\\A", param("\\A_WIDTH")); -				port("\\Y", param("\\Y_WIDTH")); +			if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool))) { +				param_bool(ID(A_SIGNED)); +				port(ID::A, param(ID(A_WIDTH))); +				port(ID::Y, param(ID(Y_WIDTH)));  				check_expected();  				return;  			} -			if (cell->type.in("$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx")) { -				param_bool("\\A_SIGNED"); -				param_bool("\\B_SIGNED"); -				port("\\A", param("\\A_WIDTH")); -				port("\\B", param("\\B_WIDTH")); -				port("\\Y", param("\\Y_WIDTH")); +			if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) { +				param_bool(ID(A_SIGNED)); +				param_bool(ID(B_SIGNED)); +				port(ID::A, param(ID(A_WIDTH))); +				port(ID::B, param(ID(B_WIDTH))); +				port(ID::Y, param(ID(Y_WIDTH)));  				check_expected(false);  				return;  			} -			if (cell->type.in("$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt")) { -				param_bool("\\A_SIGNED"); -				param_bool("\\B_SIGNED"); -				port("\\A", param("\\A_WIDTH")); -				port("\\B", param("\\B_WIDTH")); -				port("\\Y", param("\\Y_WIDTH")); +			if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt))) { +				param_bool(ID(A_SIGNED)); +				param_bool(ID(B_SIGNED)); +				port(ID::A, param(ID(A_WIDTH))); +				port(ID::B, param(ID(B_WIDTH))); +				port(ID::Y, param(ID(Y_WIDTH)));  				check_expected();  				return;  			} -			if (cell->type.in("$add", "$sub", "$mul", "$div", "$mod", "$pow")) { -				param_bool("\\A_SIGNED"); -				param_bool("\\B_SIGNED"); -				port("\\A", param("\\A_WIDTH")); -				port("\\B", param("\\B_WIDTH")); -				port("\\Y", param("\\Y_WIDTH")); -				check_expected(cell->type != "$pow"); +			if (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow))) { +				param_bool(ID(A_SIGNED)); +				param_bool(ID(B_SIGNED)); +				port(ID::A, param(ID(A_WIDTH))); +				port(ID::B, param(ID(B_WIDTH))); +				port(ID::Y, param(ID(Y_WIDTH))); +				check_expected(cell->type != ID($pow));  				return;  			} -			if (cell->type == "$fa") { -				port("\\A", param("\\WIDTH")); -				port("\\B", param("\\WIDTH")); -				port("\\C", param("\\WIDTH")); -				port("\\X", param("\\WIDTH")); -				port("\\Y", param("\\WIDTH")); +			if (cell->type == ID($fa)) { +				port(ID::A, param(ID(WIDTH))); +				port(ID::B, param(ID(WIDTH))); +				port(ID(C), param(ID(WIDTH))); +				port(ID(X), param(ID(WIDTH))); +				port(ID::Y, param(ID(WIDTH)));  				check_expected();  				return;  			} -			if (cell->type == "$lcu") { -				port("\\P", param("\\WIDTH")); -				port("\\G", param("\\WIDTH")); -				port("\\CI", 1); -				port("\\CO", param("\\WIDTH")); +			if (cell->type == ID($lcu)) { +				port(ID(P), param(ID(WIDTH))); +				port(ID(G), param(ID(WIDTH))); +				port(ID(CI), 1); +				port(ID(CO), param(ID(WIDTH)));  				check_expected();  				return;  			} -			if (cell->type == "$alu") { -				param_bool("\\A_SIGNED"); -				param_bool("\\B_SIGNED"); -				port("\\A", param("\\A_WIDTH")); -				port("\\B", param("\\B_WIDTH")); -				port("\\CI", 1); -				port("\\BI", 1); -				port("\\X", param("\\Y_WIDTH")); -				port("\\Y", param("\\Y_WIDTH")); -				port("\\CO", param("\\Y_WIDTH")); +			if (cell->type == ID($alu)) { +				param_bool(ID(A_SIGNED)); +				param_bool(ID(B_SIGNED)); +				port(ID::A, param(ID(A_WIDTH))); +				port(ID::B, param(ID(B_WIDTH))); +				port(ID(CI), 1); +				port(ID(BI), 1); +				port(ID(X), param(ID(Y_WIDTH))); +				port(ID::Y, param(ID(Y_WIDTH))); +				port(ID(CO), param(ID(Y_WIDTH)));  				check_expected();  				return;  			} -			if (cell->type == "$macc") { -				param("\\CONFIG"); -				param("\\CONFIG_WIDTH"); -				port("\\A", param("\\A_WIDTH")); -				port("\\B", param("\\B_WIDTH")); -				port("\\Y", param("\\Y_WIDTH")); +			if (cell->type == ID($macc)) { +				param(ID(CONFIG)); +				param(ID(CONFIG_WIDTH)); +				port(ID::A, param(ID(A_WIDTH))); +				port(ID::B, param(ID(B_WIDTH))); +				port(ID::Y, param(ID(Y_WIDTH)));  				check_expected();  				Macc().from_cell(cell);  				return;  			} -			if (cell->type == "$logic_not") { -				param_bool("\\A_SIGNED"); -				port("\\A", param("\\A_WIDTH")); -				port("\\Y", param("\\Y_WIDTH")); +			if (cell->type == ID($logic_not)) { +				param_bool(ID(A_SIGNED)); +				port(ID::A, param(ID(A_WIDTH))); +				port(ID::Y, param(ID(Y_WIDTH)));  				check_expected();  				return;  			} -			if (cell->type == "$logic_and" || cell->type == "$logic_or") { -				param_bool("\\A_SIGNED"); -				param_bool("\\B_SIGNED"); -				port("\\A", param("\\A_WIDTH")); -				port("\\B", param("\\B_WIDTH")); -				port("\\Y", param("\\Y_WIDTH")); +			if (cell->type.in(ID($logic_and), ID($logic_or))) { +				param_bool(ID(A_SIGNED)); +				param_bool(ID(B_SIGNED)); +				port(ID::A, param(ID(A_WIDTH))); +				port(ID::B, param(ID(B_WIDTH))); +				port(ID::Y, param(ID(Y_WIDTH)));  				check_expected(false);  				return;  			} -			if (cell->type == "$slice") { -				param("\\OFFSET"); -				port("\\A", param("\\A_WIDTH")); -				port("\\Y", param("\\Y_WIDTH")); -				if (param("\\OFFSET") + param("\\Y_WIDTH") > param("\\A_WIDTH")) +			if (cell->type == ID($slice)) { +				param(ID(OFFSET)); +				port(ID::A, param(ID(A_WIDTH))); +				port(ID::Y, param(ID(Y_WIDTH))); +				if (param(ID(OFFSET)) + param(ID(Y_WIDTH)) > param(ID(A_WIDTH)))  					error(__LINE__);  				check_expected();  				return;  			} -			if (cell->type == "$concat") { -				port("\\A", param("\\A_WIDTH")); -				port("\\B", param("\\B_WIDTH")); -				port("\\Y", param("\\A_WIDTH") + param("\\B_WIDTH")); +			if (cell->type == ID($concat)) { +				port(ID::A, param(ID(A_WIDTH))); +				port(ID::B, param(ID(B_WIDTH))); +				port(ID::Y, param(ID(A_WIDTH)) + param(ID(B_WIDTH)));  				check_expected();  				return;  			} -			if (cell->type == "$mux") { -				port("\\A", param("\\WIDTH")); -				port("\\B", param("\\WIDTH")); -				port("\\S", 1); -				port("\\Y", param("\\WIDTH")); +			if (cell->type == ID($mux)) { +				port(ID::A, param(ID(WIDTH))); +				port(ID::B, param(ID(WIDTH))); +				port(ID(S), 1); +				port(ID::Y, param(ID(WIDTH)));  				check_expected();  				return;  			} -			if (cell->type == "$pmux") { -				port("\\A", param("\\WIDTH")); -				port("\\B", param("\\WIDTH") * param("\\S_WIDTH")); -				port("\\S", param("\\S_WIDTH")); -				port("\\Y", param("\\WIDTH")); +			if (cell->type == ID($pmux)) { +				port(ID::A, param(ID(WIDTH))); +				port(ID::B, param(ID(WIDTH)) * param(ID(S_WIDTH))); +				port(ID(S), param(ID(S_WIDTH))); +				port(ID::Y, param(ID(WIDTH)));  				check_expected();  				return;  			} -			if (cell->type == "$lut") { -				param("\\LUT"); -				port("\\A", param("\\WIDTH")); -				port("\\Y", 1); +			if (cell->type == ID($lut)) { +				param(ID(LUT)); +				port(ID::A, param(ID(WIDTH))); +				port(ID::Y, 1);  				check_expected();  				return;  			} -			if (cell->type == "$sop") { -				param("\\DEPTH"); -				param("\\TABLE"); -				port("\\A", param("\\WIDTH")); -				port("\\Y", 1); +			if (cell->type == ID($sop)) { +				param(ID(DEPTH)); +				param(ID(TABLE)); +				port(ID::A, param(ID(WIDTH))); +				port(ID::Y, 1);  				check_expected();  				return;  			} -			if (cell->type == "$sr") { -				param_bool("\\SET_POLARITY"); -				param_bool("\\CLR_POLARITY"); -				port("\\SET", param("\\WIDTH")); -				port("\\CLR", param("\\WIDTH")); -				port("\\Q",   param("\\WIDTH")); +			if (cell->type == ID($sr)) { +				param_bool(ID(SET_POLARITY)); +				param_bool(ID(CLR_POLARITY)); +				port(ID(SET), param(ID(WIDTH))); +				port(ID(CLR), param(ID(WIDTH))); +				port(ID(Q),   param(ID(WIDTH)));  				check_expected();  				return;  			} -			if (cell->type == "$ff") { -				port("\\D", param("\\WIDTH")); -				port("\\Q", param("\\WIDTH")); +			if (cell->type == ID($ff)) { +				port(ID(D), param(ID(WIDTH))); +				port(ID(Q), param(ID(WIDTH)));  				check_expected();  				return;  			} -			if (cell->type == "$dff") { -				param_bool("\\CLK_POLARITY"); -				port("\\CLK", 1); -				port("\\D", param("\\WIDTH")); -				port("\\Q", param("\\WIDTH")); +			if (cell->type == ID($dff)) { +				param_bool(ID(CLK_POLARITY)); +				port(ID(CLK), 1); +				port(ID(D), param(ID(WIDTH))); +				port(ID(Q), param(ID(WIDTH)));  				check_expected();  				return;  			} -			if (cell->type == "$dffe") { -				param_bool("\\CLK_POLARITY"); -				param_bool("\\EN_POLARITY"); -				port("\\CLK", 1); -				port("\\EN", 1); -				port("\\D", param("\\WIDTH")); -				port("\\Q", param("\\WIDTH")); +			if (cell->type == ID($dffe)) { +				param_bool(ID(CLK_POLARITY)); +				param_bool(ID(EN_POLARITY)); +				port(ID(CLK), 1); +				port(ID(EN), 1); +				port(ID(D), param(ID(WIDTH))); +				port(ID(Q), param(ID(WIDTH)));  				check_expected();  				return;  			} -			if (cell->type == "$dffsr") { -				param_bool("\\CLK_POLARITY"); -				param_bool("\\SET_POLARITY"); -				param_bool("\\CLR_POLARITY"); -				port("\\CLK", 1); -				port("\\SET", param("\\WIDTH")); -				port("\\CLR", param("\\WIDTH")); -				port("\\D", param("\\WIDTH")); -				port("\\Q", param("\\WIDTH")); +			if (cell->type == ID($dffsr)) { +				param_bool(ID(CLK_POLARITY)); +				param_bool(ID(SET_POLARITY)); +				param_bool(ID(CLR_POLARITY)); +				port(ID(CLK), 1); +				port(ID(SET), param(ID(WIDTH))); +				port(ID(CLR), param(ID(WIDTH))); +				port(ID(D), param(ID(WIDTH))); +				port(ID(Q), param(ID(WIDTH)));  				check_expected();  				return;  			} -			if (cell->type == "$adff") { -				param_bool("\\CLK_POLARITY"); -				param_bool("\\ARST_POLARITY"); -				param_bits("\\ARST_VALUE", param("\\WIDTH")); -				port("\\CLK", 1); -				port("\\ARST", 1); -				port("\\D", param("\\WIDTH")); -				port("\\Q", param("\\WIDTH")); +			if (cell->type == ID($adff)) { +				param_bool(ID(CLK_POLARITY)); +				param_bool(ID(ARST_POLARITY)); +				param_bits(ID(ARST_VALUE), param(ID(WIDTH))); +				port(ID(CLK), 1); +				port(ID(ARST), 1); +				port(ID(D), param(ID(WIDTH))); +				port(ID(Q), param(ID(WIDTH)));  				check_expected();  				return;  			} -			if (cell->type == "$dlatch") { -				param_bool("\\EN_POLARITY"); -				port("\\EN", 1); -				port("\\D", param("\\WIDTH")); -				port("\\Q", param("\\WIDTH")); +			if (cell->type == ID($dlatch)) { +				param_bool(ID(EN_POLARITY)); +				port(ID(EN), 1); +				port(ID(D), param(ID(WIDTH))); +				port(ID(Q), param(ID(WIDTH)));  				check_expected();  				return;  			} -			if (cell->type == "$dlatchsr") { -				param_bool("\\EN_POLARITY"); -				param_bool("\\SET_POLARITY"); -				param_bool("\\CLR_POLARITY"); -				port("\\EN", 1); -				port("\\SET", param("\\WIDTH")); -				port("\\CLR", param("\\WIDTH")); -				port("\\D", param("\\WIDTH")); -				port("\\Q", param("\\WIDTH")); +			if (cell->type == ID($dlatchsr)) { +				param_bool(ID(EN_POLARITY)); +				param_bool(ID(SET_POLARITY)); +				param_bool(ID(CLR_POLARITY)); +				port(ID(EN), 1); +				port(ID(SET), param(ID(WIDTH))); +				port(ID(CLR), param(ID(WIDTH))); +				port(ID(D), param(ID(WIDTH))); +				port(ID(Q), param(ID(WIDTH)));  				check_expected();  				return;  			} -			if (cell->type == "$fsm") { -				param("\\NAME"); -				param_bool("\\CLK_POLARITY"); -				param_bool("\\ARST_POLARITY"); -				param("\\STATE_BITS"); -				param("\\STATE_NUM"); -				param("\\STATE_NUM_LOG2"); -				param("\\STATE_RST"); -				param_bits("\\STATE_TABLE", param("\\STATE_BITS") * param("\\STATE_NUM")); -				param("\\TRANS_NUM"); -				param_bits("\\TRANS_TABLE", param("\\TRANS_NUM") * (2*param("\\STATE_NUM_LOG2") + param("\\CTRL_IN_WIDTH") + param("\\CTRL_OUT_WIDTH"))); -				port("\\CLK", 1); -				port("\\ARST", 1); -				port("\\CTRL_IN", param("\\CTRL_IN_WIDTH")); -				port("\\CTRL_OUT", param("\\CTRL_OUT_WIDTH")); +			if (cell->type == ID($fsm)) { +				param(ID(NAME)); +				param_bool(ID(CLK_POLARITY)); +				param_bool(ID(ARST_POLARITY)); +				param(ID(STATE_BITS)); +				param(ID(STATE_NUM)); +				param(ID(STATE_NUM_LOG2)); +				param(ID(STATE_RST)); +				param_bits(ID(STATE_TABLE), param(ID(STATE_BITS)) * param(ID(STATE_NUM))); +				param(ID(TRANS_NUM)); +				param_bits(ID(TRANS_TABLE), param(ID(TRANS_NUM)) * (2*param(ID(STATE_NUM_LOG2)) + param(ID(CTRL_IN_WIDTH)) + param(ID(CTRL_OUT_WIDTH)))); +				port(ID(CLK), 1); +				port(ID(ARST), 1); +				port(ID(CTRL_IN), param(ID(CTRL_IN_WIDTH))); +				port(ID(CTRL_OUT), param(ID(CTRL_OUT_WIDTH)));  				check_expected();  				return;  			} -			if (cell->type == "$memrd") { -				param("\\MEMID"); -				param_bool("\\CLK_ENABLE"); -				param_bool("\\CLK_POLARITY"); -				param_bool("\\TRANSPARENT"); -				port("\\CLK", 1); -				port("\\EN", 1); -				port("\\ADDR", param("\\ABITS")); -				port("\\DATA", param("\\WIDTH")); +			if (cell->type == ID($memrd)) { +				param(ID(MEMID)); +				param_bool(ID(CLK_ENABLE)); +				param_bool(ID(CLK_POLARITY)); +				param_bool(ID(TRANSPARENT)); +				port(ID(CLK), 1); +				port(ID(EN), 1); +				port(ID(ADDR), param(ID(ABITS))); +				port(ID(DATA), param(ID(WIDTH)));  				check_expected();  				return;  			} -			if (cell->type == "$memwr") { -				param("\\MEMID"); -				param_bool("\\CLK_ENABLE"); -				param_bool("\\CLK_POLARITY"); -				param("\\PRIORITY"); -				port("\\CLK", 1); -				port("\\EN", param("\\WIDTH")); -				port("\\ADDR", param("\\ABITS")); -				port("\\DATA", param("\\WIDTH")); +			if (cell->type == ID($memwr)) { +				param(ID(MEMID)); +				param_bool(ID(CLK_ENABLE)); +				param_bool(ID(CLK_POLARITY)); +				param(ID(PRIORITY)); +				port(ID(CLK), 1); +				port(ID(EN), param(ID(WIDTH))); +				port(ID(ADDR), param(ID(ABITS))); +				port(ID(DATA), param(ID(WIDTH)));  				check_expected();  				return;  			} -			if (cell->type == "$meminit") { -				param("\\MEMID"); -				param("\\PRIORITY"); -				port("\\ADDR", param("\\ABITS")); -				port("\\DATA", param("\\WIDTH") * param("\\WORDS")); +			if (cell->type == ID($meminit)) { +				param(ID(MEMID)); +				param(ID(PRIORITY)); +				port(ID(ADDR), param(ID(ABITS))); +				port(ID(DATA), param(ID(WIDTH)) * param(ID(WORDS)));  				check_expected();  				return;  			} -			if (cell->type == "$mem") { -				param("\\MEMID"); -				param("\\SIZE"); -				param("\\OFFSET"); -				param("\\INIT"); -				param_bits("\\RD_CLK_ENABLE", max(1, param("\\RD_PORTS"))); -				param_bits("\\RD_CLK_POLARITY", max(1, param("\\RD_PORTS"))); -				param_bits("\\RD_TRANSPARENT", max(1, param("\\RD_PORTS"))); -				param_bits("\\WR_CLK_ENABLE", max(1, param("\\WR_PORTS"))); -				param_bits("\\WR_CLK_POLARITY", max(1, param("\\WR_PORTS"))); -				port("\\RD_CLK", param("\\RD_PORTS")); -				port("\\RD_EN", param("\\RD_PORTS")); -				port("\\RD_ADDR", param("\\RD_PORTS") * param("\\ABITS")); -				port("\\RD_DATA", param("\\RD_PORTS") * param("\\WIDTH")); -				port("\\WR_CLK", param("\\WR_PORTS")); -				port("\\WR_EN", param("\\WR_PORTS") * param("\\WIDTH")); -				port("\\WR_ADDR", param("\\WR_PORTS") * param("\\ABITS")); -				port("\\WR_DATA", param("\\WR_PORTS") * param("\\WIDTH")); +			if (cell->type == ID($mem)) { +				param(ID(MEMID)); +				param(ID(SIZE)); +				param(ID(OFFSET)); +				param(ID(INIT)); +				param_bits(ID(RD_CLK_ENABLE), max(1, param(ID(RD_PORTS)))); +				param_bits(ID(RD_CLK_POLARITY), max(1, param(ID(RD_PORTS)))); +				param_bits(ID(RD_TRANSPARENT), max(1, param(ID(RD_PORTS)))); +				param_bits(ID(WR_CLK_ENABLE), max(1, param(ID(WR_PORTS)))); +				param_bits(ID(WR_CLK_POLARITY), max(1, param(ID(WR_PORTS)))); +				port(ID(RD_CLK), param(ID(RD_PORTS))); +				port(ID(RD_EN), param(ID(RD_PORTS))); +				port(ID(RD_ADDR), param(ID(RD_PORTS)) * param(ID(ABITS))); +				port(ID(RD_DATA), param(ID(RD_PORTS)) * param(ID(WIDTH))); +				port(ID(WR_CLK), param(ID(WR_PORTS))); +				port(ID(WR_EN), param(ID(WR_PORTS)) * param(ID(WIDTH))); +				port(ID(WR_ADDR), param(ID(WR_PORTS)) * param(ID(ABITS))); +				port(ID(WR_DATA), param(ID(WR_PORTS)) * param(ID(WIDTH)));  				check_expected();  				return;  			} -			if (cell->type == "$tribuf") { -				port("\\A", param("\\WIDTH")); -				port("\\Y", param("\\WIDTH")); -				port("\\EN", 1); +			if (cell->type == ID($tribuf)) { +				port(ID::A, param(ID(WIDTH))); +				port(ID::Y, param(ID(WIDTH))); +				port(ID(EN), 1);  				check_expected();  				return;  			} -			if (cell->type.in("$assert", "$assume", "$live", "$fair", "$cover")) { -				port("\\A", 1); -				port("\\EN", 1); +			if (cell->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover))) { +				port(ID::A, 1); +				port(ID(EN), 1);  				check_expected();  				return;  			} -			if (cell->type == "$initstate") { -				port("\\Y", 1); +			if (cell->type == ID($initstate)) { +				port(ID::Y, 1);  				check_expected();  				return;  			} -			if (cell->type.in("$anyconst", "$anyseq", "$allconst", "$allseq")) { -				port("\\Y", param("\\WIDTH")); +			if (cell->type.in(ID($anyconst), ID($anyseq), ID($allconst), ID($allseq))) { +				port(ID::Y, param(ID(WIDTH)));  				check_expected();  				return;  			} -			if (cell->type == "$equiv") { -				port("\\A", 1); -				port("\\B", 1); -				port("\\Y", 1); +			if (cell->type == ID($equiv)) { +				port(ID::A, 1); +				port(ID::B, 1); +				port(ID::Y, 1);  				check_expected();  				return;  			} -			if (cell->type.in("$specify2", "$specify3")) { -				param_bool("\\FULL"); -				param_bool("\\SRC_DST_PEN"); -				param_bool("\\SRC_DST_POL"); -				param("\\T_RISE_MIN"); -				param("\\T_RISE_TYP"); -				param("\\T_RISE_MAX"); -				param("\\T_FALL_MIN"); -				param("\\T_FALL_TYP"); -				param("\\T_FALL_MAX"); -				port("\\EN", 1); -				port("\\SRC", param("\\SRC_WIDTH")); -				port("\\DST", param("\\DST_WIDTH")); -				if (cell->type == "$specify3") { -					param_bool("\\EDGE_EN"); -					param_bool("\\EDGE_POL"); -					param_bool("\\DAT_DST_PEN"); -					param_bool("\\DAT_DST_POL"); -					port("\\DAT", param("\\DST_WIDTH")); +			if (cell->type.in(ID($specify2), ID($specify3))) { +				param_bool(ID(FULL)); +				param_bool(ID(SRC_DST_PEN)); +				param_bool(ID(SRC_DST_POL)); +				param(ID(T_RISE_MIN)); +				param(ID(T_RISE_TYP)); +				param(ID(T_RISE_MAX)); +				param(ID(T_FALL_MIN)); +				param(ID(T_FALL_TYP)); +				param(ID(T_FALL_MAX)); +				port(ID(EN), 1); +				port(ID(SRC), param(ID(SRC_WIDTH))); +				port(ID(DST), param(ID(DST_WIDTH))); +				if (cell->type == ID($specify3)) { +					param_bool(ID(EDGE_EN)); +					param_bool(ID(EDGE_POL)); +					param_bool(ID(DAT_DST_PEN)); +					param_bool(ID(DAT_DST_POL)); +					port(ID(DAT), param(ID(DST_WIDTH)));  				}  				check_expected();  				return;  			} -			if (cell->type == "$specrule") { -				param("\\TYPE"); -				param_bool("\\SRC_PEN"); -				param_bool("\\SRC_POL"); -				param_bool("\\DST_PEN"); -				param_bool("\\DST_POL"); -				param("\\T_LIMIT"); -				param("\\T_LIMIT2"); -				port("\\SRC_EN", 1); -				port("\\DST_EN", 1); -				port("\\SRC", param("\\SRC_WIDTH")); -				port("\\DST", param("\\DST_WIDTH")); +			if (cell->type == ID($specrule)) { +				param(ID(TYPE)); +				param_bool(ID(SRC_PEN)); +				param_bool(ID(SRC_POL)); +				param_bool(ID(DST_PEN)); +				param_bool(ID(DST_POL)); +				param(ID(T_LIMIT)); +				param(ID(T_LIMIT2)); +				port(ID(SRC_EN), 1); +				port(ID(DST_EN), 1); +				port(ID(SRC), param(ID(SRC_WIDTH))); +				port(ID(DST), param(ID(DST_WIDTH)));  				check_expected();  				return;  			} -			if (cell->type == "$_BUF_")    { check_gate("AY"); return; } -			if (cell->type == "$_NOT_")    { check_gate("AY"); return; } -			if (cell->type == "$_AND_")    { check_gate("ABY"); return; } -			if (cell->type == "$_NAND_")   { check_gate("ABY"); return; } -			if (cell->type == "$_OR_")     { check_gate("ABY"); return; } -			if (cell->type == "$_NOR_")    { check_gate("ABY"); return; } -			if (cell->type == "$_XOR_")    { check_gate("ABY"); return; } -			if (cell->type == "$_XNOR_")   { check_gate("ABY"); return; } -			if (cell->type == "$_ANDNOT_") { check_gate("ABY"); return; } -			if (cell->type == "$_ORNOT_")  { check_gate("ABY"); return; } -			if (cell->type == "$_MUX_")    { check_gate("ABSY"); return; } -			if (cell->type == "$_AOI3_")   { check_gate("ABCY"); return; } -			if (cell->type == "$_OAI3_")   { check_gate("ABCY"); return; } -			if (cell->type == "$_AOI4_")   { check_gate("ABCDY"); return; } -			if (cell->type == "$_OAI4_")   { check_gate("ABCDY"); return; } - -			if (cell->type == "$_TBUF_")  { check_gate("AYE"); return; } - -			if (cell->type == "$_MUX4_")  { check_gate("ABCDSTY"); return; } -			if (cell->type == "$_MUX8_")  { check_gate("ABCDEFGHSTUY"); return; } -			if (cell->type == "$_MUX16_") { check_gate("ABCDEFGHIJKLMNOPSTUVY"); return; } - -			if (cell->type == "$_SR_NN_") { check_gate("SRQ"); return; } -			if (cell->type == "$_SR_NP_") { check_gate("SRQ"); return; } -			if (cell->type == "$_SR_PN_") { check_gate("SRQ"); return; } -			if (cell->type == "$_SR_PP_") { check_gate("SRQ"); return; } - -			if (cell->type == "$_FF_")    { check_gate("DQ");  return; } -			if (cell->type == "$_DFF_N_") { check_gate("DQC"); return; } -			if (cell->type == "$_DFF_P_") { check_gate("DQC"); return; } - -			if (cell->type == "$_DFFE_NN_") { check_gate("DQCE"); return; } -			if (cell->type == "$_DFFE_NP_") { check_gate("DQCE"); return; } -			if (cell->type == "$_DFFE_PN_") { check_gate("DQCE"); return; } -			if (cell->type == "$_DFFE_PP_") { check_gate("DQCE"); return; } - -			if (cell->type == "$_DFF_NN0_") { check_gate("DQCR"); return; } -			if (cell->type == "$_DFF_NN1_") { check_gate("DQCR"); return; } -			if (cell->type == "$_DFF_NP0_") { check_gate("DQCR"); return; } -			if (cell->type == "$_DFF_NP1_") { check_gate("DQCR"); return; } -			if (cell->type == "$_DFF_PN0_") { check_gate("DQCR"); return; } -			if (cell->type == "$_DFF_PN1_") { check_gate("DQCR"); return; } -			if (cell->type == "$_DFF_PP0_") { check_gate("DQCR"); return; } -			if (cell->type == "$_DFF_PP1_") { check_gate("DQCR"); return; } - -			if (cell->type == "$_DFFSR_NNN_") { check_gate("CSRDQ"); return; } -			if (cell->type == "$_DFFSR_NNP_") { check_gate("CSRDQ"); return; } -			if (cell->type == "$_DFFSR_NPN_") { check_gate("CSRDQ"); return; } -			if (cell->type == "$_DFFSR_NPP_") { check_gate("CSRDQ"); return; } -			if (cell->type == "$_DFFSR_PNN_") { check_gate("CSRDQ"); return; } -			if (cell->type == "$_DFFSR_PNP_") { check_gate("CSRDQ"); return; } -			if (cell->type == "$_DFFSR_PPN_") { check_gate("CSRDQ"); return; } -			if (cell->type == "$_DFFSR_PPP_") { check_gate("CSRDQ"); return; } - -			if (cell->type == "$_DLATCH_N_") { check_gate("EDQ"); return; } -			if (cell->type == "$_DLATCH_P_") { check_gate("EDQ"); return; } - -			if (cell->type == "$_DLATCHSR_NNN_") { check_gate("ESRDQ"); return; } -			if (cell->type == "$_DLATCHSR_NNP_") { check_gate("ESRDQ"); return; } -			if (cell->type == "$_DLATCHSR_NPN_") { check_gate("ESRDQ"); return; } -			if (cell->type == "$_DLATCHSR_NPP_") { check_gate("ESRDQ"); return; } -			if (cell->type == "$_DLATCHSR_PNN_") { check_gate("ESRDQ"); return; } -			if (cell->type == "$_DLATCHSR_PNP_") { check_gate("ESRDQ"); return; } -			if (cell->type == "$_DLATCHSR_PPN_") { check_gate("ESRDQ"); return; } -			if (cell->type == "$_DLATCHSR_PPP_") { check_gate("ESRDQ"); return; } +			if (cell->type == ID($_BUF_))    { check_gate("AY"); return; } +			if (cell->type == ID($_NOT_))    { check_gate("AY"); return; } +			if (cell->type == ID($_AND_))    { check_gate("ABY"); return; } +			if (cell->type == ID($_NAND_))   { check_gate("ABY"); return; } +			if (cell->type == ID($_OR_))     { check_gate("ABY"); return; } +			if (cell->type == ID($_NOR_))    { check_gate("ABY"); return; } +			if (cell->type == ID($_XOR_))    { check_gate("ABY"); return; } +			if (cell->type == ID($_XNOR_))   { check_gate("ABY"); return; } +			if (cell->type == ID($_ANDNOT_)) { check_gate("ABY"); return; } +			if (cell->type == ID($_ORNOT_))  { check_gate("ABY"); return; } +			if (cell->type == ID($_MUX_))    { check_gate("ABSY"); return; } +			if (cell->type == ID($_NMUX_))   { check_gate("ABSY"); return; } +			if (cell->type == ID($_AOI3_))   { check_gate("ABCY"); return; } +			if (cell->type == ID($_OAI3_))   { check_gate("ABCY"); return; } +			if (cell->type == ID($_AOI4_))   { check_gate("ABCDY"); return; } +			if (cell->type == ID($_OAI4_))   { check_gate("ABCDY"); return; } + +			if (cell->type == ID($_TBUF_))  { check_gate("AYE"); return; } + +			if (cell->type == ID($_MUX4_))  { check_gate("ABCDSTY"); return; } +			if (cell->type == ID($_MUX8_))  { check_gate("ABCDEFGHSTUY"); return; } +			if (cell->type == ID($_MUX16_)) { check_gate("ABCDEFGHIJKLMNOPSTUVY"); return; } + +			if (cell->type == ID($_SR_NN_)) { check_gate("SRQ"); return; } +			if (cell->type == ID($_SR_NP_)) { check_gate("SRQ"); return; } +			if (cell->type == ID($_SR_PN_)) { check_gate("SRQ"); return; } +			if (cell->type == ID($_SR_PP_)) { check_gate("SRQ"); return; } + +			if (cell->type == ID($_FF_))    { check_gate("DQ");  return; } +			if (cell->type == ID($_DFF_N_)) { check_gate("DQC"); return; } +			if (cell->type == ID($_DFF_P_)) { check_gate("DQC"); return; } + +			if (cell->type == ID($_DFFE_NN_)) { check_gate("DQCE"); return; } +			if (cell->type == ID($_DFFE_NP_)) { check_gate("DQCE"); return; } +			if (cell->type == ID($_DFFE_PN_)) { check_gate("DQCE"); return; } +			if (cell->type == ID($_DFFE_PP_)) { check_gate("DQCE"); return; } + +			if (cell->type == ID($_DFF_NN0_)) { check_gate("DQCR"); return; } +			if (cell->type == ID($_DFF_NN1_)) { check_gate("DQCR"); return; } +			if (cell->type == ID($_DFF_NP0_)) { check_gate("DQCR"); return; } +			if (cell->type == ID($_DFF_NP1_)) { check_gate("DQCR"); return; } +			if (cell->type == ID($_DFF_PN0_)) { check_gate("DQCR"); return; } +			if (cell->type == ID($_DFF_PN1_)) { check_gate("DQCR"); return; } +			if (cell->type == ID($_DFF_PP0_)) { check_gate("DQCR"); return; } +			if (cell->type == ID($_DFF_PP1_)) { check_gate("DQCR"); return; } + +			if (cell->type == ID($_DFFSR_NNN_)) { check_gate("CSRDQ"); return; } +			if (cell->type == ID($_DFFSR_NNP_)) { check_gate("CSRDQ"); return; } +			if (cell->type == ID($_DFFSR_NPN_)) { check_gate("CSRDQ"); return; } +			if (cell->type == ID($_DFFSR_NPP_)) { check_gate("CSRDQ"); return; } +			if (cell->type == ID($_DFFSR_PNN_)) { check_gate("CSRDQ"); return; } +			if (cell->type == ID($_DFFSR_PNP_)) { check_gate("CSRDQ"); return; } +			if (cell->type == ID($_DFFSR_PPN_)) { check_gate("CSRDQ"); return; } +			if (cell->type == ID($_DFFSR_PPP_)) { check_gate("CSRDQ"); return; } + +			if (cell->type == ID($_DLATCH_N_)) { check_gate("EDQ"); return; } +			if (cell->type == ID($_DLATCH_P_)) { check_gate("EDQ"); return; } + +			if (cell->type == ID($_DLATCHSR_NNN_)) { check_gate("ESRDQ"); return; } +			if (cell->type == ID($_DLATCHSR_NNP_)) { check_gate("ESRDQ"); return; } +			if (cell->type == ID($_DLATCHSR_NPN_)) { check_gate("ESRDQ"); return; } +			if (cell->type == ID($_DLATCHSR_NPP_)) { check_gate("ESRDQ"); return; } +			if (cell->type == ID($_DLATCHSR_PNN_)) { check_gate("ESRDQ"); return; } +			if (cell->type == ID($_DLATCHSR_PNP_)) { check_gate("ESRDQ"); return; } +			if (cell->type == ID($_DLATCHSR_PPN_)) { check_gate("ESRDQ"); return; } +			if (cell->type == ID($_DLATCHSR_PPP_)) { check_gate("ESRDQ"); return; }  			error(__LINE__);  		} @@ -1816,11 +1828,11 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *oth  #define DEF_METHOD(_func, _y_size, _type) \  	RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed, const std::string &src) { \  		RTLIL::Cell *cell = addCell(name, _type);           \ -		cell->parameters["\\A_SIGNED"] = is_signed;         \ -		cell->parameters["\\A_WIDTH"] = sig_a.size();       \ -		cell->parameters["\\Y_WIDTH"] = sig_y.size();       \ -		cell->setPort("\\A", sig_a);                        \ -		cell->setPort("\\Y", sig_y);                        \ +		cell->parameters[ID(A_SIGNED)] = is_signed;         \ +		cell->parameters[ID(A_WIDTH)] = sig_a.size();       \ +		cell->parameters[ID(Y_WIDTH)] = sig_y.size();       \ +		cell->setPort(ID::A, sig_a);                        \ +		cell->setPort(ID::Y, sig_y);                        \  		cell->set_src_attribute(src);                       \  		return cell;                                        \  	} \ @@ -1829,28 +1841,28 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *oth  		add ## _func(name, sig_a, sig_y, is_signed, src);   \  		return sig_y;                                       \  	} -DEF_METHOD(Not,        sig_a.size(), "$not") -DEF_METHOD(Pos,        sig_a.size(), "$pos") -DEF_METHOD(Neg,        sig_a.size(), "$neg") -DEF_METHOD(ReduceAnd,  1, "$reduce_and") -DEF_METHOD(ReduceOr,   1, "$reduce_or") -DEF_METHOD(ReduceXor,  1, "$reduce_xor") -DEF_METHOD(ReduceXnor, 1, "$reduce_xnor") -DEF_METHOD(ReduceBool, 1, "$reduce_bool") -DEF_METHOD(LogicNot,   1, "$logic_not") +DEF_METHOD(Not,        sig_a.size(), ID($not)) +DEF_METHOD(Pos,        sig_a.size(), ID($pos)) +DEF_METHOD(Neg,        sig_a.size(), ID($neg)) +DEF_METHOD(ReduceAnd,  1, ID($reduce_and)) +DEF_METHOD(ReduceOr,   1, ID($reduce_or)) +DEF_METHOD(ReduceXor,  1, ID($reduce_xor)) +DEF_METHOD(ReduceXnor, 1, ID($reduce_xnor)) +DEF_METHOD(ReduceBool, 1, ID($reduce_bool)) +DEF_METHOD(LogicNot,   1, ID($logic_not))  #undef DEF_METHOD  #define DEF_METHOD(_func, _y_size, _type) \  	RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed, const std::string &src) { \  		RTLIL::Cell *cell = addCell(name, _type);           \ -		cell->parameters["\\A_SIGNED"] = is_signed;         \ -		cell->parameters["\\B_SIGNED"] = is_signed;         \ -		cell->parameters["\\A_WIDTH"] = sig_a.size();       \ -		cell->parameters["\\B_WIDTH"] = sig_b.size();       \ -		cell->parameters["\\Y_WIDTH"] = sig_y.size();       \ -		cell->setPort("\\A", sig_a);                        \ -		cell->setPort("\\B", sig_b);                        \ -		cell->setPort("\\Y", sig_y);                        \ +		cell->parameters[ID(A_SIGNED)] = is_signed;         \ +		cell->parameters[ID(B_SIGNED)] = is_signed;         \ +		cell->parameters[ID(A_WIDTH)] = sig_a.size();       \ +		cell->parameters[ID(B_WIDTH)] = sig_b.size();       \ +		cell->parameters[ID(Y_WIDTH)] = sig_y.size();       \ +		cell->setPort(ID::A, sig_a);                        \ +		cell->setPort(ID::B, sig_b);                        \ +		cell->setPort(ID::Y, sig_y);                        \  		cell->set_src_attribute(src);                       \  		return cell;                                        \  	} \ @@ -1859,42 +1871,42 @@ DEF_METHOD(LogicNot,   1, "$logic_not")  		add ## _func(name, sig_a, sig_b, sig_y, is_signed, src); \  		return sig_y;                                            \  	} -DEF_METHOD(And,      max(sig_a.size(), sig_b.size()), "$and") -DEF_METHOD(Or,       max(sig_a.size(), sig_b.size()), "$or") -DEF_METHOD(Xor,      max(sig_a.size(), sig_b.size()), "$xor") -DEF_METHOD(Xnor,     max(sig_a.size(), sig_b.size()), "$xnor") -DEF_METHOD(Shl,      sig_a.size(), "$shl") -DEF_METHOD(Shr,      sig_a.size(), "$shr") -DEF_METHOD(Sshl,     sig_a.size(), "$sshl") -DEF_METHOD(Sshr,     sig_a.size(), "$sshr") -DEF_METHOD(Shift,    sig_a.size(), "$shift") -DEF_METHOD(Shiftx,   sig_a.size(), "$shiftx") -DEF_METHOD(Lt,       1, "$lt") -DEF_METHOD(Le,       1, "$le") -DEF_METHOD(Eq,       1, "$eq") -DEF_METHOD(Ne,       1, "$ne") -DEF_METHOD(Eqx,      1, "$eqx") -DEF_METHOD(Nex,      1, "$nex") -DEF_METHOD(Ge,       1, "$ge") -DEF_METHOD(Gt,       1, "$gt") -DEF_METHOD(Add,      max(sig_a.size(), sig_b.size()), "$add") -DEF_METHOD(Sub,      max(sig_a.size(), sig_b.size()), "$sub") -DEF_METHOD(Mul,      max(sig_a.size(), sig_b.size()), "$mul") -DEF_METHOD(Div,      max(sig_a.size(), sig_b.size()), "$div") -DEF_METHOD(Mod,      max(sig_a.size(), sig_b.size()), "$mod") -DEF_METHOD(LogicAnd, 1, "$logic_and") -DEF_METHOD(LogicOr,  1, "$logic_or") +DEF_METHOD(And,      max(sig_a.size(), sig_b.size()), ID($and)) +DEF_METHOD(Or,       max(sig_a.size(), sig_b.size()), ID($or)) +DEF_METHOD(Xor,      max(sig_a.size(), sig_b.size()), ID($xor)) +DEF_METHOD(Xnor,     max(sig_a.size(), sig_b.size()), ID($xnor)) +DEF_METHOD(Shl,      sig_a.size(), ID($shl)) +DEF_METHOD(Shr,      sig_a.size(), ID($shr)) +DEF_METHOD(Sshl,     sig_a.size(), ID($sshl)) +DEF_METHOD(Sshr,     sig_a.size(), ID($sshr)) +DEF_METHOD(Shift,    sig_a.size(), ID($shift)) +DEF_METHOD(Shiftx,   sig_a.size(), ID($shiftx)) +DEF_METHOD(Lt,       1, ID($lt)) +DEF_METHOD(Le,       1, ID($le)) +DEF_METHOD(Eq,       1, ID($eq)) +DEF_METHOD(Ne,       1, ID($ne)) +DEF_METHOD(Eqx,      1, ID($eqx)) +DEF_METHOD(Nex,      1, ID($nex)) +DEF_METHOD(Ge,       1, ID($ge)) +DEF_METHOD(Gt,       1, ID($gt)) +DEF_METHOD(Add,      max(sig_a.size(), sig_b.size()), ID($add)) +DEF_METHOD(Sub,      max(sig_a.size(), sig_b.size()), ID($sub)) +DEF_METHOD(Mul,      max(sig_a.size(), sig_b.size()), ID($mul)) +DEF_METHOD(Div,      max(sig_a.size(), sig_b.size()), ID($div)) +DEF_METHOD(Mod,      max(sig_a.size(), sig_b.size()), ID($mod)) +DEF_METHOD(LogicAnd, 1, ID($logic_and)) +DEF_METHOD(LogicOr,  1, ID($logic_or))  #undef DEF_METHOD  #define DEF_METHOD(_func, _type, _pmux) \  	RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y, const std::string &src) { \  		RTLIL::Cell *cell = addCell(name, _type);                 \ -		cell->parameters["\\WIDTH"] = sig_a.size();               \ -		if (_pmux) cell->parameters["\\S_WIDTH"] = sig_s.size();  \ -		cell->setPort("\\A", sig_a);                              \ -		cell->setPort("\\B", sig_b);                              \ -		cell->setPort("\\S", sig_s);                              \ -		cell->setPort("\\Y", sig_y);                              \ +		cell->parameters[ID(WIDTH)] = sig_a.size();               \ +		if (_pmux) cell->parameters[ID(S_WIDTH)] = sig_s.size();  \ +		cell->setPort(ID::A, sig_a);                              \ +		cell->setPort(ID::B, sig_b);                              \ +		cell->setPort(ID(S), sig_s);                              \ +		cell->setPort(ID::Y, sig_y);                              \  		cell->set_src_attribute(src);                             \  		return cell;                                              \  	} \ @@ -1903,8 +1915,8 @@ DEF_METHOD(LogicOr,  1, "$logic_or")  		add ## _func(name, sig_a, sig_b, sig_s, sig_y, src);      \  		return sig_y;                                             \  	} -DEF_METHOD(Mux,      "$mux",        0) -DEF_METHOD(Pmux,     "$pmux",       1) +DEF_METHOD(Mux,      ID($mux),        0) +DEF_METHOD(Pmux,     ID($pmux),       1)  #undef DEF_METHOD  #define DEF_METHOD_2(_func, _type, _P1, _P2) \ @@ -1965,21 +1977,22 @@ DEF_METHOD(Pmux,     "$pmux",       1)  		add ## _func(name, sig1, sig2, sig3, sig4, sig5, src); \  		return sig5;                                           \  	} -DEF_METHOD_2(BufGate,    "$_BUF_",    A, Y) -DEF_METHOD_2(NotGate,    "$_NOT_",    A, Y) -DEF_METHOD_3(AndGate,    "$_AND_",    A, B, Y) -DEF_METHOD_3(NandGate,   "$_NAND_",   A, B, Y) -DEF_METHOD_3(OrGate,     "$_OR_",     A, B, Y) -DEF_METHOD_3(NorGate,    "$_NOR_",    A, B, Y) -DEF_METHOD_3(XorGate,    "$_XOR_",    A, B, Y) -DEF_METHOD_3(XnorGate,   "$_XNOR_",   A, B, Y) -DEF_METHOD_3(AndnotGate, "$_ANDNOT_", A, B, Y) -DEF_METHOD_3(OrnotGate,  "$_ORNOT_",  A, B, Y) -DEF_METHOD_4(MuxGate,    "$_MUX_",    A, B, S, Y) -DEF_METHOD_4(Aoi3Gate,   "$_AOI3_",   A, B, C, Y) -DEF_METHOD_4(Oai3Gate,   "$_OAI3_",   A, B, C, Y) -DEF_METHOD_5(Aoi4Gate,   "$_AOI4_",   A, B, C, D, Y) -DEF_METHOD_5(Oai4Gate,   "$_OAI4_",   A, B, C, D, Y) +DEF_METHOD_2(BufGate,    ID($_BUF_),    A, Y) +DEF_METHOD_2(NotGate,    ID($_NOT_),    A, Y) +DEF_METHOD_3(AndGate,    ID($_AND_),    A, B, Y) +DEF_METHOD_3(NandGate,   ID($_NAND_),   A, B, Y) +DEF_METHOD_3(OrGate,     ID($_OR_),     A, B, Y) +DEF_METHOD_3(NorGate,    ID($_NOR_),    A, B, Y) +DEF_METHOD_3(XorGate,    ID($_XOR_),    A, B, Y) +DEF_METHOD_3(XnorGate,   ID($_XNOR_),   A, B, Y) +DEF_METHOD_3(AndnotGate, ID($_ANDNOT_), A, B, Y) +DEF_METHOD_3(OrnotGate,  ID($_ORNOT_),  A, B, Y) +DEF_METHOD_4(MuxGate,    ID($_MUX_),    A, B, S, Y) +DEF_METHOD_4(NmuxGate,   ID($_NMUX_),   A, B, S, Y) +DEF_METHOD_4(Aoi3Gate,   ID($_AOI3_),   A, B, C, Y) +DEF_METHOD_4(Oai3Gate,   ID($_OAI3_),   A, B, C, Y) +DEF_METHOD_5(Aoi4Gate,   ID($_AOI4_),   A, B, C, D, Y) +DEF_METHOD_5(Oai4Gate,   ID($_OAI4_),   A, B, C, D, Y)  #undef DEF_METHOD_2  #undef DEF_METHOD_3  #undef DEF_METHOD_4 @@ -1987,165 +2000,165 @@ DEF_METHOD_5(Oai4Gate,   "$_OAI4_",   A, B, C, D, Y)  RTLIL::Cell* RTLIL::Module::addPow(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool a_signed, bool b_signed, const std::string &src)  { -	RTLIL::Cell *cell = addCell(name, "$pow"); -	cell->parameters["\\A_SIGNED"] = a_signed; -	cell->parameters["\\B_SIGNED"] = b_signed; -	cell->parameters["\\A_WIDTH"] = sig_a.size(); -	cell->parameters["\\B_WIDTH"] = sig_b.size(); -	cell->parameters["\\Y_WIDTH"] = sig_y.size(); -	cell->setPort("\\A", sig_a); -	cell->setPort("\\B", sig_b); -	cell->setPort("\\Y", sig_y); +	RTLIL::Cell *cell = addCell(name, ID($pow)); +	cell->parameters[ID(A_SIGNED)] = a_signed; +	cell->parameters[ID(B_SIGNED)] = b_signed; +	cell->parameters[ID(A_WIDTH)] = sig_a.size(); +	cell->parameters[ID(B_WIDTH)] = sig_b.size(); +	cell->parameters[ID(Y_WIDTH)] = sig_y.size(); +	cell->setPort(ID::A, sig_a); +	cell->setPort(ID::B, sig_b); +	cell->setPort(ID::Y, sig_y);  	cell->set_src_attribute(src);  	return cell;  }  RTLIL::Cell* RTLIL::Module::addSlice(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const offset, const std::string &src)  { -	RTLIL::Cell *cell = addCell(name, "$slice"); -	cell->parameters["\\A_WIDTH"] = sig_a.size(); -	cell->parameters["\\Y_WIDTH"] = sig_y.size(); -	cell->parameters["\\OFFSET"] = offset; -	cell->setPort("\\A", sig_a); -	cell->setPort("\\Y", sig_y); +	RTLIL::Cell *cell = addCell(name, ID($slice)); +	cell->parameters[ID(A_WIDTH)] = sig_a.size(); +	cell->parameters[ID(Y_WIDTH)] = sig_y.size(); +	cell->parameters[ID(OFFSET)] = offset; +	cell->setPort(ID::A, sig_a); +	cell->setPort(ID::Y, sig_y);  	cell->set_src_attribute(src);  	return cell;  }  RTLIL::Cell* RTLIL::Module::addConcat(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, const std::string &src)  { -	RTLIL::Cell *cell = addCell(name, "$concat"); -	cell->parameters["\\A_WIDTH"] = sig_a.size(); -	cell->parameters["\\B_WIDTH"] = sig_b.size(); -	cell->setPort("\\A", sig_a); -	cell->setPort("\\B", sig_b); -	cell->setPort("\\Y", sig_y); +	RTLIL::Cell *cell = addCell(name, ID($concat)); +	cell->parameters[ID(A_WIDTH)] = sig_a.size(); +	cell->parameters[ID(B_WIDTH)] = sig_b.size(); +	cell->setPort(ID::A, sig_a); +	cell->setPort(ID::B, sig_b); +	cell->setPort(ID::Y, sig_y);  	cell->set_src_attribute(src);  	return cell;  }  RTLIL::Cell* RTLIL::Module::addLut(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const lut, const std::string &src)  { -	RTLIL::Cell *cell = addCell(name, "$lut"); -	cell->parameters["\\LUT"] = lut; -	cell->parameters["\\WIDTH"] = sig_a.size(); -	cell->setPort("\\A", sig_a); -	cell->setPort("\\Y", sig_y); +	RTLIL::Cell *cell = addCell(name, ID($lut)); +	cell->parameters[ID(LUT)] = lut; +	cell->parameters[ID(WIDTH)] = sig_a.size(); +	cell->setPort(ID::A, sig_a); +	cell->setPort(ID::Y, sig_y);  	cell->set_src_attribute(src);  	return cell;  }  RTLIL::Cell* RTLIL::Module::addTribuf(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_y, const std::string &src)  { -	RTLIL::Cell *cell = addCell(name, "$tribuf"); -	cell->parameters["\\WIDTH"] = sig_a.size(); -	cell->setPort("\\A", sig_a); -	cell->setPort("\\EN", sig_en); -	cell->setPort("\\Y", sig_y); +	RTLIL::Cell *cell = addCell(name, ID($tribuf)); +	cell->parameters[ID(WIDTH)] = sig_a.size(); +	cell->setPort(ID::A, sig_a); +	cell->setPort(ID(EN), sig_en); +	cell->setPort(ID::Y, sig_y);  	cell->set_src_attribute(src);  	return cell;  }  RTLIL::Cell* RTLIL::Module::addAssert(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)  { -	RTLIL::Cell *cell = addCell(name, "$assert"); -	cell->setPort("\\A", sig_a); -	cell->setPort("\\EN", sig_en); +	RTLIL::Cell *cell = addCell(name, ID($assert)); +	cell->setPort(ID::A, sig_a); +	cell->setPort(ID(EN), sig_en);  	cell->set_src_attribute(src);  	return cell;  }  RTLIL::Cell* RTLIL::Module::addAssume(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)  { -	RTLIL::Cell *cell = addCell(name, "$assume"); -	cell->setPort("\\A", sig_a); -	cell->setPort("\\EN", sig_en); +	RTLIL::Cell *cell = addCell(name, ID($assume)); +	cell->setPort(ID::A, sig_a); +	cell->setPort(ID(EN), sig_en);  	cell->set_src_attribute(src);  	return cell;  }  RTLIL::Cell* RTLIL::Module::addLive(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)  { -	RTLIL::Cell *cell = addCell(name, "$live"); -	cell->setPort("\\A", sig_a); -	cell->setPort("\\EN", sig_en); +	RTLIL::Cell *cell = addCell(name, ID($live)); +	cell->setPort(ID::A, sig_a); +	cell->setPort(ID(EN), sig_en);  	cell->set_src_attribute(src);  	return cell;  }  RTLIL::Cell* RTLIL::Module::addFair(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)  { -	RTLIL::Cell *cell = addCell(name, "$fair"); -	cell->setPort("\\A", sig_a); -	cell->setPort("\\EN", sig_en); +	RTLIL::Cell *cell = addCell(name, ID($fair)); +	cell->setPort(ID::A, sig_a); +	cell->setPort(ID(EN), sig_en);  	cell->set_src_attribute(src);  	return cell;  }  RTLIL::Cell* RTLIL::Module::addCover(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)  { -	RTLIL::Cell *cell = addCell(name, "$cover"); -	cell->setPort("\\A", sig_a); -	cell->setPort("\\EN", sig_en); +	RTLIL::Cell *cell = addCell(name, ID($cover)); +	cell->setPort(ID::A, sig_a); +	cell->setPort(ID(EN), sig_en);  	cell->set_src_attribute(src);  	return cell;  }  RTLIL::Cell* RTLIL::Module::addEquiv(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, const std::string &src)  { -	RTLIL::Cell *cell = addCell(name, "$equiv"); -	cell->setPort("\\A", sig_a); -	cell->setPort("\\B", sig_b); -	cell->setPort("\\Y", sig_y); +	RTLIL::Cell *cell = addCell(name, ID($equiv)); +	cell->setPort(ID::A, sig_a); +	cell->setPort(ID::B, sig_b); +	cell->setPort(ID::Y, sig_y);  	cell->set_src_attribute(src);  	return cell;  }  RTLIL::Cell* RTLIL::Module::addSr(RTLIL::IdString name, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_q, bool set_polarity, bool clr_polarity, const std::string &src)  { -	RTLIL::Cell *cell = addCell(name, "$sr"); -	cell->parameters["\\SET_POLARITY"] = set_polarity; -	cell->parameters["\\CLR_POLARITY"] = clr_polarity; -	cell->parameters["\\WIDTH"] = sig_q.size(); -	cell->setPort("\\SET", sig_set); -	cell->setPort("\\CLR", sig_clr); -	cell->setPort("\\Q", sig_q); +	RTLIL::Cell *cell = addCell(name, ID($sr)); +	cell->parameters[ID(SET_POLARITY)] = set_polarity; +	cell->parameters[ID(CLR_POLARITY)] = clr_polarity; +	cell->parameters[ID(WIDTH)] = sig_q.size(); +	cell->setPort(ID(SET), sig_set); +	cell->setPort(ID(CLR), sig_clr); +	cell->setPort(ID(Q), sig_q);  	cell->set_src_attribute(src);  	return cell;  }  RTLIL::Cell* RTLIL::Module::addFf(RTLIL::IdString name, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, const std::string &src)  { -	RTLIL::Cell *cell = addCell(name, "$ff"); -	cell->parameters["\\WIDTH"] = sig_q.size(); -	cell->setPort("\\D", sig_d); -	cell->setPort("\\Q", sig_q); +	RTLIL::Cell *cell = addCell(name, ID($ff)); +	cell->parameters[ID(WIDTH)] = sig_q.size(); +	cell->setPort(ID(D), sig_d); +	cell->setPort(ID(Q), sig_q);  	cell->set_src_attribute(src);  	return cell;  }  RTLIL::Cell* RTLIL::Module::addDff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, const std::string &src)  { -	RTLIL::Cell *cell = addCell(name, "$dff"); -	cell->parameters["\\CLK_POLARITY"] = clk_polarity; -	cell->parameters["\\WIDTH"] = sig_q.size(); -	cell->setPort("\\CLK", sig_clk); -	cell->setPort("\\D", sig_d); -	cell->setPort("\\Q", sig_q); +	RTLIL::Cell *cell = addCell(name, ID($dff)); +	cell->parameters[ID(CLK_POLARITY)] = clk_polarity; +	cell->parameters[ID(WIDTH)] = sig_q.size(); +	cell->setPort(ID(CLK), sig_clk); +	cell->setPort(ID(D), sig_d); +	cell->setPort(ID(Q), sig_q);  	cell->set_src_attribute(src);  	return cell;  }  RTLIL::Cell* RTLIL::Module::addDffe(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool en_polarity, const std::string &src)  { -	RTLIL::Cell *cell = addCell(name, "$dffe"); -	cell->parameters["\\CLK_POLARITY"] = clk_polarity; -	cell->parameters["\\EN_POLARITY"] = en_polarity; -	cell->parameters["\\WIDTH"] = sig_q.size(); -	cell->setPort("\\CLK", sig_clk); -	cell->setPort("\\EN", sig_en); -	cell->setPort("\\D", sig_d); -	cell->setPort("\\Q", sig_q); +	RTLIL::Cell *cell = addCell(name, ID($dffe)); +	cell->parameters[ID(CLK_POLARITY)] = clk_polarity; +	cell->parameters[ID(EN_POLARITY)] = en_polarity; +	cell->parameters[ID(WIDTH)] = sig_q.size(); +	cell->setPort(ID(CLK), sig_clk); +	cell->setPort(ID(EN), sig_en); +	cell->setPort(ID(D), sig_d); +	cell->setPort(ID(Q), sig_q);  	cell->set_src_attribute(src);  	return cell;  } @@ -2153,16 +2166,16 @@ RTLIL::Cell* RTLIL::Module::addDffe(RTLIL::IdString name, RTLIL::SigSpec sig_clk  RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,  		RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, const std::string &src)  { -	RTLIL::Cell *cell = addCell(name, "$dffsr"); -	cell->parameters["\\CLK_POLARITY"] = clk_polarity; -	cell->parameters["\\SET_POLARITY"] = set_polarity; -	cell->parameters["\\CLR_POLARITY"] = clr_polarity; -	cell->parameters["\\WIDTH"] = sig_q.size(); -	cell->setPort("\\CLK", sig_clk); -	cell->setPort("\\SET", sig_set); -	cell->setPort("\\CLR", sig_clr); -	cell->setPort("\\D", sig_d); -	cell->setPort("\\Q", sig_q); +	RTLIL::Cell *cell = addCell(name, ID($dffsr)); +	cell->parameters[ID(CLK_POLARITY)] = clk_polarity; +	cell->parameters[ID(SET_POLARITY)] = set_polarity; +	cell->parameters[ID(CLR_POLARITY)] = clr_polarity; +	cell->parameters[ID(WIDTH)] = sig_q.size(); +	cell->setPort(ID(CLK), sig_clk); +	cell->setPort(ID(SET), sig_set); +	cell->setPort(ID(CLR), sig_clr); +	cell->setPort(ID(D), sig_d); +	cell->setPort(ID(Q), sig_q);  	cell->set_src_attribute(src);  	return cell;  } @@ -2170,27 +2183,27 @@ RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, RTLIL::SigSpec sig_cl  RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q,  		RTLIL::Const arst_value, bool clk_polarity, bool arst_polarity, const std::string &src)  { -	RTLIL::Cell *cell = addCell(name, "$adff"); -	cell->parameters["\\CLK_POLARITY"] = clk_polarity; -	cell->parameters["\\ARST_POLARITY"] = arst_polarity; -	cell->parameters["\\ARST_VALUE"] = arst_value; -	cell->parameters["\\WIDTH"] = sig_q.size(); -	cell->setPort("\\CLK", sig_clk); -	cell->setPort("\\ARST", sig_arst); -	cell->setPort("\\D", sig_d); -	cell->setPort("\\Q", sig_q); +	RTLIL::Cell *cell = addCell(name, ID($adff)); +	cell->parameters[ID(CLK_POLARITY)] = clk_polarity; +	cell->parameters[ID(ARST_POLARITY)] = arst_polarity; +	cell->parameters[ID(ARST_VALUE)] = arst_value; +	cell->parameters[ID(WIDTH)] = sig_q.size(); +	cell->setPort(ID(CLK), sig_clk); +	cell->setPort(ID(ARST), sig_arst); +	cell->setPort(ID(D), sig_d); +	cell->setPort(ID(Q), sig_q);  	cell->set_src_attribute(src);  	return cell;  }  RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, const std::string &src)  { -	RTLIL::Cell *cell = addCell(name, "$dlatch"); -	cell->parameters["\\EN_POLARITY"] = en_polarity; -	cell->parameters["\\WIDTH"] = sig_q.size(); -	cell->setPort("\\EN", sig_en); -	cell->setPort("\\D", sig_d); -	cell->setPort("\\Q", sig_q); +	RTLIL::Cell *cell = addCell(name, ID($dlatch)); +	cell->parameters[ID(EN_POLARITY)] = en_polarity; +	cell->parameters[ID(WIDTH)] = sig_q.size(); +	cell->setPort(ID(EN), sig_en); +	cell->setPort(ID(D), sig_d); +	cell->setPort(ID(Q), sig_q);  	cell->set_src_attribute(src);  	return cell;  } @@ -2198,25 +2211,25 @@ RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, RTLIL::SigSpec sig_e  RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,  		RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src)  { -	RTLIL::Cell *cell = addCell(name, "$dlatchsr"); -	cell->parameters["\\EN_POLARITY"] = en_polarity; -	cell->parameters["\\SET_POLARITY"] = set_polarity; -	cell->parameters["\\CLR_POLARITY"] = clr_polarity; -	cell->parameters["\\WIDTH"] = sig_q.size(); -	cell->setPort("\\EN", sig_en); -	cell->setPort("\\SET", sig_set); -	cell->setPort("\\CLR", sig_clr); -	cell->setPort("\\D", sig_d); -	cell->setPort("\\Q", sig_q); +	RTLIL::Cell *cell = addCell(name, ID($dlatchsr)); +	cell->parameters[ID(EN_POLARITY)] = en_polarity; +	cell->parameters[ID(SET_POLARITY)] = set_polarity; +	cell->parameters[ID(CLR_POLARITY)] = clr_polarity; +	cell->parameters[ID(WIDTH)] = sig_q.size(); +	cell->setPort(ID(EN), sig_en); +	cell->setPort(ID(SET), sig_set); +	cell->setPort(ID(CLR), sig_clr); +	cell->setPort(ID(D), sig_d); +	cell->setPort(ID(Q), sig_q);  	cell->set_src_attribute(src);  	return cell;  }  RTLIL::Cell* RTLIL::Module::addFfGate(RTLIL::IdString name, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, const std::string &src)  { -	RTLIL::Cell *cell = addCell(name, "$_FF_"); -	cell->setPort("\\D", sig_d); -	cell->setPort("\\Q", sig_q); +	RTLIL::Cell *cell = addCell(name, ID($_FF_)); +	cell->setPort(ID(D), sig_d); +	cell->setPort(ID(Q), sig_q);  	cell->set_src_attribute(src);  	return cell;  } @@ -2224,9 +2237,9 @@ RTLIL::Cell* RTLIL::Module::addFfGate(RTLIL::IdString name, RTLIL::SigSpec sig_d  RTLIL::Cell* RTLIL::Module::addDffGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, const std::string &src)  {  	RTLIL::Cell *cell = addCell(name, stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N')); -	cell->setPort("\\C", sig_clk); -	cell->setPort("\\D", sig_d); -	cell->setPort("\\Q", sig_q); +	cell->setPort(ID(C), sig_clk); +	cell->setPort(ID(D), sig_d); +	cell->setPort(ID(Q), sig_q);  	cell->set_src_attribute(src);  	return cell;  } @@ -2234,10 +2247,10 @@ RTLIL::Cell* RTLIL::Module::addDffGate(RTLIL::IdString name, RTLIL::SigSpec sig_  RTLIL::Cell* RTLIL::Module::addDffeGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool en_polarity, const std::string &src)  {  	RTLIL::Cell *cell = addCell(name, stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')); -	cell->setPort("\\C", sig_clk); -	cell->setPort("\\E", sig_en); -	cell->setPort("\\D", sig_d); -	cell->setPort("\\Q", sig_q); +	cell->setPort(ID(C), sig_clk); +	cell->setPort(ID(E), sig_en); +	cell->setPort(ID(D), sig_d); +	cell->setPort(ID(Q), sig_q);  	cell->set_src_attribute(src);  	return cell;  } @@ -2246,11 +2259,11 @@ RTLIL::Cell* RTLIL::Module::addDffsrGate(RTLIL::IdString name, RTLIL::SigSpec si  		RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, const std::string &src)  {  	RTLIL::Cell *cell = addCell(name, stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')); -	cell->setPort("\\C", sig_clk); -	cell->setPort("\\S", sig_set); -	cell->setPort("\\R", sig_clr); -	cell->setPort("\\D", sig_d); -	cell->setPort("\\Q", sig_q); +	cell->setPort(ID(C), sig_clk); +	cell->setPort(ID(S), sig_set); +	cell->setPort(ID(R), sig_clr); +	cell->setPort(ID(D), sig_d); +	cell->setPort(ID(Q), sig_q);  	cell->set_src_attribute(src);  	return cell;  } @@ -2259,10 +2272,10 @@ RTLIL::Cell* RTLIL::Module::addAdffGate(RTLIL::IdString name, RTLIL::SigSpec sig  		bool arst_value, bool clk_polarity, bool arst_polarity, const std::string &src)  {  	RTLIL::Cell *cell = addCell(name, stringf("$_DFF_%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0')); -	cell->setPort("\\C", sig_clk); -	cell->setPort("\\R", sig_arst); -	cell->setPort("\\D", sig_d); -	cell->setPort("\\Q", sig_q); +	cell->setPort(ID(C), sig_clk); +	cell->setPort(ID(R), sig_arst); +	cell->setPort(ID(D), sig_d); +	cell->setPort(ID(Q), sig_q);  	cell->set_src_attribute(src);  	return cell;  } @@ -2270,9 +2283,9 @@ RTLIL::Cell* RTLIL::Module::addAdffGate(RTLIL::IdString name, RTLIL::SigSpec sig  RTLIL::Cell* RTLIL::Module::addDlatchGate(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, const std::string &src)  {  	RTLIL::Cell *cell = addCell(name, stringf("$_DLATCH_%c_", en_polarity ? 'P' : 'N')); -	cell->setPort("\\E", sig_en); -	cell->setPort("\\D", sig_d); -	cell->setPort("\\Q", sig_q); +	cell->setPort(ID(E), sig_en); +	cell->setPort(ID(D), sig_d); +	cell->setPort(ID(Q), sig_q);  	cell->set_src_attribute(src);  	return cell;  } @@ -2281,11 +2294,11 @@ RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, RTLIL::SigSpec  		RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src)  {  	RTLIL::Cell *cell = addCell(name, stringf("$_DLATCHSR_%c%c%c_", en_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')); -	cell->setPort("\\E", sig_en); -	cell->setPort("\\S", sig_set); -	cell->setPort("\\R", sig_clr); -	cell->setPort("\\D", sig_d); -	cell->setPort("\\Q", sig_q); +	cell->setPort(ID(E), sig_en); +	cell->setPort(ID(S), sig_set); +	cell->setPort(ID(R), sig_clr); +	cell->setPort(ID(D), sig_d); +	cell->setPort(ID(Q), sig_q);  	cell->set_src_attribute(src);  	return cell;  } @@ -2293,9 +2306,9 @@ RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, RTLIL::SigSpec  RTLIL::SigSpec RTLIL::Module::Anyconst(RTLIL::IdString name, int width, const std::string &src)  {  	RTLIL::SigSpec sig = addWire(NEW_ID, width); -	Cell *cell = addCell(name, "$anyconst"); -	cell->setParam("\\WIDTH", width); -	cell->setPort("\\Y", sig); +	Cell *cell = addCell(name, ID($anyconst)); +	cell->setParam(ID(WIDTH), width); +	cell->setPort(ID::Y, sig);  	cell->set_src_attribute(src);  	return sig;  } @@ -2303,9 +2316,9 @@ RTLIL::SigSpec RTLIL::Module::Anyconst(RTLIL::IdString name, int width, const st  RTLIL::SigSpec RTLIL::Module::Anyseq(RTLIL::IdString name, int width, const std::string &src)  {  	RTLIL::SigSpec sig = addWire(NEW_ID, width); -	Cell *cell = addCell(name, "$anyseq"); -	cell->setParam("\\WIDTH", width); -	cell->setPort("\\Y", sig); +	Cell *cell = addCell(name, ID($anyseq)); +	cell->setParam(ID(WIDTH), width); +	cell->setPort(ID::Y, sig);  	cell->set_src_attribute(src);  	return sig;  } @@ -2313,9 +2326,9 @@ RTLIL::SigSpec RTLIL::Module::Anyseq(RTLIL::IdString name, int width, const std:  RTLIL::SigSpec RTLIL::Module::Allconst(RTLIL::IdString name, int width, const std::string &src)  {  	RTLIL::SigSpec sig = addWire(NEW_ID, width); -	Cell *cell = addCell(name, "$allconst"); -	cell->setParam("\\WIDTH", width); -	cell->setPort("\\Y", sig); +	Cell *cell = addCell(name, ID($allconst)); +	cell->setParam(ID(WIDTH), width); +	cell->setPort(ID::Y, sig);  	cell->set_src_attribute(src);  	return sig;  } @@ -2323,9 +2336,9 @@ RTLIL::SigSpec RTLIL::Module::Allconst(RTLIL::IdString name, int width, const st  RTLIL::SigSpec RTLIL::Module::Allseq(RTLIL::IdString name, int width, const std::string &src)  {  	RTLIL::SigSpec sig = addWire(NEW_ID, width); -	Cell *cell = addCell(name, "$allseq"); -	cell->setParam("\\WIDTH", width); -	cell->setPort("\\Y", sig); +	Cell *cell = addCell(name, ID($allseq)); +	cell->setParam(ID(WIDTH), width); +	cell->setPort(ID::Y, sig);  	cell->set_src_attribute(src);  	return sig;  } @@ -2333,8 +2346,8 @@ RTLIL::SigSpec RTLIL::Module::Allseq(RTLIL::IdString name, int width, const std:  RTLIL::SigSpec RTLIL::Module::Initstate(RTLIL::IdString name, const std::string &src)  {  	RTLIL::SigSpec sig = addWire(NEW_ID); -	Cell *cell = addCell(name, "$initstate"); -	cell->setPort("\\Y", sig); +	Cell *cell = addCell(name, ID($initstate)); +	cell->setPort(ID::Y, sig);  	cell->set_src_attribute(src);  	return sig;  } @@ -2551,60 +2564,60 @@ void RTLIL::Cell::check()  void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)  { -	if (type.substr(0, 1) != "$" || type.substr(0, 2) == "$_" || type.substr(0, 8) == "$paramod" || type.substr(0,10) == "$fmcombine" || -			type.substr(0, 9) == "$verific$" || type.substr(0, 7) == "$array:" || type.substr(0, 8) == "$extern:") +	if (!type.begins_with("$") || type.begins_with("$_") || type.begins_with("$paramod") || type.begins_with("$fmcombine") || +			type.begins_with("$verific$") || type.begins_with("$array:") || type.begins_with("$extern:"))  		return; -	if (type == "$mux" || type == "$pmux") { -		parameters["\\WIDTH"] = GetSize(connections_["\\Y"]); -		if (type == "$pmux") -			parameters["\\S_WIDTH"] = GetSize(connections_["\\S"]); +	if (type == ID($mux) || type == ID($pmux)) { +		parameters[ID(WIDTH)] = GetSize(connections_[ID::Y]); +		if (type == ID($pmux)) +			parameters[ID(S_WIDTH)] = GetSize(connections_[ID(S)]);  		check();  		return;  	} -	if (type == "$lut" || type == "$sop") { -		parameters["\\WIDTH"] = GetSize(connections_["\\A"]); +	if (type == ID($lut) || type == ID($sop)) { +		parameters[ID(WIDTH)] = GetSize(connections_[ID::A]);  		return;  	} -	if (type == "$fa") { -		parameters["\\WIDTH"] = GetSize(connections_["\\Y"]); +	if (type == ID($fa)) { +		parameters[ID(WIDTH)] = GetSize(connections_[ID::Y]);  		return;  	} -	if (type == "$lcu") { -		parameters["\\WIDTH"] = GetSize(connections_["\\CO"]); +	if (type == ID($lcu)) { +		parameters[ID(WIDTH)] = GetSize(connections_[ID(CO)]);  		return;  	} -	bool signedness_ab = !type.in("$slice", "$concat", "$macc"); +	bool signedness_ab = !type.in(ID($slice), ID($concat), ID($macc)); -	if (connections_.count("\\A")) { +	if (connections_.count(ID::A)) {  		if (signedness_ab) {  			if (set_a_signed) -				parameters["\\A_SIGNED"] = true; -			else if (parameters.count("\\A_SIGNED") == 0) -				parameters["\\A_SIGNED"] = false; +				parameters[ID(A_SIGNED)] = true; +			else if (parameters.count(ID(A_SIGNED)) == 0) +				parameters[ID(A_SIGNED)] = false;  		} -		parameters["\\A_WIDTH"] = GetSize(connections_["\\A"]); +		parameters[ID(A_WIDTH)] = GetSize(connections_[ID::A]);  	} -	if (connections_.count("\\B")) { +	if (connections_.count(ID::B)) {  		if (signedness_ab) {  			if (set_b_signed) -				parameters["\\B_SIGNED"] = true; -			else if (parameters.count("\\B_SIGNED") == 0) -				parameters["\\B_SIGNED"] = false; +				parameters[ID(B_SIGNED)] = true; +			else if (parameters.count(ID(B_SIGNED)) == 0) +				parameters[ID(B_SIGNED)] = false;  		} -		parameters["\\B_WIDTH"] = GetSize(connections_["\\B"]); +		parameters[ID(B_WIDTH)] = GetSize(connections_[ID::B]);  	} -	if (connections_.count("\\Y")) -		parameters["\\Y_WIDTH"] = GetSize(connections_["\\Y"]); +	if (connections_.count(ID::Y)) +		parameters[ID(Y_WIDTH)] = GetSize(connections_[ID::Y]); -	if (connections_.count("\\Q")) -		parameters["\\WIDTH"] = GetSize(connections_["\\Q"]); +	if (connections_.count(ID(Q))) +		parameters[ID(WIDTH)] = GetSize(connections_[ID(Q)]);  	check();  } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 82cbfaf28..c08653b65 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -78,6 +78,8 @@ namespace RTLIL  	{  		#undef YOSYS_XTRACE_GET_PUT  		#undef YOSYS_SORT_ID_FREE_LIST +		#undef YOSYS_USE_STICKY_IDS +		#undef YOSYS_NO_IDS_REFCNT  		// the global id string cache @@ -87,13 +89,17 @@ namespace RTLIL  			~destruct_guard_t() { ok = false; }  		} destruct_guard; -		static std::vector<int> global_refcount_storage_;  		static std::vector<char*> global_id_storage_;  		static dict<char*, int, hash_cstr_ops> global_id_index_; +	#ifndef YOSYS_NO_IDS_REFCNT +		static std::vector<int> global_refcount_storage_;  		static std::vector<int> global_free_idx_list_; +	#endif +	#ifdef YOSYS_USE_STICKY_IDS  		static int last_created_idx_ptr_;  		static int last_created_idx_[8]; +	#endif  		static inline void xtrace_db_dump()  		{ @@ -110,12 +116,14 @@ namespace RTLIL  		static inline void checkpoint()  		{ +		#ifdef YOSYS_USE_STICKY_IDS  			last_created_idx_ptr_ = 0;  			for (int i = 0; i < 8; i++) {  				if (last_created_idx_[i])  					put_reference(last_created_idx_[i]);  				last_created_idx_[i] = 0;  			} +		#endif  		#ifdef YOSYS_SORT_ID_FREE_LIST  			std::sort(global_free_idx_list_.begin(), global_free_idx_list_.end(), std::greater<int>());  		#endif @@ -123,36 +131,47 @@ namespace RTLIL  		static inline int get_reference(int idx)  		{ -			global_refcount_storage_.at(idx)++; +			if (idx) { +		#ifndef YOSYS_NO_IDS_REFCNT +				global_refcount_storage_[idx]++; +		#endif  		#ifdef YOSYS_XTRACE_GET_PUT -			if (yosys_xtrace) { -				log("#X# GET-BY-INDEX '%s' (index %d, refcount %d)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx)); -			} +				if (yosys_xtrace) +					log("#X# GET-BY-INDEX '%s' (index %d, refcount %d)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx));  		#endif +			}  			return idx;  		} -		static inline int get_reference(const char *p) +		static int get_reference(const char *p)  		{  			log_assert(destruct_guard.ok); -			if (p[0]) { -				log_assert(p[1] != 0); -				log_assert(p[0] == '$' || p[0] == '\\'); -			} +			if (!p[0]) +				return 0; + +			log_assert(p[0] == '$' || p[0] == '\\'); +			log_assert(p[1] != 0);  			auto it = global_id_index_.find((char*)p);  			if (it != global_id_index_.end()) { +		#ifndef YOSYS_NO_IDS_REFCNT  				global_refcount_storage_.at(it->second)++; +		#endif  		#ifdef YOSYS_XTRACE_GET_PUT -				if (yosys_xtrace) { +				if (yosys_xtrace)  					log("#X# GET-BY-NAME '%s' (index %d, refcount %d)\n", global_id_storage_.at(it->second), it->second, global_refcount_storage_.at(it->second)); -				}  		#endif  				return it->second;  			} +		#ifndef YOSYS_NO_IDS_REFCNT  			if (global_free_idx_list_.empty()) { +				if (global_id_storage_.empty()) { +					global_refcount_storage_.push_back(0); +					global_id_storage_.push_back((char*)""); +					global_id_index_[global_id_storage_.back()] = 0; +				}  				log_assert(global_id_storage_.size() < 0x40000000);  				global_free_idx_list_.push_back(global_id_storage_.size());  				global_id_storage_.push_back(nullptr); @@ -164,13 +183,15 @@ namespace RTLIL  			global_id_storage_.at(idx) = strdup(p);  			global_id_index_[global_id_storage_.at(idx)] = idx;  			global_refcount_storage_.at(idx)++; - -			// Avoid Create->Delete->Create pattern -			if (last_created_idx_[last_created_idx_ptr_]) -				put_reference(last_created_idx_[last_created_idx_ptr_]); -			last_created_idx_[last_created_idx_ptr_] = idx; -			get_reference(last_created_idx_[last_created_idx_ptr_]); -			last_created_idx_ptr_ = (last_created_idx_ptr_ + 1) & 7; +		#else +			if (global_id_storage_.empty()) { +				global_id_storage_.push_back((char*)""); +				global_id_index_[global_id_storage_.back()] = 0; +			} +			int idx = global_id_storage_.size(); +			global_id_storage_.push_back(strdup(p)); +			global_id_index_[global_id_storage_.back()] = idx; +		#endif  			if (yosys_xtrace) {  				log("#X# New IdString '%s' with index %d.\n", p, idx); @@ -178,18 +199,28 @@ namespace RTLIL  			}  		#ifdef YOSYS_XTRACE_GET_PUT -			if (yosys_xtrace) { +			if (yosys_xtrace)  				log("#X# GET-BY-NAME '%s' (index %d, refcount %d)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx)); -			}  		#endif + +		#ifdef YOSYS_USE_STICKY_IDS +			// Avoid Create->Delete->Create pattern +			if (last_created_idx_[last_created_idx_ptr_]) +				put_reference(last_created_idx_[last_created_idx_ptr_]); +			last_created_idx_[last_created_idx_ptr_] = idx; +			get_reference(last_created_idx_[last_created_idx_ptr_]); +			last_created_idx_ptr_ = (last_created_idx_ptr_ + 1) & 7; +		#endif +  			return idx;  		} +	#ifndef YOSYS_NO_IDS_REFCNT  		static inline void put_reference(int idx)  		{  			// put_reference() may be called from destructors after the destructor of  			// global_refcount_storage_ has been run. in this case we simply do nothing. -			if (!destruct_guard.ok) +			if (!destruct_guard.ok || !idx)  				return;  		#ifdef YOSYS_XTRACE_GET_PUT @@ -198,11 +229,13 @@ namespace RTLIL  			}  		#endif -			log_assert(global_refcount_storage_.at(idx) > 0); +			int &refcount = global_refcount_storage_[idx]; -			if (--global_refcount_storage_.at(idx) != 0) +			if (--refcount > 0)  				return; +			log_assert(refcount == 0); +  			if (yosys_xtrace) {  				log("#X# Removed IdString '%s' with index %d.\n", global_id_storage_.at(idx), idx);  				log_backtrace("-X- ", yosys_xtrace-1); @@ -213,46 +246,50 @@ namespace RTLIL  			global_id_storage_.at(idx) = nullptr;  			global_free_idx_list_.push_back(idx);  		} +	#else +		static inline void put_reference(int) { } +	#endif  		// the actual IdString object is just is a single int  		int index_; -		IdString() : index_(get_reference("")) { } -		IdString(const char *str) : index_(get_reference(str)) { } -		IdString(const IdString &str) : index_(get_reference(str.index_)) { } -		IdString(const std::string &str) : index_(get_reference(str.c_str())) { } -		~IdString() { put_reference(index_); } +		inline IdString() : index_(0) { } +		inline IdString(const char *str) : index_(get_reference(str)) { } +		inline IdString(const IdString &str) : index_(get_reference(str.index_)) { } +		inline IdString(IdString &&str) : index_(str.index_) { str.index_ = 0; } +		inline IdString(const std::string &str) : index_(get_reference(str.c_str())) { } +		inline ~IdString() { put_reference(index_); } -		void operator=(const IdString &rhs) { +		inline void operator=(const IdString &rhs) {  			put_reference(index_);  			index_ = get_reference(rhs.index_);  		} -		void operator=(const char *rhs) { +		inline void operator=(const char *rhs) {  			IdString id(rhs);  			*this = id;  		} -		void operator=(const std::string &rhs) { +		inline void operator=(const std::string &rhs) {  			IdString id(rhs);  			*this = id;  		} -		const char *c_str() const { +		inline const char *c_str() const {  			return global_id_storage_.at(index_);  		} -		std::string str() const { +		inline std::string str() const {  			return std::string(global_id_storage_.at(index_));  		} -		bool operator<(const IdString &rhs) const { +		inline bool operator<(const IdString &rhs) const {  			return index_ < rhs.index_;  		} -		bool operator==(const IdString &rhs) const { return index_ == rhs.index_; } -		bool operator!=(const IdString &rhs) const { return index_ != rhs.index_; } +		inline bool operator==(const IdString &rhs) const { return index_ == rhs.index_; } +		inline bool operator!=(const IdString &rhs) const { return index_ != rhs.index_; }  		// The methods below are just convenience functions for better compatibility with std::string. @@ -276,20 +313,24 @@ namespace RTLIL  				return std::string(c_str() + pos, len);  		} +		int compare(size_t pos, size_t len, const char* s) const { +			return strncmp(c_str()+pos, s, len); +		} +  		bool begins_with(const char* prefix) const {  			size_t len = strlen(prefix);  			if (size() < len) return false; -			return substr(0, len) == prefix; +			return compare(0, len, prefix) == 0;  		}  		bool ends_with(const char* suffix) const {  			size_t len = strlen(suffix);  			if (size() < len) return false; -			return substr(size()-len) == suffix; +			return compare(size()-len, len, suffix) == 0;  		}  		size_t size() const { -			return str().size(); +			return strlen(c_str());  		}  		bool empty() const { @@ -328,6 +369,14 @@ namespace RTLIL  		bool in(const pool<IdString> &rhs) const { return rhs.count(*this) != 0; }  	}; +	namespace ID { +		// defined in rtlil.cc, initialized in yosys.cc +		extern IdString A, B, Y; +		extern IdString keep; +		extern IdString whitebox; +		extern IdString blackbox; +	}; +  	static inline std::string escape_id(std::string str) {  		if (str.size() > 0 && str[0] != '\\' && str[0] != '$')  			return "\\" + str; @@ -420,8 +469,12 @@ namespace RTLIL  	// It maintains a reference counter that is used to make sure that the container is not modified while being iterated over.  	template<typename T> -	struct ObjIterator -	{ +	struct ObjIterator { +		using iterator_category = std::forward_iterator_tag; +		using value_type = T; +		using difference_type = ptrdiff_t; +		using pointer = T*; +		using reference = T&;  		typename dict<RTLIL::IdString, T>::iterator it;  		dict<RTLIL::IdString, T> *list_p;  		int *refcount_p; @@ -474,13 +527,25 @@ namespace RTLIL  			return it != other.it;  		} -		inline void operator++() { + +		inline bool operator==(const RTLIL::ObjIterator<T> &other) const { +			return !(*this != other); +		} + +		inline ObjIterator<T>& operator++() {  			log_assert(list_p != nullptr);  			if (++it == list_p->end()) {  				(*refcount_p)--;  				list_p = nullptr;  				refcount_p = nullptr;  			} +			return *this; +		} + +		inline const ObjIterator<T> operator++(int) { +			ObjIterator<T> result(*this); +			++(*this); +			return result;  		}  	}; @@ -584,7 +649,7 @@ struct RTLIL::AttrObject  	bool get_bool_attribute(RTLIL::IdString id) const;  	bool get_blackbox_attribute(bool ignore_wb=false) const { -		return get_bool_attribute("\\blackbox") || (!ignore_wb && get_bool_attribute("\\whitebox")); +		return get_bool_attribute(ID::blackbox) || (!ignore_wb && get_bool_attribute(ID::whitebox));  	}  	void set_strpool_attribute(RTLIL::IdString id, const pool<string> &data); @@ -772,6 +837,7 @@ public:  	RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other = NULL) const;  	RTLIL::SigSpec extract(const pool<RTLIL::SigBit> &pattern, const RTLIL::SigSpec *other = NULL) const;  	RTLIL::SigSpec extract(int offset, int length = 1) const; +	RTLIL::SigSpec extract_end(int offset) const { return extract(offset, width_ - offset); }  	void append(const RTLIL::SigSpec &signal);  	void append_bit(const RTLIL::SigBit &bit); @@ -818,6 +884,7 @@ public:  	operator std::vector<RTLIL::SigChunk>() const { return chunks(); }  	operator std::vector<RTLIL::SigBit>() const { return bits(); } +	RTLIL::SigBit at(int offset, const RTLIL::SigBit &defval) { return offset < width_ ? (*this)[offset] : defval; }  	unsigned int hash() const { if (!hash_) updhash(); return hash_; }; @@ -1138,6 +1205,7 @@ public:  	RTLIL::Cell* addAndnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = "");  	RTLIL::Cell* addOrnotGate  (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = "");  	RTLIL::Cell* addMuxGate    (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, RTLIL::SigBit sig_y, const std::string &src = ""); +	RTLIL::Cell* addNmuxGate   (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, RTLIL::SigBit sig_y, const std::string &src = "");  	RTLIL::Cell* addAoi3Gate   (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_y, const std::string &src = "");  	RTLIL::Cell* addOai3Gate   (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_y, const std::string &src = "");  	RTLIL::Cell* addAoi4Gate   (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, RTLIL::SigBit sig_y, const std::string &src = ""); @@ -1213,6 +1281,7 @@ public:  	RTLIL::SigBit AndnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = "");  	RTLIL::SigBit OrnotGate  (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = "");  	RTLIL::SigBit MuxGate    (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, const std::string &src = ""); +	RTLIL::SigBit NmuxGate   (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, const std::string &src = "");  	RTLIL::SigBit Aoi3Gate   (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, const std::string &src = "");  	RTLIL::SigBit Oai3Gate   (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, const std::string &src = "");  	RTLIL::SigBit Aoi4Gate   (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, const std::string &src = ""); @@ -1315,8 +1384,8 @@ public:  	void fixup_parameters(bool set_a_signed = false, bool set_b_signed = false);  	bool has_keep_attr() const { -		return get_bool_attribute("\\keep") || (module && module->design && module->design->module(type) && -				module->design->module(type)->get_bool_attribute("\\keep")); +		return get_bool_attribute(ID::keep) || (module && module->design && module->design->module(type) && +				module->design->module(type)->get_bool_attribute(ID::keep));  	}  	template<typename T> void rewrite_sigspecs(T &functor); @@ -1384,7 +1453,7 @@ struct RTLIL::Process : public RTLIL::AttrObject  inline RTLIL::SigBit::SigBit() : wire(NULL), data(RTLIL::State::S0) { }  inline RTLIL::SigBit::SigBit(RTLIL::State bit) : wire(NULL), data(bit) { } -inline RTLIL::SigBit::SigBit(bool bit) : wire(NULL), data(bit ? RTLIL::S1 : RTLIL::S0) { } +inline RTLIL::SigBit::SigBit(bool bit) : wire(NULL), data(bit ? State::S1 : State::S0) { }  inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire) : wire(wire), offset(0) { log_assert(wire && wire->width == 1); }  inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire, int offset) : wire(wire), offset(offset) { log_assert(wire != nullptr); }  inline RTLIL::SigBit::SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { log_assert(chunk.width == 1); if (wire) offset = chunk.offset; else data = chunk.data[0]; } diff --git a/kernel/satgen.h b/kernel/satgen.h index 210cca3f3..133389eee 100644 --- a/kernel/satgen.h +++ b/kernel/satgen.h @@ -224,8 +224,8 @@ struct SatGen  	void extendSignalWidth(std::vector<int> &vec_a, std::vector<int> &vec_b, RTLIL::Cell *cell, size_t y_width = 0, bool forced_signed = false)  	{  		bool is_signed = forced_signed; -		if (!forced_signed && cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters.count("\\B_SIGNED") > 0) -			is_signed = cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool(); +		if (!forced_signed && cell->parameters.count(ID(A_SIGNED)) > 0 && cell->parameters.count(ID(B_SIGNED)) > 0) +			is_signed = cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool();  		while (vec_a.size() < vec_b.size() || vec_a.size() < y_width)  			vec_a.push_back(is_signed && vec_a.size() > 0 ? vec_a.back() : ez->CONST_FALSE);  		while (vec_b.size() < vec_a.size() || vec_b.size() < y_width) @@ -241,7 +241,7 @@ struct SatGen  	void extendSignalWidthUnary(std::vector<int> &vec_a, std::vector<int> &vec_y, RTLIL::Cell *cell, bool forced_signed = false)  	{ -		bool is_signed = forced_signed || (cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters["\\A_SIGNED"].as_bool()); +		bool is_signed = forced_signed || (cell->parameters.count(ID(A_SIGNED)) > 0 && cell->parameters[ID(A_SIGNED)].as_bool());  		while (vec_a.size() < vec_y.size())  			vec_a.push_back(is_signed && vec_a.size() > 0 ? vec_a.back() : ez->CONST_FALSE);  		while (vec_y.size() < vec_a.size()) @@ -277,13 +277,13 @@ struct SatGen  	bool importCell(RTLIL::Cell *cell, int timestep = -1)  	{  		bool arith_undef_handled = false; -		bool is_arith_compare = cell->type.in("$lt", "$le", "$ge", "$gt"); +		bool is_arith_compare = cell->type.in(ID($lt), ID($le), ID($ge), ID($gt)); -		if (model_undef && (cell->type.in("$add", "$sub", "$mul", "$div", "$mod") || is_arith_compare)) +		if (model_undef && (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod)) || is_arith_compare))  		{ -			std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); -			std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); -			std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); +			std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); +			std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); +			std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);  			if (is_arith_compare)  				extendSignalWidth(undef_a, undef_b, cell, true);  			else @@ -293,8 +293,8 @@ struct SatGen  			int undef_any_b = ez->expression(ezSAT::OpOr, undef_b);  			int undef_y_bit = ez->OR(undef_any_a, undef_any_b); -			if (cell->type == "$div" || cell->type == "$mod") { -				std::vector<int> b = importSigSpec(cell->getPort("\\B"), timestep); +			if (cell->type.in(ID($div), ID($mod))) { +				std::vector<int> b = importSigSpec(cell->getPort(ID::B), timestep);  				undef_y_bit = ez->OR(undef_y_bit, ez->NOT(ez->expression(ezSAT::OpOr, b)));  			} @@ -310,68 +310,68 @@ struct SatGen  			arith_undef_handled = true;  		} -		if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_", -				"$and", "$or", "$xor", "$xnor", "$add", "$sub")) +		if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_), +				ID($and), ID($or), ID($xor), ID($xnor), ID($add), ID($sub)))  		{ -			std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep); -			std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep); -			std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep); +			std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); +			std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); +			std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);  			extendSignalWidth(a, b, y, cell);  			std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; -			if (cell->type == "$and" || cell->type == "$_AND_") +			if (cell->type.in(ID($and), ID($_AND_)))  				ez->assume(ez->vec_eq(ez->vec_and(a, b), yy)); -			if (cell->type == "$_NAND_") +			if (cell->type == ID($_NAND_))  				ez->assume(ez->vec_eq(ez->vec_not(ez->vec_and(a, b)), yy)); -			if (cell->type == "$or" || cell->type == "$_OR_") +			if (cell->type.in(ID($or), ID($_OR_)))  				ez->assume(ez->vec_eq(ez->vec_or(a, b), yy)); -			if (cell->type == "$_NOR_") +			if (cell->type == ID($_NOR_))  				ez->assume(ez->vec_eq(ez->vec_not(ez->vec_or(a, b)), yy)); -			if (cell->type == "$xor" || cell->type == "$_XOR_") +			if (cell->type.in(ID($xor), ID($_XOR_)))  				ez->assume(ez->vec_eq(ez->vec_xor(a, b), yy)); -			if (cell->type == "$xnor" || cell->type == "$_XNOR_") +			if (cell->type.in(ID($xnor), ID($_XNOR_)))  				ez->assume(ez->vec_eq(ez->vec_not(ez->vec_xor(a, b)), yy)); -			if (cell->type == "$_ANDNOT_") +			if (cell->type == ID($_ANDNOT_))  				ez->assume(ez->vec_eq(ez->vec_and(a, ez->vec_not(b)), yy)); -			if (cell->type == "$_ORNOT_") +			if (cell->type == ID($_ORNOT_))  				ez->assume(ez->vec_eq(ez->vec_or(a, ez->vec_not(b)), yy)); -			if (cell->type == "$add") +			if (cell->type == ID($add))  				ez->assume(ez->vec_eq(ez->vec_add(a, b), yy)); -			if (cell->type == "$sub") +			if (cell->type == ID($sub))  				ez->assume(ez->vec_eq(ez->vec_sub(a, b), yy));  			if (model_undef && !arith_undef_handled)  			{ -				std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); -				std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); -				std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); +				std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); +				std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); +				std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);  				extendSignalWidth(undef_a, undef_b, undef_y, cell, false); -				if (cell->type.in("$and", "$_AND_", "$_NAND_")) { +				if (cell->type.in(ID($and), ID($_AND_), ID($_NAND_))) {  					std::vector<int> a0 = ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a));  					std::vector<int> b0 = ez->vec_and(ez->vec_not(b), ez->vec_not(undef_b));  					std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a0, b0)));  					ez->assume(ez->vec_eq(yX, undef_y));  				} -				else if (cell->type.in("$or", "$_OR_", "$_NOR_")) { +				else if (cell->type.in(ID($or), ID($_OR_), ID($_NOR_))) {  					std::vector<int> a1 = ez->vec_and(a, ez->vec_not(undef_a));  					std::vector<int> b1 = ez->vec_and(b, ez->vec_not(undef_b));  					std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a1, b1)));  					ez->assume(ez->vec_eq(yX, undef_y));  				} -				else if (cell->type.in("$xor", "$xnor", "$_XOR_", "$_XNOR_")) { +				else if (cell->type.in(ID($xor), ID($xnor), ID($_XOR_), ID($_XNOR_))) {  					std::vector<int> yX = ez->vec_or(undef_a, undef_b);  					ez->assume(ez->vec_eq(yX, undef_y));  				} -				else if (cell->type == "$_ANDNOT_") { +				else if (cell->type == ID($_ANDNOT_)) {  					std::vector<int> a0 = ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a));  					std::vector<int> b1 = ez->vec_and(b, ez->vec_not(undef_b));  					std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a0, b1)));  					ez->assume(ez->vec_eq(yX, undef_y));  				} -				else if (cell->type == "$_ORNOT_") { +				else if (cell->type == ID($_ORNOT_)) {  					std::vector<int> a1 = ez->vec_and(a, ez->vec_not(undef_a));  					std::vector<int> b0 = ez->vec_and(ez->vec_not(b), ez->vec_not(undef_b));  					std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a1, b0))); @@ -384,36 +384,36 @@ struct SatGen  			}  			else if (model_undef)  			{ -				std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); +				std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);  				undefGating(y, yy, undef_y);  			}  			return true;  		} -		if (cell->type.in("$_AOI3_", "$_OAI3_", "$_AOI4_", "$_OAI4_")) +		if (cell->type.in(ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_)))  		{ -			bool aoi_mode = cell->type.in("$_AOI3_", "$_AOI4_"); -			bool three_mode = cell->type.in("$_AOI3_", "$_OAI3_"); - -			int a = importDefSigSpec(cell->getPort("\\A"), timestep).at(0); -			int b = importDefSigSpec(cell->getPort("\\B"), timestep).at(0); -			int c = importDefSigSpec(cell->getPort("\\C"), timestep).at(0); -			int d = three_mode ? (aoi_mode ? ez->CONST_TRUE : ez->CONST_FALSE) : importDefSigSpec(cell->getPort("\\D"), timestep).at(0); -			int y = importDefSigSpec(cell->getPort("\\Y"), timestep).at(0); +			bool aoi_mode = cell->type.in(ID($_AOI3_), ID($_AOI4_)); +			bool three_mode = cell->type.in(ID($_AOI3_), ID($_OAI3_)); + +			int a = importDefSigSpec(cell->getPort(ID::A), timestep).at(0); +			int b = importDefSigSpec(cell->getPort(ID::B), timestep).at(0); +			int c = importDefSigSpec(cell->getPort(ID(C)), timestep).at(0); +			int d = three_mode ? (aoi_mode ? ez->CONST_TRUE : ez->CONST_FALSE) : importDefSigSpec(cell->getPort(ID(D)), timestep).at(0); +			int y = importDefSigSpec(cell->getPort(ID::Y), timestep).at(0);  			int yy = model_undef ? ez->literal() : y; -			if (cell->type.in("$_AOI3_", "$_AOI4_")) +			if (cell->type.in(ID($_AOI3_), ID($_AOI4_)))  				ez->assume(ez->IFF(ez->NOT(ez->OR(ez->AND(a, b), ez->AND(c, d))), yy));  			else  				ez->assume(ez->IFF(ez->NOT(ez->AND(ez->OR(a, b), ez->OR(c, d))), yy));  			if (model_undef)  			{ -				int undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep).at(0); -				int undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep).at(0); -				int undef_c = importUndefSigSpec(cell->getPort("\\C"), timestep).at(0); -				int undef_d = three_mode ? ez->CONST_FALSE : importUndefSigSpec(cell->getPort("\\D"), timestep).at(0); -				int undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep).at(0); +				int undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep).at(0); +				int undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep).at(0); +				int undef_c = importUndefSigSpec(cell->getPort(ID(C)), timestep).at(0); +				int undef_d = three_mode ? ez->CONST_FALSE : importUndefSigSpec(cell->getPort(ID(D)), timestep).at(0); +				int undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep).at(0);  				if (aoi_mode)  				{ @@ -456,18 +456,18 @@ struct SatGen  			return true;  		} -		if (cell->type == "$_NOT_" || cell->type == "$not") +		if (cell->type.in(ID($_NOT_), ID($not)))  		{ -			std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep); -			std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep); +			std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); +			std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);  			extendSignalWidthUnary(a, y, cell);  			std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;  			ez->assume(ez->vec_eq(ez->vec_not(a), yy));  			if (model_undef) { -				std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); -				std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); +				std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); +				std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);  				extendSignalWidthUnary(undef_a, undef_y, cell, false);  				ez->assume(ez->vec_eq(undef_a, undef_y));  				undefGating(y, yy, undef_y); @@ -475,22 +475,25 @@ struct SatGen  			return true;  		} -		if (cell->type == "$_MUX_" || cell->type == "$mux") +		if (cell->type.in(ID($_MUX_), ID($mux), ID($_NMUX_)))  		{ -			std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep); -			std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep); -			std::vector<int> s = importDefSigSpec(cell->getPort("\\S"), timestep); -			std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep); +			std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); +			std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); +			std::vector<int> s = importDefSigSpec(cell->getPort(ID(S)), timestep); +			std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);  			std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; -			ez->assume(ez->vec_eq(ez->vec_ite(s.at(0), b, a), yy)); +			if (cell->type == ID($_NMUX_)) +				ez->assume(ez->vec_eq(ez->vec_not(ez->vec_ite(s.at(0), b, a)), yy)); +			else +				ez->assume(ez->vec_eq(ez->vec_ite(s.at(0), b, a), yy));  			if (model_undef)  			{ -				std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); -				std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); -				std::vector<int> undef_s = importUndefSigSpec(cell->getPort("\\S"), timestep); -				std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); +				std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); +				std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); +				std::vector<int> undef_s = importUndefSigSpec(cell->getPort(ID(S)), timestep); +				std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);  				std::vector<int> unequal_ab = ez->vec_not(ez->vec_iff(a, b));  				std::vector<int> undef_ab = ez->vec_or(unequal_ab, ez->vec_or(undef_a, undef_b)); @@ -501,12 +504,12 @@ struct SatGen  			return true;  		} -		if (cell->type == "$pmux") +		if (cell->type == ID($pmux))  		{ -			std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep); -			std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep); -			std::vector<int> s = importDefSigSpec(cell->getPort("\\S"), timestep); -			std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep); +			std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); +			std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); +			std::vector<int> s = importDefSigSpec(cell->getPort(ID(S)), timestep); +			std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);  			std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; @@ -519,10 +522,10 @@ struct SatGen  			if (model_undef)  			{ -				std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); -				std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); -				std::vector<int> undef_s = importUndefSigSpec(cell->getPort("\\S"), timestep); -				std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); +				std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); +				std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); +				std::vector<int> undef_s = importUndefSigSpec(cell->getPort(ID(S)), timestep); +				std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);  				int maybe_a = ez->CONST_TRUE; @@ -552,15 +555,15 @@ struct SatGen  			return true;  		} -		if (cell->type == "$pos" || cell->type == "$neg") +		if (cell->type.in(ID($pos), ID($neg)))  		{ -			std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep); -			std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep); +			std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); +			std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);  			extendSignalWidthUnary(a, y, cell);  			std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; -			if (cell->type == "$pos") { +			if (cell->type == ID($pos)) {  				ez->assume(ez->vec_eq(a, yy));  			} else {  				std::vector<int> zero(a.size(), ez->CONST_FALSE); @@ -569,11 +572,11 @@ struct SatGen  			if (model_undef)  			{ -				std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); -				std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); +				std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); +				std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);  				extendSignalWidthUnary(undef_a, undef_y, cell); -				if (cell->type == "$pos") { +				if (cell->type == ID($pos)) {  					ez->assume(ez->vec_eq(undef_a, undef_y));  				} else {  					int undef_any_a = ez->expression(ezSAT::OpOr, undef_a); @@ -586,42 +589,41 @@ struct SatGen  			return true;  		} -		if (cell->type == "$reduce_and" || cell->type == "$reduce_or" || cell->type == "$reduce_xor" || -				cell->type == "$reduce_xnor" || cell->type == "$reduce_bool" || cell->type == "$logic_not") +		if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($logic_not)))  		{ -			std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep); -			std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep); +			std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); +			std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);  			std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; -			if (cell->type == "$reduce_and") +			if (cell->type == ID($reduce_and))  				ez->SET(ez->expression(ez->OpAnd, a), yy.at(0)); -			if (cell->type == "$reduce_or" || cell->type == "$reduce_bool") +			if (cell->type.in(ID($reduce_or), ID($reduce_bool)))  				ez->SET(ez->expression(ez->OpOr, a), yy.at(0)); -			if (cell->type == "$reduce_xor") +			if (cell->type == ID($reduce_xor))  				ez->SET(ez->expression(ez->OpXor, a), yy.at(0)); -			if (cell->type == "$reduce_xnor") +			if (cell->type == ID($reduce_xnor))  				ez->SET(ez->NOT(ez->expression(ez->OpXor, a)), yy.at(0)); -			if (cell->type == "$logic_not") +			if (cell->type == ID($logic_not))  				ez->SET(ez->NOT(ez->expression(ez->OpOr, a)), yy.at(0));  			for (size_t i = 1; i < y.size(); i++)  				ez->SET(ez->CONST_FALSE, yy.at(i));  			if (model_undef)  			{ -				std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); -				std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); +				std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); +				std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);  				int aX = ez->expression(ezSAT::OpOr, undef_a); -				if (cell->type == "$reduce_and") { +				if (cell->type == ID($reduce_and)) {  					int a0 = ez->expression(ezSAT::OpOr, ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a)));  					ez->assume(ez->IFF(ez->AND(ez->NOT(a0), aX), undef_y.at(0)));  				} -				else if (cell->type == "$reduce_or" || cell->type == "$reduce_bool" || cell->type == "$logic_not") { +				else if (cell->type.in(ID($reduce_or), ID($reduce_bool), ID($logic_not))) {  					int a1 = ez->expression(ezSAT::OpOr, ez->vec_and(a, ez->vec_not(undef_a)));  					ez->assume(ez->IFF(ez->AND(ez->NOT(a1), aX), undef_y.at(0)));  				} -				else if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor") { +				else if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) {  					ez->assume(ez->IFF(aX, undef_y.at(0)));  				} else  					log_abort(); @@ -634,18 +636,18 @@ struct SatGen  			return true;  		} -		if (cell->type == "$logic_and" || cell->type == "$logic_or") +		if (cell->type.in(ID($logic_and), ID($logic_or)))  		{ -			std::vector<int> vec_a = importDefSigSpec(cell->getPort("\\A"), timestep); -			std::vector<int> vec_b = importDefSigSpec(cell->getPort("\\B"), timestep); +			std::vector<int> vec_a = importDefSigSpec(cell->getPort(ID::A), timestep); +			std::vector<int> vec_b = importDefSigSpec(cell->getPort(ID::B), timestep);  			int a = ez->expression(ez->OpOr, vec_a);  			int b = ez->expression(ez->OpOr, vec_b); -			std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep); +			std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);  			std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; -			if (cell->type == "$logic_and") +			if (cell->type == ID($logic_and))  				ez->SET(ez->expression(ez->OpAnd, a, b), yy.at(0));  			else  				ez->SET(ez->expression(ez->OpOr, a, b), yy.at(0)); @@ -654,9 +656,9 @@ struct SatGen  			if (model_undef)  			{ -				std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); -				std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); -				std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); +				std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); +				std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); +				std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);  				int a0 = ez->NOT(ez->OR(ez->expression(ezSAT::OpOr, vec_a), ez->expression(ezSAT::OpOr, undef_a)));  				int b0 = ez->NOT(ez->OR(ez->expression(ezSAT::OpOr, vec_b), ez->expression(ezSAT::OpOr, undef_b))); @@ -665,9 +667,9 @@ struct SatGen  				int aX = ez->expression(ezSAT::OpOr, undef_a);  				int bX = ez->expression(ezSAT::OpOr, undef_b); -				if (cell->type == "$logic_and") +				if (cell->type == ID($logic_and))  					ez->SET(ez->AND(ez->OR(aX, bX), ez->NOT(ez->AND(a1, b1)), ez->NOT(a0), ez->NOT(b0)), undef_y.at(0)); -				else if (cell->type == "$logic_or") +				else if (cell->type == ID($logic_or))  					ez->SET(ez->AND(ez->OR(aX, bX), ez->NOT(ez->AND(a0, b0)), ez->NOT(a1), ez->NOT(b1)), undef_y.at(0));  				else  					log_abort(); @@ -680,47 +682,47 @@ struct SatGen  			return true;  		} -		if (cell->type == "$lt" || cell->type == "$le" || cell->type == "$eq" || cell->type == "$ne" || cell->type == "$eqx" || cell->type == "$nex" || cell->type == "$ge" || cell->type == "$gt") +		if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt)))  		{ -			bool is_signed = cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool(); -			std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep); -			std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep); -			std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep); +			bool is_signed = cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool(); +			std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); +			std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); +			std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);  			extendSignalWidth(a, b, cell);  			std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; -			if (model_undef && (cell->type == "$eqx" || cell->type == "$nex")) { -				std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); -				std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); +			if (model_undef && cell->type.in(ID($eqx), ID($nex))) { +				std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); +				std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);  				extendSignalWidth(undef_a, undef_b, cell, true);  				a = ez->vec_or(a, undef_a);  				b = ez->vec_or(b, undef_b);  			} -			if (cell->type == "$lt") +			if (cell->type == ID($lt))  				ez->SET(is_signed ? ez->vec_lt_signed(a, b) : ez->vec_lt_unsigned(a, b), yy.at(0)); -			if (cell->type == "$le") +			if (cell->type == ID($le))  				ez->SET(is_signed ? ez->vec_le_signed(a, b) : ez->vec_le_unsigned(a, b), yy.at(0)); -			if (cell->type == "$eq" || cell->type == "$eqx") +			if (cell->type.in(ID($eq), ID($eqx)))  				ez->SET(ez->vec_eq(a, b), yy.at(0)); -			if (cell->type == "$ne" || cell->type == "$nex") +			if (cell->type.in(ID($ne), ID($nex)))  				ez->SET(ez->vec_ne(a, b), yy.at(0)); -			if (cell->type == "$ge") +			if (cell->type == ID($ge))  				ez->SET(is_signed ? ez->vec_ge_signed(a, b) : ez->vec_ge_unsigned(a, b), yy.at(0)); -			if (cell->type == "$gt") +			if (cell->type == ID($gt))  				ez->SET(is_signed ? ez->vec_gt_signed(a, b) : ez->vec_gt_unsigned(a, b), yy.at(0));  			for (size_t i = 1; i < y.size(); i++)  				ez->SET(ez->CONST_FALSE, yy.at(i)); -			if (model_undef && (cell->type == "$eqx" || cell->type == "$nex")) +			if (model_undef && cell->type.in(ID($eqx), ID($nex)))  			{ -				std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); -				std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); -				std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); +				std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); +				std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); +				std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);  				extendSignalWidth(undef_a, undef_b, cell, true); -				if (cell->type == "$eqx") +				if (cell->type == ID($eqx))  					yy.at(0) = ez->AND(yy.at(0), ez->vec_eq(undef_a, undef_b));  				else  					yy.at(0) = ez->OR(yy.at(0), ez->vec_ne(undef_a, undef_b)); @@ -730,11 +732,11 @@ struct SatGen  				ez->assume(ez->vec_eq(y, yy));  			} -			else if (model_undef && (cell->type == "$eq" || cell->type == "$ne")) +			else if (model_undef && cell->type.in(ID($eq), ID($ne)))  			{ -				std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); -				std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); -				std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); +				std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); +				std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); +				std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);  				extendSignalWidth(undef_a, undef_b, cell, true);  				int undef_any_a = ez->expression(ezSAT::OpOr, undef_a); @@ -756,7 +758,7 @@ struct SatGen  			else  			{  				if (model_undef) { -					std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); +					std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);  					undefGating(y, yy, undef_y);  				}  				log_assert(!model_undef || arith_undef_handled); @@ -764,15 +766,15 @@ struct SatGen  			return true;  		} -		if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" || cell->type == "$shift" || cell->type == "$shiftx") +		if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx)))  		{ -			std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep); -			std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep); -			std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep); +			std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); +			std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); +			std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);  			int extend_bit = ez->CONST_FALSE; -			if (!cell->type.in("$shift", "$shiftx") && cell->parameters["\\A_SIGNED"].as_bool()) +			if (!cell->type.in(ID($shift), ID($shiftx)) && cell->parameters[ID(A_SIGNED)].as_bool())  				extend_bit = a.back();  			while (y.size() < a.size()) @@ -783,29 +785,29 @@ struct SatGen  			std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;  			std::vector<int> shifted_a; -			if (cell->type == "$shl" || cell->type == "$sshl") +			if (cell->type.in( ID($shl), ID($sshl)))  				shifted_a = ez->vec_shift_left(a, b, false, ez->CONST_FALSE, ez->CONST_FALSE); -			if (cell->type == "$shr") +			if (cell->type == ID($shr))  				shifted_a = ez->vec_shift_right(a, b, false, ez->CONST_FALSE, ez->CONST_FALSE); -			if (cell->type == "$sshr") -				shifted_a = ez->vec_shift_right(a, b, false, cell->parameters["\\A_SIGNED"].as_bool() ? a.back() : ez->CONST_FALSE, ez->CONST_FALSE); +			if (cell->type == ID($sshr)) +				shifted_a = ez->vec_shift_right(a, b, false, cell->parameters[ID(A_SIGNED)].as_bool() ? a.back() : ez->CONST_FALSE, ez->CONST_FALSE); -			if (cell->type == "$shift" || cell->type == "$shiftx") -				shifted_a = ez->vec_shift_right(a, b, cell->parameters["\\B_SIGNED"].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE); +			if (cell->type.in(ID($shift), ID($shiftx))) +				shifted_a = ez->vec_shift_right(a, b, cell->parameters[ID(B_SIGNED)].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE);  			ez->assume(ez->vec_eq(shifted_a, yy));  			if (model_undef)  			{ -				std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); -				std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); -				std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); +				std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); +				std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); +				std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);  				std::vector<int> undef_a_shifted; -				extend_bit = cell->type == "$shiftx" ? ez->CONST_TRUE : ez->CONST_FALSE; -				if (!cell->type.in("$shift", "$shiftx") && cell->parameters["\\A_SIGNED"].as_bool()) +				extend_bit = cell->type == ID($shiftx) ? ez->CONST_TRUE : ez->CONST_FALSE; +				if (!cell->type.in(ID($shift), ID($shiftx)) && cell->parameters[ID(A_SIGNED)].as_bool())  					extend_bit = undef_a.back();  				while (undef_y.size() < undef_a.size()) @@ -813,20 +815,20 @@ struct SatGen  				while (undef_y.size() > undef_a.size())  					undef_a.push_back(extend_bit); -				if (cell->type == "$shl" || cell->type == "$sshl") +				if (cell->type.in(ID($shl), ID($sshl)))  					undef_a_shifted = ez->vec_shift_left(undef_a, b, false, ez->CONST_FALSE, ez->CONST_FALSE); -				if (cell->type == "$shr") +				if (cell->type == ID($shr))  					undef_a_shifted = ez->vec_shift_right(undef_a, b, false, ez->CONST_FALSE, ez->CONST_FALSE); -				if (cell->type == "$sshr") -					undef_a_shifted = ez->vec_shift_right(undef_a, b, false, cell->parameters["\\A_SIGNED"].as_bool() ? undef_a.back() : ez->CONST_FALSE, ez->CONST_FALSE); +				if (cell->type == ID($sshr)) +					undef_a_shifted = ez->vec_shift_right(undef_a, b, false, cell->parameters[ID(A_SIGNED)].as_bool() ? undef_a.back() : ez->CONST_FALSE, ez->CONST_FALSE); -				if (cell->type == "$shift") -					undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters["\\B_SIGNED"].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE); +				if (cell->type == ID($shift)) +					undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters[ID(B_SIGNED)].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE); -				if (cell->type == "$shiftx") -					undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters["\\B_SIGNED"].as_bool(), ez->CONST_TRUE, ez->CONST_TRUE); +				if (cell->type == ID($shiftx)) +					undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters[ID(B_SIGNED)].as_bool(), ez->CONST_TRUE, ez->CONST_TRUE);  				int undef_any_b = ez->expression(ezSAT::OpOr, undef_b);  				std::vector<int> undef_all_y_bits(undef_y.size(), undef_any_b); @@ -836,11 +838,11 @@ struct SatGen  			return true;  		} -		if (cell->type == "$mul") +		if (cell->type == ID($mul))  		{ -			std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep); -			std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep); -			std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep); +			std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); +			std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); +			std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);  			extendSignalWidth(a, b, y, cell);  			std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y; @@ -857,17 +859,17 @@ struct SatGen  			if (model_undef) {  				log_assert(arith_undef_handled); -				std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); +				std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);  				undefGating(y, yy, undef_y);  			}  			return true;  		} -		if (cell->type == "$macc") +		if (cell->type == ID($macc))  		{ -			std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep); -			std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep); -			std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep); +			std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); +			std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); +			std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);  			Macc macc;  			macc.from_cell(cell); @@ -916,13 +918,13 @@ struct SatGen  			if (model_undef)  			{ -				std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); -				std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); +				std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); +				std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);  				int undef_any_a = ez->expression(ezSAT::OpOr, undef_a);  				int undef_any_b = ez->expression(ezSAT::OpOr, undef_b); -				std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); +				std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);  				ez->assume(ez->vec_eq(undef_y, std::vector<int>(GetSize(y), ez->OR(undef_any_a, undef_any_b))));  				undefGating(y, tmp, undef_y); @@ -933,17 +935,17 @@ struct SatGen  			return true;  		} -		if (cell->type == "$div" || cell->type == "$mod") +		if (cell->type.in(ID($div), ID($mod)))  		{ -			std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep); -			std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep); -			std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep); +			std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); +			std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); +			std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);  			extendSignalWidth(a, b, y, cell);  			std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;  			std::vector<int> a_u, b_u; -			if (cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()) { +			if (cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool()) {  				a_u = ez->vec_ite(a.back(), ez->vec_neg(a), a);  				b_u = ez->vec_ite(b.back(), ez->vec_neg(b), b);  			} else { @@ -968,13 +970,13 @@ struct SatGen  			}  			std::vector<int> y_tmp = ignore_div_by_zero ? yy : ez->vec_var(y.size()); -			if (cell->type == "$div") { -				if (cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()) +			if (cell->type == ID($div)) { +				if (cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool())  					ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(ez->XOR(a.back(), b.back()), ez->vec_neg(y_u), y_u)));  				else  					ez->assume(ez->vec_eq(y_tmp, y_u));  			} else { -				if (cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()) +				if (cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool())  					ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(a.back(), ez->vec_neg(chain_buf), chain_buf)));  				else  					ez->assume(ez->vec_eq(y_tmp, chain_buf)); @@ -984,20 +986,20 @@ struct SatGen  				ez->assume(ez->expression(ezSAT::OpOr, b));  			} else {  				std::vector<int> div_zero_result; -				if (cell->type == "$div") { -					if (cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()) { +				if (cell->type == ID($div)) { +					if (cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool()) {  						std::vector<int> all_ones(y.size(), ez->CONST_TRUE);  						std::vector<int> only_first_one(y.size(), ez->CONST_FALSE);  						only_first_one.at(0) = ez->CONST_TRUE;  						div_zero_result = ez->vec_ite(a.back(), only_first_one, all_ones);  					} else { -						div_zero_result.insert(div_zero_result.end(), cell->getPort("\\A").size(), ez->CONST_TRUE); +						div_zero_result.insert(div_zero_result.end(), cell->getPort(ID::A).size(), ez->CONST_TRUE);  						div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->CONST_FALSE);  					}  				} else { -					int copy_a_bits = min(cell->getPort("\\A").size(), cell->getPort("\\B").size()); +					int copy_a_bits = min(cell->getPort(ID::A).size(), cell->getPort(ID::B).size());  					div_zero_result.insert(div_zero_result.end(), a.begin(), a.begin() + copy_a_bits); -					if (cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()) +					if (cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool())  						div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), div_zero_result.back());  					else  						div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->CONST_FALSE); @@ -1007,27 +1009,27 @@ struct SatGen  			if (model_undef) {  				log_assert(arith_undef_handled); -				std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); +				std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);  				undefGating(y, yy, undef_y);  			}  			return true;  		} -		if (cell->type == "$lut") +		if (cell->type == ID($lut))  		{ -			std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep); -			std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep); +			std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); +			std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);  			std::vector<int> lut; -			for (auto bit : cell->getParam("\\LUT").bits) -				lut.push_back(bit == RTLIL::S1 ? ez->CONST_TRUE : ez->CONST_FALSE); +			for (auto bit : cell->getParam(ID(LUT)).bits) +				lut.push_back(bit == State::S1 ? ez->CONST_TRUE : ez->CONST_FALSE);  			while (GetSize(lut) < (1 << GetSize(a)))  				lut.push_back(ez->CONST_FALSE);  			lut.resize(1 << GetSize(a));  			if (model_undef)  			{ -				std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); +				std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);  				std::vector<int> t(lut), u(GetSize(t), ez->CONST_FALSE);  				for (int i = GetSize(a)-1; i >= 0; i--) @@ -1045,7 +1047,7 @@ struct SatGen  				log_assert(GetSize(t) == 1);  				log_assert(GetSize(u) == 1);  				undefGating(y, t, u); -				ez->assume(ez->vec_eq(importUndefSigSpec(cell->getPort("\\Y"), timestep), u)); +				ez->assume(ez->vec_eq(importUndefSigSpec(cell->getPort(ID::Y), timestep), u));  			}  			else  			{ @@ -1063,15 +1065,15 @@ struct SatGen  			return true;  		} -		if (cell->type == "$sop") +		if (cell->type == ID($sop))  		{ -			std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep); -			int y = importDefSigSpec(cell->getPort("\\Y"), timestep).at(0); +			std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); +			int y = importDefSigSpec(cell->getPort(ID::Y), timestep).at(0); -			int width = cell->getParam("\\WIDTH").as_int(); -			int depth = cell->getParam("\\DEPTH").as_int(); +			int width = cell->getParam(ID(WIDTH)).as_int(); +			int depth = cell->getParam(ID(DEPTH)).as_int(); -			vector<State> table_raw = cell->getParam("\\TABLE").bits; +			vector<State> table_raw = cell->getParam(ID(TABLE)).bits;  			while (GetSize(table_raw) < 2*width*depth)  				table_raw.push_back(State::S0); @@ -1094,8 +1096,8 @@ struct SatGen  			if (model_undef)  			{  				std::vector<int> products, undef_products; -				std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); -				int undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep).at(0); +				std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); +				int undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep).at(0);  				for (int i = 0; i < depth; i++)  				{ @@ -1145,13 +1147,13 @@ struct SatGen  			return true;  		} -		if (cell->type == "$fa") +		if (cell->type == ID($fa))  		{ -			std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep); -			std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep); -			std::vector<int> c = importDefSigSpec(cell->getPort("\\C"), timestep); -			std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep); -			std::vector<int> x = importDefSigSpec(cell->getPort("\\X"), timestep); +			std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); +			std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); +			std::vector<int> c = importDefSigSpec(cell->getPort(ID(C)), timestep); +			std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); +			std::vector<int> x = importDefSigSpec(cell->getPort(ID(X)), timestep);  			std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;  			std::vector<int> xx = model_undef ? ez->vec_var(x.size()) : x; @@ -1165,12 +1167,12 @@ struct SatGen  			if (model_undef)  			{ -				std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); -				std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); -				std::vector<int> undef_c = importUndefSigSpec(cell->getPort("\\C"), timestep); +				std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); +				std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); +				std::vector<int> undef_c = importUndefSigSpec(cell->getPort(ID(C)), timestep); -				std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); -				std::vector<int> undef_x = importUndefSigSpec(cell->getPort("\\X"), timestep); +				std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); +				std::vector<int> undef_x = importUndefSigSpec(cell->getPort(ID(X)), timestep);  				ez->assume(ez->vec_eq(undef_y, ez->vec_or(ez->vec_or(undef_a, undef_b), undef_c)));  				ez->assume(ez->vec_eq(undef_x, undef_y)); @@ -1181,12 +1183,12 @@ struct SatGen  			return true;  		} -		if (cell->type == "$lcu") +		if (cell->type == ID($lcu))  		{ -			std::vector<int> p = importDefSigSpec(cell->getPort("\\P"), timestep); -			std::vector<int> g = importDefSigSpec(cell->getPort("\\G"), timestep); -			std::vector<int> ci = importDefSigSpec(cell->getPort("\\CI"), timestep); -			std::vector<int> co = importDefSigSpec(cell->getPort("\\CO"), timestep); +			std::vector<int> p = importDefSigSpec(cell->getPort(ID(P)), timestep); +			std::vector<int> g = importDefSigSpec(cell->getPort(ID(G)), timestep); +			std::vector<int> ci = importDefSigSpec(cell->getPort(ID(CI)), timestep); +			std::vector<int> co = importDefSigSpec(cell->getPort(ID(CO)), timestep);  			std::vector<int> yy = model_undef ? ez->vec_var(co.size()) : co; @@ -1195,10 +1197,10 @@ struct SatGen  			if (model_undef)  			{ -				std::vector<int> undef_p = importUndefSigSpec(cell->getPort("\\P"), timestep); -				std::vector<int> undef_g = importUndefSigSpec(cell->getPort("\\G"), timestep); -				std::vector<int> undef_ci = importUndefSigSpec(cell->getPort("\\CI"), timestep); -				std::vector<int> undef_co = importUndefSigSpec(cell->getPort("\\CO"), timestep); +				std::vector<int> undef_p = importUndefSigSpec(cell->getPort(ID(P)), timestep); +				std::vector<int> undef_g = importUndefSigSpec(cell->getPort(ID(G)), timestep); +				std::vector<int> undef_ci = importUndefSigSpec(cell->getPort(ID(CI)), timestep); +				std::vector<int> undef_co = importUndefSigSpec(cell->getPort(ID(CO)), timestep);  				int undef_any_p = ez->expression(ezSAT::OpOr, undef_p);  				int undef_any_g = ez->expression(ezSAT::OpOr, undef_g); @@ -1213,15 +1215,15 @@ struct SatGen  			return true;  		} -		if (cell->type == "$alu") +		if (cell->type == ID($alu))  		{ -			std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep); -			std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep); -			std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep); -			std::vector<int> x = importDefSigSpec(cell->getPort("\\X"), timestep); -			std::vector<int> ci = importDefSigSpec(cell->getPort("\\CI"), timestep); -			std::vector<int> bi = importDefSigSpec(cell->getPort("\\BI"), timestep); -			std::vector<int> co = importDefSigSpec(cell->getPort("\\CO"), timestep); +			std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); +			std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep); +			std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep); +			std::vector<int> x = importDefSigSpec(cell->getPort(ID(X)), timestep); +			std::vector<int> ci = importDefSigSpec(cell->getPort(ID(CI)), timestep); +			std::vector<int> bi = importDefSigSpec(cell->getPort(ID(BI)), timestep); +			std::vector<int> co = importDefSigSpec(cell->getPort(ID(CO)), timestep);  			extendSignalWidth(a, b, y, cell);  			extendSignalWidth(a, b, x, cell); @@ -1246,14 +1248,14 @@ struct SatGen  			if (model_undef)  			{ -				std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); -				std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); -				std::vector<int> undef_ci = importUndefSigSpec(cell->getPort("\\CI"), timestep); -				std::vector<int> undef_bi = importUndefSigSpec(cell->getPort("\\BI"), timestep); +				std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); +				std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep); +				std::vector<int> undef_ci = importUndefSigSpec(cell->getPort(ID(CI)), timestep); +				std::vector<int> undef_bi = importUndefSigSpec(cell->getPort(ID(BI)), timestep); -				std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); -				std::vector<int> undef_x = importUndefSigSpec(cell->getPort("\\X"), timestep); -				std::vector<int> undef_co = importUndefSigSpec(cell->getPort("\\CO"), timestep); +				std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep); +				std::vector<int> undef_x = importUndefSigSpec(cell->getPort(ID(X)), timestep); +				std::vector<int> undef_co = importUndefSigSpec(cell->getPort(ID(CO)), timestep);  				extendSignalWidth(undef_a, undef_b, undef_y, cell);  				extendSignalWidth(undef_a, undef_b, undef_x, cell); @@ -1279,19 +1281,19 @@ struct SatGen  			return true;  		} -		if (cell->type == "$slice") +		if (cell->type == ID($slice))  		{ -			RTLIL::SigSpec a = cell->getPort("\\A"); -			RTLIL::SigSpec y = cell->getPort("\\Y"); -			ez->assume(signals_eq(a.extract(cell->parameters.at("\\OFFSET").as_int(), y.size()), y, timestep)); +			RTLIL::SigSpec a = cell->getPort(ID::A); +			RTLIL::SigSpec y = cell->getPort(ID::Y); +			ez->assume(signals_eq(a.extract(cell->parameters.at(ID(OFFSET)).as_int(), y.size()), y, timestep));  			return true;  		} -		if (cell->type == "$concat") +		if (cell->type == ID($concat))  		{ -			RTLIL::SigSpec a = cell->getPort("\\A"); -			RTLIL::SigSpec b = cell->getPort("\\B"); -			RTLIL::SigSpec y = cell->getPort("\\Y"); +			RTLIL::SigSpec a = cell->getPort(ID::A); +			RTLIL::SigSpec b = cell->getPort(ID::B); +			RTLIL::SigSpec y = cell->getPort(ID::Y);  			RTLIL::SigSpec ab = a;  			ab.append(b); @@ -1300,24 +1302,24 @@ struct SatGen  			return true;  		} -		if (timestep > 0 && cell->type.in("$ff", "$dff", "$_FF_", "$_DFF_N_", "$_DFF_P_")) +		if (timestep > 0 && cell->type.in(ID($ff), ID($dff), ID($_FF_), ID($_DFF_N_), ID($_DFF_P_)))  		{  			if (timestep == 1)  			{ -				initial_state.add((*sigmap)(cell->getPort("\\Q"))); +				initial_state.add((*sigmap)(cell->getPort(ID(Q))));  			}  			else  			{ -				std::vector<int> d = importDefSigSpec(cell->getPort("\\D"), timestep-1); -				std::vector<int> q = importDefSigSpec(cell->getPort("\\Q"), timestep); +				std::vector<int> d = importDefSigSpec(cell->getPort(ID(D)), timestep-1); +				std::vector<int> q = importDefSigSpec(cell->getPort(ID(Q)), timestep);  				std::vector<int> qq = model_undef ? ez->vec_var(q.size()) : q;  				ez->assume(ez->vec_eq(d, qq));  				if (model_undef)  				{ -					std::vector<int> undef_d = importUndefSigSpec(cell->getPort("\\D"), timestep-1); -					std::vector<int> undef_q = importUndefSigSpec(cell->getPort("\\Q"), timestep); +					std::vector<int> undef_d = importUndefSigSpec(cell->getPort(ID(D)), timestep-1); +					std::vector<int> undef_q = importUndefSigSpec(cell->getPort(ID(Q)), timestep);  					ez->assume(ez->vec_eq(undef_d, undef_q));  					undefGating(q, qq, undef_q); @@ -1326,21 +1328,21 @@ struct SatGen  			return true;  		} -		if (cell->type == "$anyconst") +		if (cell->type == ID($anyconst))  		{  			if (timestep < 2)  				return true; -			std::vector<int> d = importDefSigSpec(cell->getPort("\\Y"), timestep-1); -			std::vector<int> q = importDefSigSpec(cell->getPort("\\Y"), timestep); +			std::vector<int> d = importDefSigSpec(cell->getPort(ID::Y), timestep-1); +			std::vector<int> q = importDefSigSpec(cell->getPort(ID::Y), timestep);  			std::vector<int> qq = model_undef ? ez->vec_var(q.size()) : q;  			ez->assume(ez->vec_eq(d, qq));  			if (model_undef)  			{ -				std::vector<int> undef_d = importUndefSigSpec(cell->getPort("\\Y"), timestep-1); -				std::vector<int> undef_q = importUndefSigSpec(cell->getPort("\\Y"), timestep); +				std::vector<int> undef_d = importUndefSigSpec(cell->getPort(ID::Y), timestep-1); +				std::vector<int> undef_q = importUndefSigSpec(cell->getPort(ID::Y), timestep);  				ez->assume(ez->vec_eq(undef_d, undef_q));  				undefGating(q, qq, undef_q); @@ -1348,23 +1350,23 @@ struct SatGen  			return true;  		} -		if (cell->type == "$anyseq") +		if (cell->type == ID($anyseq))  		{  			return true;  		} -		if (cell->type == "$_BUF_" || cell->type == "$equiv") +		if (cell->type.in(ID($_BUF_), ID($equiv)))  		{ -			std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep); -			std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep); +			std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep); +			std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);  			extendSignalWidthUnary(a, y, cell);  			std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;  			ez->assume(ez->vec_eq(a, yy));  			if (model_undef) { -				std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); -				std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); +				std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep); +				std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);  				extendSignalWidthUnary(undef_a, undef_y, cell, false);  				ez->assume(ez->vec_eq(undef_a, undef_y));  				undefGating(y, yy, undef_y); @@ -1372,18 +1374,18 @@ struct SatGen  			return true;  		} -		if (cell->type == "$initstate") +		if (cell->type == ID($initstate))  		{  			auto key = make_pair(prefix, timestep);  			if (initstates.count(key) == 0)  				initstates[key] = false; -			std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep); +			std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);  			log_assert(GetSize(y) == 1);  			ez->SET(y[0], initstates[key] ? ez->CONST_TRUE : ez->CONST_FALSE);  			if (model_undef) { -				std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); +				std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);  				log_assert(GetSize(undef_y) == 1);  				ez->SET(undef_y[0], ez->CONST_FALSE);  			} @@ -1391,19 +1393,19 @@ struct SatGen  			return true;  		} -		if (cell->type == "$assert") +		if (cell->type == ID($assert))  		{  			std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); -			asserts_a[pf].append((*sigmap)(cell->getPort("\\A"))); -			asserts_en[pf].append((*sigmap)(cell->getPort("\\EN"))); +			asserts_a[pf].append((*sigmap)(cell->getPort(ID::A))); +			asserts_en[pf].append((*sigmap)(cell->getPort(ID(EN))));  			return true;  		} -		if (cell->type == "$assume") +		if (cell->type == ID($assume))  		{  			std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep)); -			assumes_a[pf].append((*sigmap)(cell->getPort("\\A"))); -			assumes_en[pf].append((*sigmap)(cell->getPort("\\EN"))); +			assumes_a[pf].append((*sigmap)(cell->getPort(ID::A))); +			assumes_en[pf].append((*sigmap)(cell->getPort(ID(EN))));  			return true;  		} diff --git a/kernel/yosys.cc b/kernel/yosys.cc index a42a7c0b8..747f2d739 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -510,10 +510,13 @@ void yosys_setup()  	if(already_setup)  		return;  	already_setup = true; -	// if there are already IdString objects then we have a global initialization order bug -	IdString empty_id; -	log_assert(empty_id.index_ == 0); -	IdString::get_reference(empty_id.index_); + +	RTLIL::ID::A = "\\A"; +	RTLIL::ID::B = "\\B"; +	RTLIL::ID::Y = "\\Y"; +	RTLIL::ID::keep = "\\keep"; +	RTLIL::ID::whitebox = "\\whitebox"; +	RTLIL::ID::blackbox = "\\blackbox";  	#ifdef WITH_PYTHON  		PyImport_AppendInittab((char*)"libyosys", INIT_MODULE); @@ -575,9 +578,6 @@ void yosys_shutdown()  #ifdef WITH_PYTHON  	Py_Finalize();  #endif - -	IdString empty_id; -	IdString::put_reference(empty_id.index_);  }  RTLIL::IdString new_id(std::string file, int line, std::string func) @@ -647,12 +647,12 @@ std::vector<std::string> glob_filename(const std::string &filename_pattern)  void rewrite_filename(std::string &filename)  { -	if (filename.substr(0, 1) == "\"" && filename.substr(GetSize(filename)-1) == "\"") +	if (filename.compare(0, 1, "\"") == 0 && filename.compare(GetSize(filename)-1, std::string::npos, "\"") == 0)  		filename = filename.substr(1, GetSize(filename)-2); -	if (filename.substr(0, 2) == "+/") +	if (filename.compare(0, 2, "+/") == 0)  		filename = proc_share_dirname() + filename.substr(2);  #ifndef _WIN32 -	if (filename.substr(0, 2) == "~/") +	if (filename.compare(0, 2, "~/") == 0)  		filename = filename.replace(0, 1, getenv("HOME"));  #endif  } @@ -894,23 +894,26 @@ void run_frontend(std::string filename, std::string command, std::string *backen  		design = yosys_design;  	if (command == "auto") { -		if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v") +		std::string filename_trim = filename; +		if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".gz") == 0) +			filename_trim.erase(filename_trim.size()-3); +		if (filename_trim.size() > 2 && filename_trim.compare(filename_trim.size()-2, std::string::npos, ".v") == 0)  			command = "verilog"; -		else if (filename.size() > 2 && filename.substr(filename.size()-3) == ".sv") +		else if (filename_trim.size() > 2 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".sv") == 0)  			command = "verilog -sv"; -		else if (filename.size() > 3 && filename.substr(filename.size()-4) == ".vhd") +		else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-4, std::string::npos, ".vhd") == 0)  			command = "vhdl"; -		else if (filename.size() > 4 && filename.substr(filename.size()-5) == ".blif") +		else if (filename_trim.size() > 4 && filename_trim.compare(filename_trim.size()-5, std::string::npos, ".blif") == 0)  			command = "blif"; -		else if (filename.size() > 5 && filename.substr(filename.size()-6) == ".eblif") +		else if (filename_trim.size() > 5 && filename_trim.compare(filename_trim.size()-6, std::string::npos, ".eblif") == 0)  			command = "blif"; -		else if (filename.size() > 4 && filename.substr(filename.size()-5) == ".json") +		else if (filename_trim.size() > 4 && filename_trim.compare(filename_trim.size()-5, std::string::npos, ".json") == 0)  			command = "json"; -		else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") +		else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".il") == 0)  			command = "ilang"; -		else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".ys") +		else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".ys") == 0)  			command = "script"; -		else if (filename.size() > 3 && filename.substr(filename.size()-4) == ".tcl") +		else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-4, std::string::npos, ".tcl") == 0)  			command = "tcl";  		else if (filename == "-")  			command = "script"; @@ -961,14 +964,18 @@ void run_frontend(std::string filename, std::string command, std::string *backen  					command += next_line;  				}  				handle_label(command, from_to_active, run_from, run_to); -				if (from_to_active) +				if (from_to_active) {  					Pass::call(design, command); +					design->check(); +				}  			}  			if (!command.empty()) {  				handle_label(command, from_to_active, run_from, run_to); -				if (from_to_active) +				if (from_to_active) {  					Pass::call(design, command); +					design->check(); +				}  			}  		}  		catch (...) { @@ -997,6 +1004,7 @@ void run_frontend(std::string filename, std::string command, std::string *backen  		Pass::call(design, vector<string>({command, filename}));  	else  		Frontend::frontend_call(design, NULL, filename, command); +	design->check();  }  void run_frontend(std::string filename, std::string command, RTLIL::Design *design) @@ -1020,17 +1028,17 @@ void run_backend(std::string filename, std::string command, RTLIL::Design *desig  		design = yosys_design;  	if (command == "auto") { -		if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v") +		if (filename.size() > 2 && filename.compare(filename.size()-2, std::string::npos, ".v") == 0)  			command = "verilog"; -		else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") +		else if (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0)  			command = "ilang"; -		else if (filename.size() > 4 && filename.substr(filename.size()-4) == ".aig") +		else if (filename.size() > 4 && filename.compare(filename.size()-4, std::string::npos, ".aig") == 0)  			command = "aiger"; -		else if (filename.size() > 5 && filename.substr(filename.size()-5) == ".blif") +		else if (filename.size() > 5 && filename.compare(filename.size()-5, std::string::npos, ".blif") == 0)  			command = "blif"; -		else if (filename.size() > 5 && filename.substr(filename.size()-5) == ".edif") +		else if (filename.size() > 5 && filename.compare(filename.size()-5, std::string::npos, ".edif") == 0)  			command = "edif"; -		else if (filename.size() > 5 && filename.substr(filename.size()-5) == ".json") +		else if (filename.size() > 5 && filename.compare(filename.size()-5, std::string::npos, ".json") == 0)  			command = "json";  		else if (filename == "-")  			command = "ilang"; @@ -1064,7 +1072,7 @@ static char *readline_cmd_generator(const char *text, int state)  	}  	for (; it != pass_register.end(); it++) { -		if (it->first.substr(0, len) == text) +		if (it->first.compare(0, len, text) == 0)  			return strdup((it++)->first.c_str());  	}  	return NULL; @@ -1086,7 +1094,7 @@ static char *readline_obj_generator(const char *text, int state)  		if (design->selected_active_module.empty())  		{  			for (auto &it : design->modules_) -				if (RTLIL::unescape_id(it.first).substr(0, len) == text) +				if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)  					obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));  		}  		else @@ -1095,19 +1103,19 @@ static char *readline_obj_generator(const char *text, int state)  			RTLIL::Module *module = design->modules_.at(design->selected_active_module);  			for (auto &it : module->wires_) -				if (RTLIL::unescape_id(it.first).substr(0, len) == text) +				if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)  					obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));  			for (auto &it : module->memories) -				if (RTLIL::unescape_id(it.first).substr(0, len) == text) +				if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)  					obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));  			for (auto &it : module->cells_) -				if (RTLIL::unescape_id(it.first).substr(0, len) == text) +				if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)  					obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));  			for (auto &it : module->processes) -				if (RTLIL::unescape_id(it.first).substr(0, len) == text) +				if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)  					obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));  		} @@ -1180,6 +1188,7 @@ void shell(RTLIL::Design *design)  				design->selection_stack.pop_back();  			log_reset_stack();  		} +		design->check();  	}  	if (command == NULL)  		printf("exit\n"); diff --git a/kernel/yosys.h b/kernel/yosys.h index c7b671724..a80cb00b4 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -52,6 +52,7 @@  #include <stdexcept>  #include <memory>  #include <cmath> +#include <cstddef>  #include <sstream>  #include <fstream> @@ -87,6 +88,10 @@ extern int Tcl_EvalFile(Tcl_Interp *interp, const char *fileName);  extern void Tcl_Finalize(void);  extern int Tcl_GetCommandInfo(Tcl_Interp *interp, const char *cmdName, Tcl_CmdInfo *infoPtr);  extern const char *Tcl_GetStringResult(Tcl_Interp *interp); +extern Tcl_Obj *Tcl_NewStringObj(const char *bytes, int length); +extern Tcl_Obj *Tcl_NewIntObj(int intValue); +extern Tcl_Obj *Tcl_NewListObj(int objc, Tcl_Obj *const objv[]); +extern Tcl_Obj *Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags);  #  endif  #endif @@ -300,8 +305,17 @@ RTLIL::IdString new_id(std::string file, int line, std::string func);  #define NEW_ID \  	YOSYS_NAMESPACE_PREFIX new_id(__FILE__, __LINE__, __FUNCTION__) -#define ID(_str) \ -	([]() { static YOSYS_NAMESPACE_PREFIX RTLIL::IdString _id(_str); return _id; })() +// Create a statically allocated IdString object, using for example ID(A) or ID($add). +// +// Recipe for Converting old code that is using conversion of strings like "\\A" and +// "$add" for creating IdStrings: Run below SED command on the .cc file and then use for +// example "meld foo.cc foo.cc.orig" to manually compile errors, if necessary. +// +//  sed -i.orig -r 's/"\\\\([a-zA-Z0-9_]+)"/ID(\1)/g; s/"(\$[a-zA-Z0-9_]+)"/ID(\1)/g;' <filename> +// +#define ID(_id) ([]() { const char *p = "\\" #_id, *q = p[1] == '$' ? p+1 : p; \ +        static const YOSYS_NAMESPACE_PREFIX RTLIL::IdString id(q); return id; })() +namespace ID = RTLIL::ID;  RTLIL::Design *yosys_get_design();  std::string proc_self_dirname(); | 
