mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	Remove sequential extension
This commit is contained in:
		
							parent
							
								
									bbab608691
								
							
						
					
					
						commit
						091bf4a18b
					
				
					 9 changed files with 68 additions and 730 deletions
				
			
		|  | @ -76,32 +76,25 @@ void aiger_encode(std::ostream &f, int x) | ||||||
| struct XAigerWriter | struct XAigerWriter | ||||||
| { | { | ||||||
| 	Module *module; | 	Module *module; | ||||||
| 	bool zinit_mode; |  | ||||||
| 	SigMap sigmap; | 	SigMap sigmap; | ||||||
| 
 | 
 | ||||||
| 	dict<SigBit, bool> init_map; |  | ||||||
| 	pool<SigBit> input_bits, output_bits; | 	pool<SigBit> input_bits, output_bits; | ||||||
| 	dict<SigBit, SigBit> not_map, ff_map, alias_map; | 	dict<SigBit, SigBit> not_map, alias_map; | ||||||
| 	dict<SigBit, pair<SigBit, SigBit>> and_map; | 	dict<SigBit, pair<SigBit, SigBit>> and_map; | ||||||
| 	vector<std::tuple<SigBit,RTLIL::Cell*,RTLIL::IdString,int>> ci_bits; | 	vector<std::tuple<SigBit,RTLIL::Cell*,RTLIL::IdString,int>> ci_bits; | ||||||
| 	vector<std::tuple<SigBit,RTLIL::Cell*,RTLIL::IdString,int,int>> co_bits; | 	vector<std::tuple<SigBit,RTLIL::Cell*,RTLIL::IdString,int,int>> co_bits; | ||||||
| 	vector<SigBit> ff_bits; |  | ||||||
| 	dict<SigBit, float> arrival_times; | 	dict<SigBit, float> arrival_times; | ||||||
| 
 | 
 | ||||||
| 	vector<pair<int, int>> aig_gates; | 	vector<pair<int, int>> aig_gates; | ||||||
| 	vector<int> aig_latchin, aig_latchinit, aig_outputs; | 	vector<int> aig_outputs; | ||||||
| 	int aig_m = 0, aig_i = 0, aig_l = 0, aig_o = 0, aig_a = 0; | 	int aig_m = 0, aig_i = 0, aig_l = 0, aig_o = 0, aig_a = 0; | ||||||
| 
 | 
 | ||||||
| 	dict<SigBit, int> aig_map; | 	dict<SigBit, int> aig_map; | ||||||
| 	dict<SigBit, int> ordered_outputs; | 	dict<SigBit, int> ordered_outputs; | ||||||
| 	dict<SigBit, int> ordered_latches; |  | ||||||
| 
 | 
 | ||||||
| 	vector<Cell*> box_list; | 	vector<Cell*> box_list; | ||||||
| 	bool omode = false; | 	bool omode = false; | ||||||
| 
 | 
 | ||||||
| 	//dict<SigBit, int> init_inputs;
 |  | ||||||
| 	//int initstate_ff = 0;
 |  | ||||||
| 
 |  | ||||||
| 	int mkgate(int a0, int a1) | 	int mkgate(int a0, int a1) | ||||||
| 	{ | 	{ | ||||||
| 		aig_m++, aig_a++; | 		aig_m++, aig_a++; | ||||||
|  | @ -144,7 +137,7 @@ struct XAigerWriter | ||||||
| 		return a; | 		return a; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	XAigerWriter(Module *module, bool zinit_mode, bool holes_mode=false) : module(module), zinit_mode(zinit_mode), sigmap(module) | 	XAigerWriter(Module *module, bool holes_mode=false) : module(module), sigmap(module) | ||||||
| 	{ | 	{ | ||||||
| 		pool<SigBit> undriven_bits; | 		pool<SigBit> undriven_bits; | ||||||
| 		pool<SigBit> unused_bits; | 		pool<SigBit> unused_bits; | ||||||
|  | @ -167,14 +160,6 @@ struct XAigerWriter | ||||||
| 
 | 
 | ||||||
| 		for (auto wire : module->wires()) | 		for (auto wire : module->wires()) | ||||||
| 		{ | 		{ | ||||||
| 			if (wire->attributes.count("\\init")) { |  | ||||||
| 				SigSpec initsig = sigmap(wire); |  | ||||||
| 				Const initval = wire->attributes.at("\\init"); |  | ||||||
| 				for (int i = 0; i < GetSize(wire) && i < GetSize(initval); i++) |  | ||||||
| 					if (initval[i] == State::S0 || initval[i] == State::S1) |  | ||||||
| 						init_map[initsig[i]] = initval[i] == State::S1; |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			bool keep = wire->attributes.count("\\keep"); | 			bool keep = wire->attributes.count("\\keep"); | ||||||
| 
 | 
 | ||||||
| 			for (int i = 0; i < GetSize(wire); i++) | 			for (int i = 0; i < GetSize(wire); i++) | ||||||
|  | @ -218,12 +203,6 @@ struct XAigerWriter | ||||||
| 		//       box ordering, but not individual AIG cells
 | 		//       box ordering, but not individual AIG cells
 | ||||||
| 		dict<SigBit, pool<IdString>> bit_drivers, bit_users; | 		dict<SigBit, pool<IdString>> bit_drivers, bit_users; | ||||||
| 		TopoSort<IdString, RTLIL::sort_by_id_str> toposort; | 		TopoSort<IdString, RTLIL::sort_by_id_str> toposort; | ||||||
| 		struct flop_data_t { |  | ||||||
| 			IdString d_port; |  | ||||||
| 			IdString q_port; |  | ||||||
| 			int q_arrival; |  | ||||||
| 		}; |  | ||||||
| 		dict<IdString, flop_data_t> flop_data; |  | ||||||
| 		bool abc_box_seen = false; | 		bool abc_box_seen = false; | ||||||
| 
 | 
 | ||||||
| 		for (auto cell : module->selected_cells()) { | 		for (auto cell : module->selected_cells()) { | ||||||
|  | @ -262,86 +241,25 @@ struct XAigerWriter | ||||||
| 
 | 
 | ||||||
| 			log_assert(!holes_mode); | 			log_assert(!holes_mode); | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$__ABC_FF_") |  | ||||||
| 			{ |  | ||||||
| 				SigBit D = sigmap(cell->getPort("\\D").as_bit()); |  | ||||||
| 				SigBit Q = sigmap(cell->getPort("\\Q").as_bit()); |  | ||||||
| 				unused_bits.erase(D); |  | ||||||
| 				undriven_bits.erase(Q); |  | ||||||
| 				alias_map[Q] = D; |  | ||||||
| 				continue; |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			RTLIL::Module* inst_module = module->design->module(cell->type); | 			RTLIL::Module* inst_module = module->design->module(cell->type); | ||||||
| 			if (inst_module && inst_module->attributes.count("\\abc_box_id")) { | 			if (inst_module && inst_module->attributes.count("\\abc_box_id")) { | ||||||
| 				abc_box_seen = true; | 				abc_box_seen = true; | ||||||
| 
 | 
 | ||||||
| 				toposort.node(cell->name); | 				if (!holes_mode) { | ||||||
| 
 | 					toposort.node(cell->name); | ||||||
| 				auto r = flop_data.insert(std::make_pair(cell->type, flop_data_t{IdString(), IdString(), 0})); | 					for (const auto &conn : cell->connections()) { | ||||||
| 				if (r.second && inst_module->attributes.count("\\abc_flop")) { | 						auto port_wire = inst_module->wire(conn.first); | ||||||
| 					IdString &abc_flop_d = r.first->second.d_port; | 						if (port_wire->port_input) { | ||||||
| 					IdString &abc_flop_q = r.first->second.q_port; | 							// Ignore inout for the sake of topographical ordering
 | ||||||
| 					for (auto port_name : inst_module->ports) { | 							if (port_wire->port_output) continue; | ||||||
| 						auto wire = inst_module->wire(port_name); | 							for (auto bit : sigmap(conn.second)) | ||||||
| 						log_assert(wire); | 								bit_users[bit].insert(cell->name); | ||||||
| 						if (wire->attributes.count("\\abc_flop_d")) { |  | ||||||
| 							if (abc_flop_d != IdString()) |  | ||||||
| 								log_error("More than one port has the 'abc_flop_d' attribute set on module '%s'.\n", log_id(cell->type)); |  | ||||||
| 							abc_flop_d = port_name; |  | ||||||
| 						} | 						} | ||||||
| 						if (wire->attributes.count("\\abc_flop_q")) { |  | ||||||
| 							if (abc_flop_q != IdString()) |  | ||||||
| 								log_error("More than one port has the 'abc_flop_q' attribute set on module '%s'.\n", log_id(cell->type)); |  | ||||||
| 							abc_flop_q = port_name; |  | ||||||
| 
 | 
 | ||||||
| 							auto it = wire->attributes.find("\\abc_arrival"); | 						if (port_wire->port_output) | ||||||
| 							if (it != wire->attributes.end()) { | 							for (auto bit : sigmap(conn.second)) | ||||||
| 								if (it->second.flags != 0) | 								bit_drivers[bit].insert(cell->name); | ||||||
| 									log_error("Attribute 'abc_arrival' on port '%s' of module '%s' is not an integer.\n", log_id(wire), log_id(cell->type)); |  | ||||||
| 								 r.first->second.q_arrival = it->second.as_int(); |  | ||||||
| 							} |  | ||||||
| 						} |  | ||||||
| 					} | 					} | ||||||
| 					if (abc_flop_d == IdString()) |  | ||||||
| 						log_error("'abc_flop_d' attribute not found on any ports on module '%s'.\n", log_id(cell->type)); |  | ||||||
| 					if (abc_flop_q == IdString()) |  | ||||||
| 						log_error("'abc_flop_q' attribute not found on any ports on module '%s'.\n", log_id(cell->type)); |  | ||||||
| 				} |  | ||||||
| 
 |  | ||||||
| 				auto abc_flop_d = r.first->second.d_port; |  | ||||||
| 				if (abc_flop_d != IdString()) { |  | ||||||
| 					SigBit d = cell->getPort(abc_flop_d); |  | ||||||
| 					SigBit I = sigmap(d); |  | ||||||
| 					if (I != d) |  | ||||||
| 						alias_map[I] = d; |  | ||||||
| 					unused_bits.erase(d); |  | ||||||
| 
 |  | ||||||
| 					auto abc_flop_q = r.first->second.q_port; |  | ||||||
| 					SigBit q = cell->getPort(abc_flop_q); |  | ||||||
| 					SigBit O = sigmap(q); |  | ||||||
| 					if (O != q) |  | ||||||
| 						alias_map[O] = q; |  | ||||||
| 					undriven_bits.erase(O); |  | ||||||
| 					ff_bits.emplace_back(q); |  | ||||||
| 
 |  | ||||||
| 					auto arrival = r.first->second.q_arrival; |  | ||||||
| 					if (arrival) |  | ||||||
| 						arrival_times[q] = arrival; |  | ||||||
| 				} |  | ||||||
| 
 |  | ||||||
| 				for (const auto &conn : cell->connections()) { |  | ||||||
| 					auto port_wire = inst_module->wire(conn.first); |  | ||||||
| 					if (port_wire->port_input) { |  | ||||||
| 						// Ignore inout for the sake of topographical ordering
 |  | ||||||
| 						if (port_wire->port_output) continue; |  | ||||||
| 						for (auto bit : sigmap(conn.second)) |  | ||||||
| 							bit_users[bit].insert(cell->name); |  | ||||||
| 					} |  | ||||||
| 
 |  | ||||||
| 					if (port_wire->port_output) |  | ||||||
| 						for (auto bit : sigmap(conn.second)) |  | ||||||
| 							bit_drivers[bit].insert(cell->name); |  | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			else { | 			else { | ||||||
|  | @ -548,7 +466,6 @@ struct XAigerWriter | ||||||
| 			log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), log_id(module)); | 			log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), log_id(module)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		init_map.sort(); |  | ||||||
| 		if (holes_mode) { | 		if (holes_mode) { | ||||||
| 			struct sort_by_port_id { | 			struct sort_by_port_id { | ||||||
| 				bool operator()(const RTLIL::SigBit& a, const RTLIL::SigBit& b) const { | 				bool operator()(const RTLIL::SigBit& a, const RTLIL::SigBit& b) const { | ||||||
|  | @ -564,7 +481,6 @@ struct XAigerWriter | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		not_map.sort(); | 		not_map.sort(); | ||||||
| 		ff_map.sort(); |  | ||||||
| 		and_map.sort(); | 		and_map.sort(); | ||||||
| 
 | 
 | ||||||
| 		aig_map[State::S0] = 0; | 		aig_map[State::S0] = 0; | ||||||
|  | @ -576,77 +492,12 @@ struct XAigerWriter | ||||||
| 			aig_map[bit] = 2*aig_m; | 			aig_map[bit] = 2*aig_m; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for (auto bit : ff_bits) { |  | ||||||
| 			aig_m++, aig_i++; |  | ||||||
| 			log_assert(!aig_map.count(bit)); |  | ||||||
| 			aig_map[bit] = 2*aig_m; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		dict<SigBit, int> ff_aig_map; |  | ||||||
| 		for (auto &c : ci_bits) { | 		for (auto &c : ci_bits) { | ||||||
| 			RTLIL::SigBit bit = std::get<0>(c); | 			RTLIL::SigBit bit = std::get<0>(c); | ||||||
| 			aig_m++, aig_i++; | 			aig_m++, aig_i++; | ||||||
| 			auto r = aig_map.insert(std::make_pair(bit, 2*aig_m)); | 			aig_map[bit] = 2*aig_m; | ||||||
| 			if (!r.second) |  | ||||||
| 				ff_aig_map[bit] = 2*aig_m; |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		//if (zinit_mode)
 |  | ||||||
| 		//{
 |  | ||||||
| 		//	for (auto it : ff_map) {
 |  | ||||||
| 		//		if (init_map.count(it.first))
 |  | ||||||
| 		//			continue;
 |  | ||||||
| 		//		aig_m++, aig_i++;
 |  | ||||||
| 		//		init_inputs[it.first] = 2*aig_m;
 |  | ||||||
| 		//	}
 |  | ||||||
| 		//}
 |  | ||||||
| 
 |  | ||||||
| 		//for (auto it : ff_map) {
 |  | ||||||
| 		//	aig_m++, aig_l++;
 |  | ||||||
| 		//	aig_map[it.first] = 2*aig_m;
 |  | ||||||
| 		//	ordered_latches[it.first] = aig_l-1;
 |  | ||||||
| 		//	if (init_map.count(it.first) == 0)
 |  | ||||||
| 		//		aig_latchinit.push_back(2);
 |  | ||||||
| 		//	else
 |  | ||||||
| 		//		aig_latchinit.push_back(init_map.at(it.first) ? 1 : 0);
 |  | ||||||
| 		//}
 |  | ||||||
| 
 |  | ||||||
| 		//if (!init_inputs.empty()) {
 |  | ||||||
| 		//	aig_m++, aig_l++;
 |  | ||||||
| 		//	initstate_ff = 2*aig_m+1;
 |  | ||||||
| 		//	aig_latchinit.push_back(0);
 |  | ||||||
| 		//}
 |  | ||||||
| 
 |  | ||||||
| 		//if (zinit_mode)
 |  | ||||||
| 		//{
 |  | ||||||
| 		//	for (auto it : ff_map)
 |  | ||||||
| 		//	{
 |  | ||||||
| 		//		int l = ordered_latches[it.first];
 |  | ||||||
| 
 |  | ||||||
| 		//		if (aig_latchinit.at(l) == 1)
 |  | ||||||
| 		//			aig_map[it.first] ^= 1;
 |  | ||||||
| 
 |  | ||||||
| 		//		if (aig_latchinit.at(l) == 2)
 |  | ||||||
| 		//		{
 |  | ||||||
| 		//			int gated_ffout = mkgate(aig_map[it.first], initstate_ff^1);
 |  | ||||||
| 		//			int gated_initin = mkgate(init_inputs[it.first], initstate_ff);
 |  | ||||||
| 		//			aig_map[it.first] = mkgate(gated_ffout^1, gated_initin^1)^1;
 |  | ||||||
| 		//		}
 |  | ||||||
| 		//	}
 |  | ||||||
| 		//}
 |  | ||||||
| 
 |  | ||||||
| 		//for (auto it : ff_map) {
 |  | ||||||
| 		//	int a = bit2aig(it.second);
 |  | ||||||
| 		//	int l = ordered_latches[it.first];
 |  | ||||||
| 		//	if (zinit_mode && aig_latchinit.at(l) == 1)
 |  | ||||||
| 		//		aig_latchin.push_back(a ^ 1);
 |  | ||||||
| 		//	else
 |  | ||||||
| 		//		aig_latchin.push_back(a);
 |  | ||||||
| 		//}
 |  | ||||||
| 
 |  | ||||||
| 		//if (!init_inputs.empty())
 |  | ||||||
| 		//	aig_latchin.push_back(1);
 |  | ||||||
| 
 |  | ||||||
| 		for (auto &c : co_bits) { | 		for (auto &c : co_bits) { | ||||||
| 			RTLIL::SigBit bit = std::get<0>(c); | 			RTLIL::SigBit bit = std::get<0>(c); | ||||||
| 			std::get<4>(c) = ordered_outputs[bit] = aig_o++; | 			std::get<4>(c) = ordered_outputs[bit] = aig_o++; | ||||||
|  | @ -658,11 +509,6 @@ struct XAigerWriter | ||||||
| 			aig_outputs.push_back(bit2aig(bit)); | 			aig_outputs.push_back(bit2aig(bit)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for (auto bit : ff_bits) { |  | ||||||
| 			aig_o++; |  | ||||||
| 			aig_outputs.push_back(ff_aig_map.at(bit)); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (output_bits.empty()) { | 		if (output_bits.empty()) { | ||||||
| 			aig_o++; | 			aig_o++; | ||||||
| 			aig_outputs.push_back(0); | 			aig_outputs.push_back(0); | ||||||
|  | @ -677,8 +523,6 @@ struct XAigerWriter | ||||||
| 		int aig_obcjf = aig_obcj; | 		int aig_obcjf = aig_obcj; | ||||||
| 
 | 
 | ||||||
| 		log_assert(aig_m == aig_i + aig_l + aig_a); | 		log_assert(aig_m == aig_i + aig_l + aig_a); | ||||||
| 		log_assert(aig_l == GetSize(aig_latchin)); |  | ||||||
| 		log_assert(aig_l == GetSize(aig_latchinit)); |  | ||||||
| 		log_assert(aig_obcjf == GetSize(aig_outputs)); | 		log_assert(aig_obcjf == GetSize(aig_outputs)); | ||||||
| 
 | 
 | ||||||
| 		f << stringf("%s %d %d %d %d %d", ascii_mode ? "aag" : "aig", aig_m, aig_i, aig_l, aig_o, aig_a); | 		f << stringf("%s %d %d %d %d %d", ascii_mode ? "aag" : "aig", aig_m, aig_i, aig_l, aig_o, aig_a); | ||||||
|  | @ -689,15 +533,6 @@ struct XAigerWriter | ||||||
| 			for (int i = 0; i < aig_i; i++) | 			for (int i = 0; i < aig_i; i++) | ||||||
| 				f << stringf("%d\n", 2*i+2); | 				f << stringf("%d\n", 2*i+2); | ||||||
| 
 | 
 | ||||||
| 			//for (int i = 0; i < aig_l; i++) {
 |  | ||||||
| 			//	if (zinit_mode || aig_latchinit.at(i) == 0)
 |  | ||||||
| 			//		f << stringf("%d %d\n", 2*(aig_i+i)+2, aig_latchin.at(i));
 |  | ||||||
| 			//	else if (aig_latchinit.at(i) == 1)
 |  | ||||||
| 			//		f << stringf("%d %d 1\n", 2*(aig_i+i)+2, aig_latchin.at(i));
 |  | ||||||
| 			//	else if (aig_latchinit.at(i) == 2)
 |  | ||||||
| 			//		f << stringf("%d %d %d\n", 2*(aig_i+i)+2, aig_latchin.at(i), 2*(aig_i+i)+2);
 |  | ||||||
| 			//}
 |  | ||||||
| 
 |  | ||||||
| 			for (int i = 0; i < aig_obc; i++) | 			for (int i = 0; i < aig_obc; i++) | ||||||
| 				f << stringf("%d\n", aig_outputs.at(i)); | 				f << stringf("%d\n", aig_outputs.at(i)); | ||||||
| 
 | 
 | ||||||
|  | @ -715,15 +550,6 @@ struct XAigerWriter | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			//for (int i = 0; i < aig_l; i++) {
 |  | ||||||
| 			//	if (zinit_mode || aig_latchinit.at(i) == 0)
 |  | ||||||
| 			//		f << stringf("%d\n", aig_latchin.at(i));
 |  | ||||||
| 			//	else if (aig_latchinit.at(i) == 1)
 |  | ||||||
| 			//		f << stringf("%d 1\n", aig_latchin.at(i));
 |  | ||||||
| 			//	else if (aig_latchinit.at(i) == 2)
 |  | ||||||
| 			//		f << stringf("%d %d\n", aig_latchin.at(i), 2*(aig_i+i)+2);
 |  | ||||||
| 			//}
 |  | ||||||
| 
 |  | ||||||
| 			for (int i = 0; i < aig_obc; i++) | 			for (int i = 0; i < aig_obc; i++) | ||||||
| 				f << stringf("%d\n", aig_outputs.at(i)); | 				f << stringf("%d\n", aig_outputs.at(i)); | ||||||
| 
 | 
 | ||||||
|  | @ -756,14 +582,14 @@ struct XAigerWriter | ||||||
| 		std::stringstream h_buffer; | 		std::stringstream h_buffer; | ||||||
| 		auto write_h_buffer = std::bind(write_buffer, std::ref(h_buffer), std::placeholders::_1); | 		auto write_h_buffer = std::bind(write_buffer, std::ref(h_buffer), std::placeholders::_1); | ||||||
| 		write_h_buffer(1); | 		write_h_buffer(1); | ||||||
| 		log_debug("ciNum = %d\n", GetSize(input_bits) + GetSize(ff_bits) + GetSize(ci_bits)); | 		log_debug("ciNum = %d\n", GetSize(input_bits) + GetSize(ci_bits)); | ||||||
| 		write_h_buffer(input_bits.size() + ff_bits.size() + ci_bits.size()); | 		write_h_buffer(input_bits.size() + ci_bits.size()); | ||||||
| 		log_debug("coNum = %d\n", GetSize(output_bits) + GetSize(ff_bits) + GetSize(co_bits)); | 		log_debug("coNum = %d\n", GetSize(output_bits) + GetSize(co_bits)); | ||||||
| 		write_h_buffer(output_bits.size() + GetSize(ff_bits) + GetSize(co_bits)); | 		write_h_buffer(output_bits.size() + GetSize(co_bits)); | ||||||
| 		log_debug("piNum = %d\n", GetSize(input_bits) + GetSize(ff_bits)); | 		log_debug("piNum = %d\n", GetSize(input_bits)); | ||||||
| 		write_h_buffer(input_bits.size() + ff_bits.size()); | 		write_h_buffer(input_bits.size()); | ||||||
| 		log_debug("poNum = %d\n", GetSize(output_bits) + GetSize(ff_bits)); | 		log_debug("poNum = %d\n", GetSize(output_bits)); | ||||||
| 		write_h_buffer(output_bits.size() + ff_bits.size()); | 		write_h_buffer(output_bits.size()); | ||||||
| 		log_debug("boxNum = %d\n", GetSize(box_list)); | 		log_debug("boxNum = %d\n", GetSize(box_list)); | ||||||
| 		write_h_buffer(box_list.size()); | 		write_h_buffer(box_list.size()); | ||||||
| 
 | 
 | ||||||
|  | @ -779,7 +605,7 @@ struct XAigerWriter | ||||||
| 		//for (auto bit : output_bits)
 | 		//for (auto bit : output_bits)
 | ||||||
| 		//	write_o_buffer(0);
 | 		//	write_o_buffer(0);
 | ||||||
| 
 | 
 | ||||||
| 		if (!box_list.empty() || !ff_bits.empty()) { | 		if (!box_list.empty()) { | ||||||
| 			RTLIL::Module *holes_module = module->design->addModule("$__holes__"); | 			RTLIL::Module *holes_module = module->design->addModule("$__holes__"); | ||||||
| 			log_assert(holes_module); | 			log_assert(holes_module); | ||||||
| 
 | 
 | ||||||
|  | @ -845,41 +671,13 @@ struct XAigerWriter | ||||||
| 
 | 
 | ||||||
| 			std::stringstream r_buffer; | 			std::stringstream r_buffer; | ||||||
| 			auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1); | 			auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1); | ||||||
| 			log_debug("flopNum = %d\n", GetSize(ff_bits)); | 			write_r_buffer(0); | ||||||
| 			write_r_buffer(ff_bits.size()); |  | ||||||
| 			int mergeability_class = 1; |  | ||||||
| 			for (auto bit : ff_bits) { |  | ||||||
| 				write_r_buffer(mergeability_class++); |  | ||||||
| 				write_i_buffer(arrival_times.at(bit, 0)); |  | ||||||
| 				//write_o_buffer(0);
 |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			f << "r"; | 			f << "r"; | ||||||
| 			std::string buffer_str = r_buffer.str(); | 			std::string buffer_str = r_buffer.str(); | ||||||
| 			int32_t buffer_size_be = to_big_endian(buffer_str.size()); | 			int32_t buffer_size_be = to_big_endian(buffer_str.size()); | ||||||
| 			f.write(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be)); | 			f.write(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be)); | ||||||
| 			f.write(buffer_str.data(), buffer_str.size()); | 			f.write(buffer_str.data(), buffer_str.size()); | ||||||
| 
 | 
 | ||||||
| 			std::stringstream s_buffer; |  | ||||||
| 			auto write_s_buffer = std::bind(write_buffer, std::ref(s_buffer), std::placeholders::_1); |  | ||||||
| 			write_s_buffer(ff_bits.size()); |  | ||||||
| 			for (auto bit : ff_bits) { |  | ||||||
| 				auto it = bit.wire->attributes.find("\\init"); |  | ||||||
| 				if (it != bit.wire->attributes.end()) { |  | ||||||
| 					auto init = it->second[bit.offset]; |  | ||||||
| 					if (init == RTLIL::S1) { |  | ||||||
| 						write_s_buffer(1); |  | ||||||
| 						continue; |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 				write_s_buffer(0); |  | ||||||
| 			} |  | ||||||
| 			f << "s"; |  | ||||||
| 			buffer_str = s_buffer.str(); |  | ||||||
| 			buffer_size_be = to_big_endian(buffer_str.size()); |  | ||||||
| 			f.write(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be)); |  | ||||||
| 			f.write(buffer_str.data(), buffer_str.size()); |  | ||||||
| 
 |  | ||||||
| 			if (holes_module) { | 			if (holes_module) { | ||||||
| 				log_push(); | 				log_push(); | ||||||
| 
 | 
 | ||||||
|  | @ -915,7 +713,7 @@ struct XAigerWriter | ||||||
| 				Pass::call(holes_design, "clean -purge"); | 				Pass::call(holes_design, "clean -purge"); | ||||||
| 
 | 
 | ||||||
| 				std::stringstream a_buffer; | 				std::stringstream a_buffer; | ||||||
| 				XAigerWriter writer(holes_module, false /*zinit_mode*/, true /* holes_mode */); | 				XAigerWriter writer(holes_module, true /* holes_mode */); | ||||||
| 				writer.write_aiger(a_buffer, false /*ascii_mode*/); | 				writer.write_aiger(a_buffer, false /*ascii_mode*/); | ||||||
| 
 | 
 | ||||||
| 				delete holes_design; | 				delete holes_design; | ||||||
|  | @ -953,9 +751,7 @@ struct XAigerWriter | ||||||
| 	void write_map(std::ostream &f, bool verbose_map) | 	void write_map(std::ostream &f, bool verbose_map) | ||||||
| 	{ | 	{ | ||||||
| 		dict<int, string> input_lines; | 		dict<int, string> input_lines; | ||||||
| 		dict<int, string> init_lines; |  | ||||||
| 		dict<int, string> output_lines; | 		dict<int, string> output_lines; | ||||||
| 		dict<int, string> latch_lines; |  | ||||||
| 		dict<int, string> wire_lines; | 		dict<int, string> wire_lines; | ||||||
| 
 | 
 | ||||||
| 		for (auto wire : module->wires()) | 		for (auto wire : module->wires()) | ||||||
|  | @ -976,30 +772,10 @@ struct XAigerWriter | ||||||
| 
 | 
 | ||||||
| 				if (output_bits.count(b)) { | 				if (output_bits.count(b)) { | ||||||
| 					int o = ordered_outputs.at(b); | 					int o = ordered_outputs.at(b); | ||||||
| 					int init = 2; | 					output_lines[o] += stringf("output %d %d %s\n", o - GetSize(co_bits), i, log_id(wire)); | ||||||
| 					auto it = init_map.find(b); |  | ||||||
| 					if (it != init_map.end()) |  | ||||||
| 						init = it->second ? 1 : 0; |  | ||||||
| 					output_lines[o] += stringf("output %d %d %s %d\n", o - GetSize(co_bits), i, log_id(wire), init); |  | ||||||
| 					continue; | 					continue; | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				//if (init_inputs.count(sig[i])) {
 |  | ||||||
| 				//	int a = init_inputs.at(sig[i]);
 |  | ||||||
| 				//	log_assert((a & 1) == 0);
 |  | ||||||
| 				//	init_lines[a] += stringf("init %d %d %s\n", (a >> 1)-1, i, log_id(wire));
 |  | ||||||
| 				//	continue;
 |  | ||||||
| 				//}
 |  | ||||||
| 
 |  | ||||||
| 				//if (ordered_latches.count(sig[i])) {
 |  | ||||||
| 				//	int l = ordered_latches.at(sig[i]);
 |  | ||||||
| 				//	if (zinit_mode && (aig_latchinit.at(l) == 1))
 |  | ||||||
| 				//		latch_lines[l] += stringf("invlatch %d %d %s\n", l, i, log_id(wire));
 |  | ||||||
| 				//	else
 |  | ||||||
| 				//		latch_lines[l] += stringf("latch %d %d %s\n", l, i, log_id(wire));
 |  | ||||||
| 				//	continue;
 |  | ||||||
| 				//}
 |  | ||||||
| 
 |  | ||||||
| 				if (verbose_map) { | 				if (verbose_map) { | ||||||
| 					if (aig_map.count(sig[i]) == 0) | 					if (aig_map.count(sig[i]) == 0) | ||||||
| 						continue; | 						continue; | ||||||
|  | @ -1015,10 +791,6 @@ struct XAigerWriter | ||||||
| 			f << it.second; | 			f << it.second; | ||||||
| 		log_assert(input_lines.size() == input_bits.size()); | 		log_assert(input_lines.size() == input_bits.size()); | ||||||
| 
 | 
 | ||||||
| 		init_lines.sort(); |  | ||||||
| 		for (auto &it : init_lines) |  | ||||||
| 			f << it.second; |  | ||||||
| 
 |  | ||||||
| 		int box_count = 0; | 		int box_count = 0; | ||||||
| 		for (auto cell : box_list) | 		for (auto cell : box_list) | ||||||
| 			f << stringf("box %d %d %s\n", box_count++, 0, log_id(cell->name)); | 			f << stringf("box %d %d %s\n", box_count++, 0, log_id(cell->name)); | ||||||
|  | @ -1030,10 +802,6 @@ struct XAigerWriter | ||||||
| 		if (omode && output_bits.empty()) | 		if (omode && output_bits.empty()) | ||||||
| 			f << "output " << output_lines.size() << " 0 $__dummy__\n"; | 			f << "output " << output_lines.size() << " 0 $__dummy__\n"; | ||||||
| 
 | 
 | ||||||
| 		latch_lines.sort(); |  | ||||||
| 		for (auto &it : latch_lines) |  | ||||||
| 			f << it.second; |  | ||||||
| 
 |  | ||||||
| 		wire_lines.sort(); | 		wire_lines.sort(); | ||||||
| 		for (auto &it : wire_lines) | 		for (auto &it : wire_lines) | ||||||
| 			f << it.second; | 			f << it.second; | ||||||
|  | @ -1054,10 +822,6 @@ struct XAigerBackend : public Backend { | ||||||
| 		log("    -ascii\n"); | 		log("    -ascii\n"); | ||||||
| 		log("        write ASCII version of AIGER format\n"); | 		log("        write ASCII version of AIGER format\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("    -zinit\n"); |  | ||||||
| 		log("        convert FFs to zero-initialized FFs, adding additional inputs for\n"); |  | ||||||
| 		log("        uninitialized FFs.\n"); |  | ||||||
| 		log("\n"); |  | ||||||
| 		log("    -map <filename>\n"); | 		log("    -map <filename>\n"); | ||||||
| 		log("        write an extra file with port and latch symbols\n"); | 		log("        write an extra file with port and latch symbols\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
|  | @ -1068,7 +832,6 @@ struct XAigerBackend : public Backend { | ||||||
| 	void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE | 	void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE | ||||||
| 	{ | 	{ | ||||||
| 		bool ascii_mode = false; | 		bool ascii_mode = false; | ||||||
| 		bool zinit_mode = false; |  | ||||||
| 		bool verbose_map = false; | 		bool verbose_map = false; | ||||||
| 		std::string map_filename; | 		std::string map_filename; | ||||||
| 
 | 
 | ||||||
|  | @ -1081,10 +844,6 @@ struct XAigerBackend : public Backend { | ||||||
| 				ascii_mode = true; | 				ascii_mode = true; | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (args[argidx] == "-zinit") { |  | ||||||
| 				zinit_mode = true; |  | ||||||
| 				continue; |  | ||||||
| 			} |  | ||||||
| 			if (map_filename.empty() && args[argidx] == "-map" && argidx+1 < args.size()) { | 			if (map_filename.empty() && args[argidx] == "-map" && argidx+1 < args.size()) { | ||||||
| 				map_filename = args[++argidx]; | 				map_filename = args[++argidx]; | ||||||
| 				continue; | 				continue; | ||||||
|  | @ -1103,7 +862,7 @@ struct XAigerBackend : public Backend { | ||||||
| 		if (top_module == nullptr) | 		if (top_module == nullptr) | ||||||
| 			log_error("Can't find top module in current design!\n"); | 			log_error("Can't find top module in current design!\n"); | ||||||
| 
 | 
 | ||||||
| 		XAigerWriter writer(top_module, zinit_mode); | 		XAigerWriter writer(top_module); | ||||||
| 		writer.write_aiger(*f, ascii_mode); | 		writer.write_aiger(*f, ascii_mode); | ||||||
| 
 | 
 | ||||||
| 		if (!map_filename.empty()) { | 		if (!map_filename.empty()) { | ||||||
|  |  | ||||||
|  | @ -732,19 +732,12 @@ void AigerReader::parse_aiger_binary() | ||||||
| void AigerReader::post_process() | void AigerReader::post_process() | ||||||
| { | { | ||||||
| 	pool<IdString> seen_boxes; | 	pool<IdString> seen_boxes; | ||||||
| 	pool<IdString> flops; | 	unsigned ci_count = 0, co_count = 0; | ||||||
| 	unsigned ci_count = 0, co_count = 0, flop_count = 0; |  | ||||||
| 	for (auto cell : boxes) { | 	for (auto cell : boxes) { | ||||||
| 		RTLIL::Module* box_module = design->module(cell->type); | 		RTLIL::Module* box_module = design->module(cell->type); | ||||||
| 		log_assert(box_module); | 		log_assert(box_module); | ||||||
| 
 | 
 | ||||||
| 		bool is_flop = false; |  | ||||||
| 		if (seen_boxes.insert(cell->type).second) { | 		if (seen_boxes.insert(cell->type).second) { | ||||||
| 			if (box_module->attributes.count("\\abc_flop")) { |  | ||||||
| 				log_assert(flop_count < flopNum); |  | ||||||
| 				flops.insert(cell->type); |  | ||||||
| 				is_flop = true; |  | ||||||
| 			} |  | ||||||
| 			auto it = box_module->attributes.find("\\abc_carry"); | 			auto it = box_module->attributes.find("\\abc_carry"); | ||||||
| 			if (it != box_module->attributes.end()) { | 			if (it != box_module->attributes.end()) { | ||||||
| 				RTLIL::Wire *carry_in = nullptr, *carry_out = nullptr; | 				RTLIL::Wire *carry_in = nullptr, *carry_out = nullptr; | ||||||
|  | @ -784,8 +777,6 @@ void AigerReader::post_process() | ||||||
| 				carry_out->port_id = ports.size(); | 				carry_out->port_id = ports.size(); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		else |  | ||||||
| 			is_flop = flops.count(cell->type); |  | ||||||
| 
 | 
 | ||||||
| 		// NB: Assume box_module->ports are sorted alphabetically
 | 		// NB: Assume box_module->ports are sorted alphabetically
 | ||||||
| 		//     (as RTLIL::Module::fixup_ports() would do)
 | 		//     (as RTLIL::Module::fixup_ports() would do)
 | ||||||
|  | @ -812,25 +803,7 @@ void AigerReader::post_process() | ||||||
| 				rhs.append(wire); | 				rhs.append(wire); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (!is_flop || port_name != "\\$pastQ") | 			cell->setPort(port_name, rhs); | ||||||
| 				cell->setPort(port_name, rhs); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (is_flop) { |  | ||||||
| 			RTLIL::Wire *d = outputs[outputs.size() - flopNum + flop_count]; |  | ||||||
| 			log_assert(d); |  | ||||||
| 			log_assert(d->port_output); |  | ||||||
| 			d->port_output = false; |  | ||||||
| 
 |  | ||||||
| 			RTLIL::Wire *q = inputs[piNum - flopNum + flop_count]; |  | ||||||
| 			log_assert(q); |  | ||||||
| 			log_assert(q->port_input); |  | ||||||
| 			q->port_input = false; |  | ||||||
| 
 |  | ||||||
| 			flop_count++; |  | ||||||
| 			module->connect(q, d); |  | ||||||
| 			cell->set_bool_attribute("\\abc_flop"); |  | ||||||
| 			continue; |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -934,10 +907,6 @@ void AigerReader::post_process() | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 				log_debug(" -> %s\n", log_id(wire)); | 				log_debug(" -> %s\n", log_id(wire)); | ||||||
| 				int init; |  | ||||||
| 				mf >> init; |  | ||||||
| 				if (init < 2) |  | ||||||
| 					wire->attributes["\\init"] = init; |  | ||||||
| 			} | 			} | ||||||
| 			else if (type == "box") { | 			else if (type == "box") { | ||||||
| 				RTLIL::Cell* cell = module->cell(stringf("$__box%d__", variable)); | 				RTLIL::Cell* cell = module->cell(stringf("$__box%d__", variable)); | ||||||
|  |  | ||||||
|  | @ -551,7 +551,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri | ||||||
| 		dict<IdString, bool> abc_box; | 		dict<IdString, bool> abc_box; | ||||||
| 		vector<RTLIL::Cell*> boxes; | 		vector<RTLIL::Cell*> boxes; | ||||||
| 		for (auto cell : module->selected_cells()) { | 		for (auto cell : module->selected_cells()) { | ||||||
| 			if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC_FF_))) { | 			if (cell->type.in(ID($_AND_), ID($_NOT_))) { | ||||||
| 				module->remove(cell); | 				module->remove(cell); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
|  | @ -651,7 +651,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri | ||||||
| 				cell->attributes = mapped_cell->attributes; | 				cell->attributes = mapped_cell->attributes; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			auto abc_flop = mapped_cell->attributes.count("\\abc_flop"); |  | ||||||
| 			for (auto &conn : mapped_cell->connections()) { | 			for (auto &conn : mapped_cell->connections()) { | ||||||
| 				RTLIL::SigSpec newsig; | 				RTLIL::SigSpec newsig; | ||||||
| 				for (auto c : conn.second.chunks()) { | 				for (auto c : conn.second.chunks()) { | ||||||
|  | @ -664,17 +663,15 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri | ||||||
| 				} | 				} | ||||||
| 				cell->setPort(conn.first, newsig); | 				cell->setPort(conn.first, newsig); | ||||||
| 
 | 
 | ||||||
| 				if (!abc_flop) { | 				if (cell->input(conn.first)) { | ||||||
| 					if (cell->input(conn.first)) { | 					for (auto i : newsig) | ||||||
| 						for (auto i : newsig) | 						bit2sinks[i].push_back(cell); | ||||||
| 							bit2sinks[i].push_back(cell); | 					for (auto i : conn.second) | ||||||
| 						for (auto i : conn.second) | 						bit_users[i].insert(mapped_cell->name); | ||||||
| 							bit_users[i].insert(mapped_cell->name); |  | ||||||
| 					} |  | ||||||
| 					if (cell->output(conn.first)) |  | ||||||
| 						for (auto i : conn.second) |  | ||||||
| 							bit_drivers[i].insert(mapped_cell->name); |  | ||||||
| 				} | 				} | ||||||
|  | 				if (cell->output(conn.first)) | ||||||
|  | 					for (auto i : conn.second) | ||||||
|  | 						bit_drivers[i].insert(mapped_cell->name); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -1170,7 +1167,6 @@ struct Abc9Pass : public Pass { | ||||||
| 			assign_map.set(mod); | 			assign_map.set(mod); | ||||||
| 
 | 
 | ||||||
| 			if (!dff_mode || !clk_str.empty()) { | 			if (!dff_mode || !clk_str.empty()) { | ||||||
| 
 |  | ||||||
| 				design->selection_stack.emplace_back(false); | 				design->selection_stack.emplace_back(false); | ||||||
| 				RTLIL::Selection& sel = design->selection_stack.back(); | 				RTLIL::Selection& sel = design->selection_stack.back(); | ||||||
| 				sel.select(mod); | 				sel.select(mod); | ||||||
|  | @ -1198,13 +1194,6 @@ struct Abc9Pass : public Pass { | ||||||
| 			std::map<RTLIL::Cell*, std::set<RTLIL::SigBit>> cell_to_bit, cell_to_bit_up, cell_to_bit_down; | 			std::map<RTLIL::Cell*, std::set<RTLIL::SigBit>> cell_to_bit, cell_to_bit_up, cell_to_bit_down; | ||||||
| 			std::map<RTLIL::SigBit, std::set<RTLIL::Cell*>> bit_to_cell, bit_to_cell_up, bit_to_cell_down; | 			std::map<RTLIL::SigBit, std::set<RTLIL::Cell*>> bit_to_cell, bit_to_cell_up, bit_to_cell_down; | ||||||
| 
 | 
 | ||||||
| 			pool<IdString> seen_cells; |  | ||||||
| 			struct flop_data_t { |  | ||||||
| 				IdString clk_port; |  | ||||||
| 				IdString en_port; |  | ||||||
| 			}; |  | ||||||
| 			dict<IdString, flop_data_t> flop_data; |  | ||||||
| 
 |  | ||||||
| 			for (auto cell : all_cells) { | 			for (auto cell : all_cells) { | ||||||
| 				clkdomain_t key; | 				clkdomain_t key; | ||||||
| 
 | 
 | ||||||
|  | @ -1225,57 +1214,20 @@ struct Abc9Pass : public Pass { | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				decltype(flop_data)::iterator it; | 				if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) | ||||||
| 				if (seen_cells.insert(cell->type).second) { | 				{ | ||||||
| 					RTLIL::Module* inst_module = design->module(cell->type); | 					key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID(C))), true, RTLIL::SigSpec()); | ||||||
| 					if (!inst_module) |  | ||||||
| 						continue; |  | ||||||
| 
 |  | ||||||
| 					if (!inst_module->attributes.count("\\abc_flop")) |  | ||||||
| 						continue; |  | ||||||
| 
 |  | ||||||
| 					IdString abc_flop_clk, abc_flop_en; |  | ||||||
| 					for (auto port_name : inst_module->ports) { |  | ||||||
| 						auto wire = inst_module->wire(port_name); |  | ||||||
| 						log_assert(wire); |  | ||||||
| 						if (wire->attributes.count("\\abc_flop_clk")) { |  | ||||||
| 							if (abc_flop_clk != IdString()) |  | ||||||
| 								log_error("More than one port has the 'abc_flop_clk' attribute set on module '%s'.\n", log_id(cell->type)); |  | ||||||
| 							abc_flop_clk = port_name; |  | ||||||
| 						} |  | ||||||
| 						if (wire->attributes.count("\\abc_flop_en")) { |  | ||||||
| 							if (abc_flop_en != IdString()) |  | ||||||
| 								log_error("More than one port has the 'abc_flop_en' attribute set on module '%s'.\n", log_id(cell->type)); |  | ||||||
| 							abc_flop_en = port_name; |  | ||||||
| 						} |  | ||||||
| 					} |  | ||||||
| 
 |  | ||||||
| 					if (abc_flop_clk == IdString()) |  | ||||||
| 						log_error("'abc_flop_clk' attribute not found on any ports on module '%s'.\n", log_id(cell->type)); |  | ||||||
| 					if (abc_flop_en == IdString()) |  | ||||||
| 						log_error("'abc_flop_en' attribute not found on any ports on module '%s'.\n", log_id(cell->type)); |  | ||||||
| 
 |  | ||||||
| 					it = flop_data.insert(std::make_pair(cell->type, flop_data_t{abc_flop_clk, abc_flop_en})).first; |  | ||||||
| 				} | 				} | ||||||
| 				else { | 				else | ||||||
| 					it = flop_data.find(cell->type); | 				if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_))) | ||||||
| 					if (it == flop_data.end()) | 				{ | ||||||
| 						continue; | 					bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_)); | ||||||
|  | 					bool this_en_pol = cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)); | ||||||
|  | 					key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), this_en_pol, assign_map(cell->getPort(ID(E)))); | ||||||
| 				} | 				} | ||||||
|  | 				else | ||||||
|  | 					continue; | ||||||
| 
 | 
 | ||||||
| 				const auto &data = it->second; |  | ||||||
| 
 |  | ||||||
| 				auto jt = cell->parameters.find("\\CLK_POLARITY"); |  | ||||||
| 				if (jt == cell->parameters.end()) |  | ||||||
| 					log_error("'CLK_POLARITY' is not a parameter on module '%s'.\n", log_id(cell->type)); |  | ||||||
| 				bool this_clk_pol = jt->second.as_bool(); |  | ||||||
| 
 |  | ||||||
| 				jt = cell->parameters.find("\\EN_POLARITY"); |  | ||||||
| 				if (jt == cell->parameters.end()) |  | ||||||
| 					log_error("'EN_POLARITY' is not a parameter on module '%s'.\n", log_id(cell->type)); |  | ||||||
| 				bool this_en_pol = jt->second.as_bool(); |  | ||||||
| 
 |  | ||||||
| 				key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(data.clk_port)), this_en_pol, assign_map(cell->getPort(data.en_port))); |  | ||||||
| 
 | 
 | ||||||
| 				unassigned_cells.erase(cell); | 				unassigned_cells.erase(cell); | ||||||
| 				expand_queue.insert(cell); | 				expand_queue.insert(cell); | ||||||
|  |  | ||||||
|  | @ -20,103 +20,6 @@ | ||||||
| 
 | 
 | ||||||
| // ============================================================================ | // ============================================================================ | ||||||
| 
 | 
 | ||||||
| module FDRE (output reg Q, input C, CE, D, R); |  | ||||||
|   parameter [0:0] INIT = 1'b0; |  | ||||||
|   parameter [0:0] IS_C_INVERTED = 1'b0; |  | ||||||
|   parameter [0:0] IS_D_INVERTED = 1'b0; |  | ||||||
|   parameter [0:0] IS_R_INVERTED = 1'b0; |  | ||||||
|   wire \$nextQ ; |  | ||||||
|   \$__ABC_FDRE #( |  | ||||||
|     .INIT(INIT), |  | ||||||
|     .IS_C_INVERTED(IS_C_INVERTED), |  | ||||||
|     .IS_D_INVERTED(IS_D_INVERTED), |  | ||||||
|     .IS_R_INVERTED(IS_R_INVERTED), |  | ||||||
|     .CLK_POLARITY(!IS_C_INVERTED), |  | ||||||
|     .EN_POLARITY(1'b1) |  | ||||||
|   ) _TECHMAP_REPLACE_ ( |  | ||||||
|     .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .R(R) |  | ||||||
|   ); |  | ||||||
|   \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); |  | ||||||
| endmodule |  | ||||||
| module FDRE_1 (output reg Q, input C, CE, D, R); |  | ||||||
|   parameter [0:0] INIT = 1'b0; |  | ||||||
|   wire \$nextQ ; |  | ||||||
|   \$__ABC_FDRE_1 #( |  | ||||||
|       .INIT(|0), |  | ||||||
|     .CLK_POLARITY(1'b0), |  | ||||||
|     .EN_POLARITY(1'b1) |  | ||||||
|   ) _TECHMAP_REPLACE_ ( |  | ||||||
|     .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .R(R) |  | ||||||
|   ); |  | ||||||
|   \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(Q)); |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module FDCE (output reg Q, input C, CE, D, CLR); |  | ||||||
|   parameter [0:0] INIT = 1'b0; |  | ||||||
|   parameter [0:0] IS_C_INVERTED = 1'b0; |  | ||||||
|   parameter [0:0] IS_D_INVERTED = 1'b0; |  | ||||||
|   parameter [0:0] IS_CLR_INVERTED = 1'b0; |  | ||||||
|   wire \$nextQ , \$currQ ; |  | ||||||
|   \$__ABC_FDCE #( |  | ||||||
|     .INIT(INIT), |  | ||||||
|     .IS_C_INVERTED(IS_C_INVERTED), |  | ||||||
|     .IS_D_INVERTED(IS_D_INVERTED), |  | ||||||
|     .IS_CLR_INVERTED(IS_CLR_INVERTED), |  | ||||||
|     .CLK_POLARITY(!IS_C_INVERTED), |  | ||||||
|     .EN_POLARITY(1'b1) |  | ||||||
|   ) _TECHMAP_REPLACE_ ( |  | ||||||
|     .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .CLR(CLR) |  | ||||||
|   ); |  | ||||||
|   \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); |  | ||||||
|   \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(CLR), .Y(Q)); |  | ||||||
| endmodule |  | ||||||
| module FDCE_1 (output reg Q, input C, CE, D, CLR); |  | ||||||
|   parameter [0:0] INIT = 1'b0; |  | ||||||
|   wire \$nextQ , \$currQ ; |  | ||||||
|   \$__ABC_FDCE_1 #( |  | ||||||
|     .INIT(INIT), |  | ||||||
|     .CLK_POLARITY(1'b0), |  | ||||||
|     .EN_POLARITY(1'b1) |  | ||||||
|   ) _TECHMAP_REPLACE_ ( |  | ||||||
|     .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .CLR(CLR) |  | ||||||
|   ); |  | ||||||
|   \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); |  | ||||||
|   \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(CLR), .Y(Q)); |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module FDPE (output reg Q, input C, CE, D, PRE); |  | ||||||
|   parameter [0:0] INIT = 1'b0; |  | ||||||
|   parameter [0:0] IS_C_INVERTED = 1'b0; |  | ||||||
|   parameter [0:0] IS_D_INVERTED = 1'b0; |  | ||||||
|   parameter [0:0] IS_PRE_INVERTED = 1'b0; |  | ||||||
|   wire \$nextQ , \$currQ ; |  | ||||||
|   \$__ABC_FDPE #( |  | ||||||
|     .INIT(INIT), |  | ||||||
|     .IS_C_INVERTED(IS_C_INVERTED), |  | ||||||
|     .IS_D_INVERTED(IS_D_INVERTED), |  | ||||||
|     .IS_PRE_INVERTED(IS_PRE_INVERTED), |  | ||||||
|     .CLK_POLARITY(!IS_C_INVERTED), |  | ||||||
|     .EN_POLARITY(1'b1) |  | ||||||
|   ) _TECHMAP_REPLACE_ ( |  | ||||||
|     .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .PRE(PRE) |  | ||||||
|   ); |  | ||||||
|   \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); |  | ||||||
|   \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(PRE), .Y(Q)); |  | ||||||
| endmodule |  | ||||||
| module FDPE_1 (output reg Q, input C, CE, D, PRE); |  | ||||||
|   parameter [0:0] INIT = 1'b0; |  | ||||||
|   wire \$nextQ , \$currQ ; |  | ||||||
|   \$__ABC_FDPE_1 #( |  | ||||||
|     .INIT(INIT), |  | ||||||
|     .CLK_POLARITY(1'b0), |  | ||||||
|     .EN_POLARITY(1'b1) |  | ||||||
|   ) _TECHMAP_REPLACE_ ( |  | ||||||
|     .D(D), .Q(\$nextQ ), .\$pastQ (Q), .C(C), .CE(CE), .PRE(PRE) |  | ||||||
|   ); |  | ||||||
|   \$__ABC_FF_ abc_dff (.D(\$nextQ ), .Q(\$currQ )); |  | ||||||
|   \$__ABC_ASYNC abc_async (.A(\$currQ ), .S(PRE), .Y(Q)); |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module RAM32X1D ( | module RAM32X1D ( | ||||||
|   output DPO, SPO, |   output DPO, SPO, | ||||||
|   input  D, |   input  D, | ||||||
|  |  | ||||||
|  | @ -26,94 +26,6 @@ module \$__XILINX_MUXF78 (output O, input I0, I1, I2, I3, S0, S1); | ||||||
|                 : (S0 ? I1 : I0); |                 : (S0 ? I1 : I0); | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module \$__ABC_FF_ (input C, D, output Q); |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| (* abc_box_id = 1000 *) |  | ||||||
| module \$__ABC_ASYNC (input A, S, output Y); |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| (* abc_box_id=1001, lib_whitebox, abc_flop *) |  | ||||||
| module \$__ABC_FDRE ((* abc_flop_q, abc_arrival=303 *) output Q, |  | ||||||
|                      (* abc_flop_clk *) input C, |  | ||||||
|                      (* abc_flop_en *)  input CE, |  | ||||||
|                      (* abc_flop_d *)   input D, |  | ||||||
|                      input R, \$pastQ ); |  | ||||||
|   parameter [0:0] INIT = 1'b0; |  | ||||||
|   parameter [0:0] IS_C_INVERTED = 1'b0; |  | ||||||
|   parameter [0:0] IS_D_INVERTED = 1'b0; |  | ||||||
|   parameter [0:0] IS_R_INVERTED = 1'b0; |  | ||||||
|   parameter CLK_POLARITY = !IS_C_INVERTED; |  | ||||||
|   parameter EN_POLARITY = 1'b1; |  | ||||||
|   assign Q = (R ^ IS_R_INVERTED) ? 1'b0 : (CE ? (D ^ IS_D_INVERTED) : \$pastQ ); |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| (* abc_box_id=1002, lib_whitebox, abc_flop *) |  | ||||||
| module \$__ABC_FDRE_1 ((* abc_flop_q, abc_arrival=303 *) output Q, |  | ||||||
|                        (* abc_flop_clk *) input C, |  | ||||||
|                        (* abc_flop_en *)  input CE, |  | ||||||
|                        (* abc_flop_d *)   input D, |  | ||||||
|                        input R, \$pastQ ); |  | ||||||
|   parameter [0:0] INIT = 1'b0; |  | ||||||
|   parameter CLK_POLARITY = 1'b0; |  | ||||||
|   parameter EN_POLARITY = 1'b1; |  | ||||||
|   assign Q = R ? 1'b0 : (CE ? D : \$pastQ ); |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| (* abc_box_id=1003, lib_whitebox, abc_flop *) |  | ||||||
| module \$__ABC_FDCE ((* abc_flop_q, abc_arrival=303 *) output Q, |  | ||||||
|                      (* abc_flop_clk *) input C, |  | ||||||
|                      (* abc_flop_en *)  input CE, |  | ||||||
|                      (* abc_flop_d *)   input D, |  | ||||||
|                      input CLR, \$pastQ ); |  | ||||||
|   parameter [0:0] INIT = 1'b0; |  | ||||||
|   parameter [0:0] IS_C_INVERTED = 1'b0; |  | ||||||
|   parameter [0:0] IS_D_INVERTED = 1'b0; |  | ||||||
|   parameter [0:0] IS_CLR_INVERTED = 1'b0; |  | ||||||
|   parameter CLK_POLARITY = !IS_C_INVERTED; |  | ||||||
|   parameter EN_POLARITY = 1'b1; |  | ||||||
|   assign Q = (CE && !(CLR ^ IS_CLR_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| (* abc_box_id=1004, lib_whitebox, abc_flop *) |  | ||||||
| module \$__ABC_FDCE_1 ((* abc_flop_q, abc_arrival=303 *) output Q, |  | ||||||
|                        (* abc_flop_clk *) input C, |  | ||||||
|                        (* abc_flop_en *)  input CE, |  | ||||||
|                        (* abc_flop_d *)   input D, |  | ||||||
|                        input CLR, \$pastQ ); |  | ||||||
|   parameter [0:0] INIT = 1'b0; |  | ||||||
|   parameter CLK_POLARITY = 1'b0; |  | ||||||
|   parameter EN_POLARITY = 1'b1; |  | ||||||
|   assign Q = (CE && !CLR) ? D : \$pastQ ; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| (* abc_box_id=1005, lib_whitebox, abc_flop *) |  | ||||||
| module \$__ABC_FDPE ((* abc_flop_q, abc_arrival=303 *) output Q, |  | ||||||
|                      (* abc_flop_clk *) input C, |  | ||||||
|                      (* abc_flop_en *)  input CE, |  | ||||||
|                      (* abc_flop_d *)   input D, |  | ||||||
|                      input PRE, \$pastQ ); |  | ||||||
|   parameter [0:0] INIT = 1'b0; |  | ||||||
|   parameter [0:0] IS_C_INVERTED = 1'b0; |  | ||||||
|   parameter [0:0] IS_D_INVERTED = 1'b0; |  | ||||||
|   parameter [0:0] IS_PRE_INVERTED = 1'b0; |  | ||||||
|   parameter CLK_POLARITY = !IS_C_INVERTED; |  | ||||||
|   parameter EN_POLARITY = 1'b1; |  | ||||||
|   assign Q = (CE && !(PRE ^ IS_PRE_INVERTED)) ? (D ^ IS_D_INVERTED) : \$pastQ ; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| (* abc_box_id=1006, lib_whitebox, abc_flop *) |  | ||||||
| module \$__ABC_FDPE_1 ((* abc_flop_q, abc_arrival=303 *) output Q, |  | ||||||
|                        (* abc_flop_clk *) input C, |  | ||||||
|                        (* abc_flop_en *)  input CE, |  | ||||||
|                        (* abc_flop_d *)   input D, |  | ||||||
|                        input PRE, \$pastQ ); |  | ||||||
|   parameter [0:0] INIT = 1'b0;  |  | ||||||
|   parameter CLK_POLARITY = 1'b0; |  | ||||||
|   parameter EN_POLARITY = 1'b1; |  | ||||||
|   assign Q = (CE && !PRE) ? D : \$pastQ ; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| (* abc_box_id=2000 *) | (* abc_box_id=2000 *) | ||||||
| module \$__ABC_LUTMUX6 (input A, input [5:0] S, output Y); | module \$__ABC_LUTMUX6 (input A, input [5:0] S, output Y); | ||||||
| endmodule | endmodule | ||||||
|  | @ -121,7 +33,6 @@ endmodule | ||||||
| module \$__ABC_LUTMUX7 (input A, input [6:0] S, output Y); | module \$__ABC_LUTMUX7 (input A, input [6:0] S, output Y); | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| module \$__ABC_RAM32X1D ( | module \$__ABC_RAM32X1D ( | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 |   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 | ||||||
|   (* abc_arrival=1153 *) output DPO, SPO, |   (* abc_arrival=1153 *) output DPO, SPO, | ||||||
|  |  | ||||||
|  | @ -20,125 +20,6 @@ | ||||||
| 
 | 
 | ||||||
| // ============================================================================ | // ============================================================================ | ||||||
| 
 | 
 | ||||||
| module \$__ABC_ASYNC (input A, S, output Y); |  | ||||||
|   assign Y = A; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module \$__ABC_FDRE (output Q, |  | ||||||
|                      input C, |  | ||||||
|                      input CE, |  | ||||||
|                      input D, |  | ||||||
|                      input R, \$pastQ ); |  | ||||||
|   parameter [0:0] INIT = 1'b0; |  | ||||||
|   parameter [0:0] IS_C_INVERTED = 1'b0; |  | ||||||
|   parameter [0:0] IS_D_INVERTED = 1'b0; |  | ||||||
|   parameter [0:0] IS_R_INVERTED = 1'b0; |  | ||||||
|   parameter CLK_POLARITY = !IS_C_INVERTED; |  | ||||||
|   parameter EN_POLARITY = 1'b1; |  | ||||||
| 
 |  | ||||||
|   FDRE #( |  | ||||||
|     .INIT(INIT), |  | ||||||
|     .IS_C_INVERTED(IS_C_INVERTED), |  | ||||||
|     .IS_D_INVERTED(IS_D_INVERTED), |  | ||||||
|     .IS_R_INVERTED(IS_R_INVERTED), |  | ||||||
|   ) _TECHMAP_REPLACE_ ( |  | ||||||
|     .D(D), .Q(Q), .C(C), .CE(CE), .R(R) |  | ||||||
|   ); |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module \$__ABC_FDRE_1 (output Q, |  | ||||||
|                        input C, |  | ||||||
|                        input CE, |  | ||||||
|                        input D, |  | ||||||
|                        input R, \$pastQ ); |  | ||||||
|   parameter [0:0] INIT = 1'b0; |  | ||||||
|   parameter CLK_POLARITY = 1'b0; |  | ||||||
|   parameter EN_POLARITY = 1'b1; |  | ||||||
|   assign Q = R ? 1'b0 : (CE ? D : \$pastQ ); |  | ||||||
| 
 |  | ||||||
|   FDRE_1 #( |  | ||||||
|     .INIT(INIT), |  | ||||||
|   ) _TECHMAP_REPLACE_ ( |  | ||||||
|     .D(D), .Q(Q), .C(C), .CE(CE), .R(R) |  | ||||||
|   ); |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module \$__ABC_FDCE (output Q, |  | ||||||
|                      input C, |  | ||||||
|                      input CE, |  | ||||||
|                      input D, |  | ||||||
|                      input CLR, \$pastQ ); |  | ||||||
|   parameter [0:0] INIT = 1'b0; |  | ||||||
|   parameter [0:0] IS_C_INVERTED = 1'b0; |  | ||||||
|   parameter [0:0] IS_D_INVERTED = 1'b0; |  | ||||||
|   parameter [0:0] IS_CLR_INVERTED = 1'b0; |  | ||||||
|   parameter CLK_POLARITY = !IS_C_INVERTED; |  | ||||||
|   parameter EN_POLARITY = 1'b1; |  | ||||||
| 
 |  | ||||||
|   FDCE #( |  | ||||||
|     .INIT(INIT), |  | ||||||
|     .IS_C_INVERTED(IS_C_INVERTED), |  | ||||||
|     .IS_D_INVERTED(IS_D_INVERTED), |  | ||||||
|     .IS_CLR_INVERTED(IS_CLR_INVERTED), |  | ||||||
|   ) _TECHMAP_REPLACE_ ( |  | ||||||
|     .D(D), .Q(Q), .C(C), .CE(CE), .CLR(CLR) |  | ||||||
|   ); |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module \$__ABC_FDCE_1 (output Q, |  | ||||||
|                        input C, |  | ||||||
|                        input CE, |  | ||||||
|                        input D, |  | ||||||
|                        input CLR, \$pastQ ); |  | ||||||
|   parameter [0:0] INIT = 1'b0; |  | ||||||
|   parameter CLK_POLARITY = 1'b0; |  | ||||||
|   parameter EN_POLARITY = 1'b1; |  | ||||||
| 
 |  | ||||||
|   FDCE_1 #( |  | ||||||
|     .INIT(INIT), |  | ||||||
|   ) _TECHMAP_REPLACE_ ( |  | ||||||
|     .D(D), .Q(Q), .C(C), .CE(CE), .CLR(CLR) |  | ||||||
|   ); |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module \$__ABC_FDPE (output Q, |  | ||||||
|                      input C, |  | ||||||
|                      input CE, |  | ||||||
|                      input D, |  | ||||||
|                      input PRE, \$pastQ ); |  | ||||||
|   parameter [0:0] INIT = 1'b0; |  | ||||||
|   parameter [0:0] IS_C_INVERTED = 1'b0; |  | ||||||
|   parameter [0:0] IS_D_INVERTED = 1'b0; |  | ||||||
|   parameter [0:0] IS_PRE_INVERTED = 1'b0; |  | ||||||
|   parameter CLK_POLARITY = !IS_C_INVERTED; |  | ||||||
|   parameter EN_POLARITY = 1'b1; |  | ||||||
| 
 |  | ||||||
|   FDPE #( |  | ||||||
|     .INIT(INIT), |  | ||||||
|     .IS_C_INVERTED(IS_C_INVERTED), |  | ||||||
|     .IS_D_INVERTED(IS_D_INVERTED), |  | ||||||
|     .IS_PRE_INVERTED(IS_PRE_INVERTED), |  | ||||||
|   ) _TECHMAP_REPLACE_ ( |  | ||||||
|     .D(D), .Q(Q), .C(C), .CE(CE), .PRE(PRE) |  | ||||||
|   ); |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module \$__ABC_FDPE_1 (output Q, |  | ||||||
|                        input C, |  | ||||||
|                        input CE, |  | ||||||
|                        input D, |  | ||||||
|                        input PRE, \$pastQ ); |  | ||||||
|   parameter [0:0] INIT = 1'b0; |  | ||||||
|   parameter CLK_POLARITY = 1'b0; |  | ||||||
|   parameter EN_POLARITY = 1'b1; |  | ||||||
| 
 |  | ||||||
|   FDPE_1 #( |  | ||||||
|     .INIT(INIT), |  | ||||||
|   ) _TECHMAP_REPLACE_ ( |  | ||||||
|     .D(D), .Q(Q), .C(C), .CE(CE), .PRE(PRE) |  | ||||||
|   ); |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module \$__ABC_LUTMUX6 (input A, input [5:0] S, output Y); | module \$__ABC_LUTMUX6 (input A, input [5:0] S, output Y); | ||||||
|   assign Y = A; |   assign Y = A; | ||||||
| endmodule | endmodule | ||||||
|  |  | ||||||
|  | @ -38,47 +38,6 @@ CARRY4 4 1 10 8 | ||||||
| 592 540 520 356 -   512 548 292 -   228 | 592 540 520 356 -   512 548 292 -   228 | ||||||
| 580 526 507 398 385 508 528 378 380 114 | 580 526 507 398 385 508 528 378 380 114 | ||||||
| 
 | 
 | ||||||
| # Box to emulate async behaviour of FD[CP]* |  | ||||||
| # Inputs: A S |  | ||||||
| # Outputs: Y |  | ||||||
| $__ABC_ASYNC 1000 0 2 1 |  | ||||||
| 0 764 |  | ||||||
| 
 |  | ||||||
| # The following FD*.{CE,R,CLR,PRE) are offset by 46ps to |  | ||||||
| # reflect the -46ps Tsu |  | ||||||
| # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L237-L251 |  | ||||||
| # https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L265-L277 |  | ||||||
| 
 |  | ||||||
| # Inputs: C CE D R \$pastQ |  | ||||||
| # Outputs: Q |  | ||||||
| FDRE 1001 1 5 1 |  | ||||||
| 0 151 0 446 0 |  | ||||||
| 
 |  | ||||||
| # Inputs: C CE D R \$pastQ |  | ||||||
| # Outputs: Q |  | ||||||
| FDRE_1 1002 1 5 1 |  | ||||||
| 0 151 0 446 0 |  | ||||||
| 
 |  | ||||||
| # Inputs: C CE CLR D \$pastQ |  | ||||||
| # Outputs: Q |  | ||||||
| FDCE 1003 1 5 1 |  | ||||||
| 0 151 806 0 0 |  | ||||||
| 
 |  | ||||||
| # Inputs: C CE CLR D \$pastQ |  | ||||||
| # Outputs: Q |  | ||||||
| FDCE_1 1004 1 5 1 |  | ||||||
| 0 151 806 0 0 |  | ||||||
| 
 |  | ||||||
| # Inputs: C CE D PRE \$pastQ |  | ||||||
| # Outputs: Q |  | ||||||
| FDPE 1005 1 5 1 |  | ||||||
| 0 151 0 806 0 |  | ||||||
| 
 |  | ||||||
| # Inputs: C CE D PRE \$pastQ |  | ||||||
| # Outputs: Q |  | ||||||
| FDPE_1 1006 1 5 1 |  | ||||||
| 0 151 0 806 0 |  | ||||||
| 
 |  | ||||||
| # SLICEM/A6LUT | # SLICEM/A6LUT | ||||||
| # Box to emulate comb/seq behaviour of RAMD{32,64} and SRL{16,32} | # Box to emulate comb/seq behaviour of RAMD{32,64} and SRL{16,32} | ||||||
| # Inputs: A S0 S1 S2 S3 S4 S5 | # Inputs: A S0 S1 S2 S3 S4 S5 | ||||||
|  |  | ||||||
|  | @ -211,7 +211,8 @@ endmodule | ||||||
| 
 | 
 | ||||||
| `endif | `endif | ||||||
| 
 | 
 | ||||||
| module FDRE (output reg Q, input C, CE, D, R); | module FDRE ((* abc_arrival=303 *) output reg Q, | ||||||
|  |              input C, CE, D, R); | ||||||
|   parameter [0:0] INIT = 1'b0; |   parameter [0:0] INIT = 1'b0; | ||||||
|   parameter [0:0] IS_C_INVERTED = 1'b0; |   parameter [0:0] IS_C_INVERTED = 1'b0; | ||||||
|   parameter [0:0] IS_D_INVERTED = 1'b0; |   parameter [0:0] IS_D_INVERTED = 1'b0; | ||||||
|  | @ -223,7 +224,8 @@ module FDRE (output reg Q, input C, CE, D, R); | ||||||
|   endcase endgenerate |   endcase endgenerate | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module FDSE (output reg Q, input C, CE, D, S); | module FDSE ((* abc_arrival=303 *) output reg Q, | ||||||
|  |              input C, CE, D, S); | ||||||
|   parameter [0:0] INIT = 1'b1; |   parameter [0:0] INIT = 1'b1; | ||||||
|   parameter [0:0] IS_C_INVERTED = 1'b0; |   parameter [0:0] IS_C_INVERTED = 1'b0; | ||||||
|   parameter [0:0] IS_D_INVERTED = 1'b0; |   parameter [0:0] IS_D_INVERTED = 1'b0; | ||||||
|  | @ -235,7 +237,8 @@ module FDSE (output reg Q, input C, CE, D, S); | ||||||
|   endcase endgenerate |   endcase endgenerate | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module FDCE (output reg Q, input C, CE, D, CLR); | module FDCE ((* abc_arrival=303 *) output reg Q, | ||||||
|  |              input C, CE, D, CLR); | ||||||
|   parameter [0:0] INIT = 1'b0; |   parameter [0:0] INIT = 1'b0; | ||||||
|   parameter [0:0] IS_C_INVERTED = 1'b0; |   parameter [0:0] IS_C_INVERTED = 1'b0; | ||||||
|   parameter [0:0] IS_D_INVERTED = 1'b0; |   parameter [0:0] IS_D_INVERTED = 1'b0; | ||||||
|  | @ -249,7 +252,8 @@ module FDCE (output reg Q, input C, CE, D, CLR); | ||||||
|   endcase endgenerate |   endcase endgenerate | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module FDPE (output reg Q, input C, CE, D, PRE); | module FDPE ((* abc_arrival=303 *) output reg Q, | ||||||
|  |              input C, CE, D, PRE); | ||||||
|   parameter [0:0] INIT = 1'b1; |   parameter [0:0] INIT = 1'b1; | ||||||
|   parameter [0:0] IS_C_INVERTED = 1'b0; |   parameter [0:0] IS_C_INVERTED = 1'b0; | ||||||
|   parameter [0:0] IS_D_INVERTED = 1'b0; |   parameter [0:0] IS_D_INVERTED = 1'b0; | ||||||
|  | @ -263,25 +267,29 @@ module FDPE (output reg Q, input C, CE, D, PRE); | ||||||
|   endcase endgenerate |   endcase endgenerate | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module FDRE_1 (output reg Q, input C, CE, D, R); | module FDRE_1 ((* abc_arrival=303 *) output reg Q, | ||||||
|  |                input C, CE, D, R); | ||||||
|   parameter [0:0] INIT = 1'b0; |   parameter [0:0] INIT = 1'b0; | ||||||
|   initial Q <= INIT; |   initial Q <= INIT; | ||||||
|   always @(negedge C) if (R) Q <= 1'b0; else if(CE) Q <= D; |   always @(negedge C) if (R) Q <= 1'b0; else if(CE) Q <= D; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module FDSE_1 (output reg Q, input C, CE, D, S); | module FDSE_1 ((* abc_arrival=303 *) output reg Q, | ||||||
|  |                input C, CE, D, S); | ||||||
|   parameter [0:0] INIT = 1'b1; |   parameter [0:0] INIT = 1'b1; | ||||||
|   initial Q <= INIT; |   initial Q <= INIT; | ||||||
|   always @(negedge C) if (S) Q <= 1'b1; else if(CE) Q <= D; |   always @(negedge C) if (S) Q <= 1'b1; else if(CE) Q <= D; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module FDCE_1 (output reg Q, input C, CE, D, CLR); | module FDCE_1 ((* abc_arrival=303 *) output reg Q, | ||||||
|  |                input C, CE, D, CLR); | ||||||
|   parameter [0:0] INIT = 1'b0; |   parameter [0:0] INIT = 1'b0; | ||||||
|   initial Q <= INIT; |   initial Q <= INIT; | ||||||
|   always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D; |   always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module FDPE_1 (output reg Q, input C, CE, D, PRE); | module FDPE_1 ((* abc_arrival=303 *) output reg Q, | ||||||
|  |                input C, CE, D, PRE); | ||||||
|   parameter [0:0] INIT = 1'b1; |   parameter [0:0] INIT = 1'b1; | ||||||
|   initial Q <= INIT; |   initial Q <= INIT; | ||||||
|   always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D; |   always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D; | ||||||
|  |  | ||||||
|  | @ -379,8 +379,6 @@ struct SynthXilinxPass : public ScriptPass | ||||||
| 			std::string techmap_args = "-map +/techmap.v -map +/xilinx/cells_map.v"; | 			std::string techmap_args = "-map +/techmap.v -map +/xilinx/cells_map.v"; | ||||||
| 			if (widemux > 0) | 			if (widemux > 0) | ||||||
| 				techmap_args += stringf(" -D MIN_MUX_INPUTS=%d", widemux); | 				techmap_args += stringf(" -D MIN_MUX_INPUTS=%d", widemux); | ||||||
| 			if (abc9) |  | ||||||
| 				techmap_args += " -map +/xilinx/ff_map.v"; |  | ||||||
| 			run("techmap " + techmap_args); | 			run("techmap " + techmap_args); | ||||||
| 			run("clean"); | 			run("clean"); | ||||||
| 		} | 		} | ||||||
|  | @ -411,11 +409,9 @@ struct SynthXilinxPass : public ScriptPass | ||||||
| 			//   has performed any necessary retiming
 | 			//   has performed any necessary retiming
 | ||||||
| 			if (!nosrl || help_mode) | 			if (!nosrl || help_mode) | ||||||
| 				run("shregmap -minlen 3 -init -params -enpol any_or_none", "(skip if '-nosrl')"); | 				run("shregmap -minlen 3 -init -params -enpol any_or_none", "(skip if '-nosrl')"); | ||||||
| 			std::string techmap_args = "-map +/xilinx/lut_map.v"; | 			std::string techmap_args = "-map +/xilinx/lut_map.v -map +/xilinx/ff_map.v"; | ||||||
| 			if (abc9) | 			if (abc9) | ||||||
| 				techmap_args += " -map +/xilinx/abc_unmap.v"; | 				techmap_args += " -map +/xilinx/abc_unmap.v"; | ||||||
| 			else |  | ||||||
| 				techmap_args += " -map +/xilinx/ff_map.v"; |  | ||||||
| 			run("techmap " + techmap_args); | 			run("techmap " + techmap_args); | ||||||
| 			run("dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT -ff FDSE Q INIT " | 			run("dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT -ff FDSE Q INIT " | ||||||
| 					"-ff FDRE_1 Q INIT -ff FDCE_1 Q INIT -ff FDPE_1 Q INIT -ff FDSE_1 Q INIT"); | 					"-ff FDRE_1 Q INIT -ff FDCE_1 Q INIT -ff FDPE_1 Q INIT -ff FDSE_1 Q INIT"); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue