mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-30 19:22:31 +00:00 
			
		
		
		
	Merge branch 'master' into clifford/fix1255
This commit is contained in:
		
						commit
						49301b733e
					
				
					 28 changed files with 2506 additions and 2324 deletions
				
			
		|  | @ -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,183 +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_")) | ||||
| 	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("\\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); | ||||
| 		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); | ||||
| 			if (cell->type == "$_NMUX_") | ||||
| 			if (cell->type == ID($_NMUX_)) | ||||
| 				Y = mk.not_gate(Y); | ||||
| 			mk.outport(Y, "\\Y", i); | ||||
| 			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; | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; | ||||
| 	} | ||||
|  |  | |||
|  | @ -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"; | ||||
| 		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("$tribuf", {A, EN}, {Y}, true); | ||||
| 		setup_type(ID($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); | ||||
| 		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,27 +131,27 @@ 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 = "\\SET", CLR = "\\CLR", CLK = "\\CLK", ARST = "\\ARST", EN = "\\EN"; | ||||
| 		IdString Q = "\\Q", D = "\\D"; | ||||
| 		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("$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(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}); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
|  | @ -159,63 +159,63 @@ struct CellTypes | |||
| 	{ | ||||
| 		setup_internals_ff(); | ||||
| 
 | ||||
| 		IdString CLK = "\\CLK", ARST = "\\ARST", EN = "\\EN"; | ||||
| 		IdString 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"; | ||||
| 		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("$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(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("$fsm", {CLK, ARST, CTRL_IN}, {CTRL_OUT}); | ||||
| 		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"; | ||||
| 		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("$_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("$_NMUX_", {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); | ||||
| 		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'}; | ||||
| 
 | ||||
|  | @ -223,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}); | ||||
|  | @ -289,13 +289,13 @@ struct CellTypes | |||
| 
 | ||||
| 	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; | ||||
| 		} | ||||
|  | @ -338,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) { | ||||
|  | @ -369,25 +369,25 @@ 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(State::S0); | ||||
| 			t.resize(1 << width); | ||||
|  | @ -409,11 +409,11 @@ 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(State::S0); | ||||
|  | @ -447,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) { | ||||
|  | @ -465,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); | ||||
|  | @ -476,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); | ||||
|  |  | |||
|  | @ -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; | ||||
|  | @ -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.in("$mux", "$pmux", "$_MUX_", "$_NMUX_")) | ||||
| 		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,7 @@ struct ConstEval | |||
| 			for (auto &yc : y_candidates) { | ||||
| 				if (!eval(yc, undef, cell)) | ||||
| 					return false; | ||||
| 				if (cell->type == "$_NMUX_") | ||||
| 				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()); | ||||
|  | @ -198,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)) | ||||
|  | @ -227,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; | ||||
|  | @ -247,8 +247,8 @@ 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); | ||||
|  | @ -283,7 +283,7 @@ struct ConstEval | |||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		else if (cell->type == "$macc") | ||||
| 		else if (cell->type == ID($macc)) | ||||
| 		{ | ||||
| 			Macc macc; | ||||
| 			macc.from_cell(cell); | ||||
|  | @ -298,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)) | ||||
|  |  | |||
|  | @ -28,44 +28,44 @@ struct CellCosts | |||
| { | ||||
| 	static const dict<RTLIL::IdString, int>& default_gate_cost() { | ||||
| 		static const dict<RTLIL::IdString, int> db = { | ||||
| 			{ "$_BUF_",    1 }, | ||||
| 			{ "$_NOT_",    2 }, | ||||
| 			{ "$_AND_",    4 }, | ||||
| 			{ "$_NAND_",   4 }, | ||||
| 			{ "$_OR_",     4 }, | ||||
| 			{ "$_NOR_",    4 }, | ||||
| 			{ "$_ANDNOT_", 4 }, | ||||
| 			{ "$_ORNOT_",  4 }, | ||||
| 			{ "$_XOR_",    5 }, | ||||
| 			{ "$_XNOR_",   5 }, | ||||
| 			{ "$_AOI3_",   6 }, | ||||
| 			{ "$_OAI3_",   6 }, | ||||
| 			{ "$_AOI4_",   7 }, | ||||
| 			{ "$_OAI4_",   7 }, | ||||
| 			{ "$_MUX_",    4 }, | ||||
| 			{ "$_NMUX_",   4 } | ||||
| 			{ 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 = { | ||||
| 			{ "$_BUF_",     1 }, | ||||
| 			{ "$_NOT_",     2 }, | ||||
| 			{ "$_AND_",     6 }, | ||||
| 			{ "$_NAND_",    4 }, | ||||
| 			{ "$_OR_",      6 }, | ||||
| 			{ "$_NOR_",     4 }, | ||||
| 			{ "$_ANDNOT_",  6 }, | ||||
| 			{ "$_ORNOT_",   6 }, | ||||
| 			{ "$_XOR_",    12 }, | ||||
| 			{ "$_XNOR_",   12 }, | ||||
| 			{ "$_AOI3_",    6 }, | ||||
| 			{ "$_OAI3_",    6 }, | ||||
| 			{ "$_AOI4_",    8 }, | ||||
| 			{ "$_OAI4_",    8 }, | ||||
| 			{ "$_MUX_",    12 }, | ||||
| 			{ "$_NMUX_",   10 } | ||||
| 			{ 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; | ||||
| 	} | ||||
|  | @ -92,8 +92,8 @@ struct CellCosts | |||
| 		{ | ||||
| 			RTLIL::Module *mod = design->module(cell->type); | ||||
| 
 | ||||
| 			if (mod->attributes.count("\\cost")) | ||||
| 				return mod->attributes.at("\\cost").as_int(); | ||||
| 			if (mod->attributes.count(ID(cost))) | ||||
| 				return mod->attributes.at(ID(cost)).as_int(); | ||||
| 
 | ||||
| 			if (mod_cost_cache.count(mod->name)) | ||||
| 				return mod_cost_cache.at(mod->name); | ||||
|  |  | |||
|  | @ -99,16 +99,16 @@ 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 | ||||
| 
 | ||||
|  | @ -191,12 +191,12 @@ struct Macc | |||
| 			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 | ||||
|  |  | |||
							
								
								
									
										1151
									
								
								kernel/rtlil.cc
									
										
									
									
									
								
							
							
						
						
									
										1151
									
								
								kernel/rtlil.cc
									
										
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										127
									
								
								kernel/rtlil.h
									
										
									
									
									
								
							
							
						
						
									
										127
									
								
								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)++; | ||||
| 		#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 (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)); | ||||
| 		#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.
 | ||||
| 
 | ||||
|  | @ -332,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; | ||||
|  | @ -604,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); | ||||
|  | @ -1339,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); | ||||
|  |  | |||
							
								
								
									
										520
									
								
								kernel/satgen.h
									
										
									
									
									
								
							
							
						
						
									
										520
									
								
								kernel/satgen.h
									
										
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -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) | ||||
|  |  | |||
|  | @ -305,8 +305,16 @@ 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; })() | ||||
| 
 | ||||
| RTLIL::Design *yosys_get_design(); | ||||
| std::string proc_self_dirname(); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue