mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	abc9 -keepff -> -dff; refactor dff operations
This commit is contained in:
		
							parent
							
								
									0e95756e96
								
							
						
					
					
						commit
						8e507bd807
					
				
					 4 changed files with 135 additions and 166 deletions
				
			
		|  | @ -82,7 +82,7 @@ struct XAigerWriter | ||||||
| 	dict<SigBit, SigBit> not_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<SigBit> ci_bits, co_bits; | 	vector<SigBit> ci_bits, co_bits; | ||||||
| 	dict<SigBit, std::tuple<SigBit,int,int>> ff_bits; | 	dict<SigBit, Cell*> ff_bits; | ||||||
| 	dict<SigBit, float> arrival_times; | 	dict<SigBit, float> arrival_times; | ||||||
| 
 | 
 | ||||||
| 	vector<pair<int, int>> aig_gates; | 	vector<pair<int, int>> aig_gates; | ||||||
|  | @ -204,7 +204,6 @@ struct XAigerWriter | ||||||
| 		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; | ||||||
| 		bool abc9_box_seen = false; | 		bool abc9_box_seen = false; | ||||||
| 		std::vector<Cell*> flop_boxes; |  | ||||||
| 
 | 
 | ||||||
| 		for (auto cell : module->selected_cells()) { | 		for (auto cell : module->selected_cells()) { | ||||||
| 			if (cell->type == "$_NOT_") | 			if (cell->type == "$_NOT_") | ||||||
|  | @ -236,14 +235,17 @@ struct XAigerWriter | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$__ABC9_FF_") | 			if (cell->type == "$__ABC9_FF_" && | ||||||
|  |                                         // The presence of an abc9_mergeability attribute indicates
 | ||||||
|  |                                         //   that we do want to pass this flop to ABC
 | ||||||
|  |                                         cell->attributes.count("\\abc9_mergeability")) | ||||||
| 			{ | 			{ | ||||||
| 				SigBit D = sigmap(cell->getPort("\\D").as_bit()); | 				SigBit D = sigmap(cell->getPort("\\D").as_bit()); | ||||||
| 				SigBit Q = sigmap(cell->getPort("\\Q").as_bit()); | 				SigBit Q = sigmap(cell->getPort("\\Q").as_bit()); | ||||||
| 				unused_bits.erase(D); | 				unused_bits.erase(D); | ||||||
| 				undriven_bits.erase(Q); | 				undriven_bits.erase(Q); | ||||||
| 				alias_map[Q] = D; | 				alias_map[Q] = D; | ||||||
| 				auto r = ff_bits.insert(std::make_pair(D, std::make_tuple(Q, 0, 2))); | 				auto r YS_ATTRIBUTE(unused) = ff_bits.insert(std::make_pair(D, cell)); | ||||||
| 				log_assert(r.second); | 				log_assert(r.second); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
|  | @ -252,14 +254,25 @@ struct XAigerWriter | ||||||
| 			if (inst_module) { | 			if (inst_module) { | ||||||
| 				bool abc9_box = inst_module->attributes.count("\\abc9_box_id"); | 				bool abc9_box = inst_module->attributes.count("\\abc9_box_id"); | ||||||
| 				bool abc9_flop = inst_module->get_bool_attribute("\\abc9_flop"); | 				bool abc9_flop = inst_module->get_bool_attribute("\\abc9_flop"); | ||||||
| 				// The lack of an abc9_mergeability attribute indicates that
 | 				if (abc9_box && cell->get_bool_attribute("\\abc9_keep")) | ||||||
| 				//   we do want to keep this flop, so do not treat it as a box
 |  | ||||||
| 				if (abc9_flop && !cell->attributes.count("\\abc9_mergeability")) |  | ||||||
| 					abc9_box = false; | 					abc9_box = false; | ||||||
| 
 | 
 | ||||||
| 				for (const auto &conn : cell->connections()) { | 				for (const auto &conn : cell->connections()) { | ||||||
| 					auto port_wire = inst_module->wire(conn.first); | 					auto port_wire = inst_module->wire(conn.first); | ||||||
| 
 | 
 | ||||||
|  | 					if (abc9_box) { | ||||||
|  | 						// Ignore inout for the sake of topographical ordering
 | ||||||
|  | 						if (port_wire->port_input && !port_wire->port_output) | ||||||
|  | 							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); | ||||||
|  | 
 | ||||||
|  | 						if (!abc9_flop) | ||||||
|  | 							continue; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
| 					if (port_wire->port_output) { | 					if (port_wire->port_output) { | ||||||
| 						int arrival = 0; | 						int arrival = 0; | ||||||
| 						auto it = port_wire->attributes.find("\\abc9_arrival"); | 						auto it = port_wire->attributes.find("\\abc9_arrival"); | ||||||
|  | @ -272,25 +285,11 @@ struct XAigerWriter | ||||||
| 							for (auto bit : sigmap(conn.second)) | 							for (auto bit : sigmap(conn.second)) | ||||||
| 								arrival_times[bit] = arrival; | 								arrival_times[bit] = arrival; | ||||||
| 					} | 					} | ||||||
| 
 |  | ||||||
| 					if (abc9_box) { |  | ||||||
| 						// Ignore inout for the sake of topographical ordering
 |  | ||||||
| 						if (port_wire->port_input && !port_wire->port_output) |  | ||||||
| 							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); |  | ||||||
| 					} |  | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				if (abc9_box) { | 				if (abc9_box) { | ||||||
| 					abc9_box_seen = true; | 					abc9_box_seen = true; | ||||||
| 
 |  | ||||||
| 					toposort.node(cell->name); | 					toposort.node(cell->name); | ||||||
| 
 |  | ||||||
| 					if (abc9_flop) |  | ||||||
| 						flop_boxes.push_back(cell); |  | ||||||
| 					continue; | 					continue; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | @ -321,61 +320,6 @@ struct XAigerWriter | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (abc9_box_seen) { | 		if (abc9_box_seen) { | ||||||
| 			dict<IdString, std::pair<IdString,int>> flop_q; |  | ||||||
| 			for (auto cell : flop_boxes) { |  | ||||||
| 				auto r = flop_q.insert(std::make_pair(cell->type, std::make_pair(IdString(), 0))); |  | ||||||
| 				SigBit d; |  | ||||||
| 				if (r.second) { |  | ||||||
| 					for (const auto &conn : cell->connections()) { |  | ||||||
| 						if (!conn.second.is_bit()) |  | ||||||
| 							continue; |  | ||||||
| 						d = conn.second; |  | ||||||
| 						if (!ff_bits.count(d)) |  | ||||||
| 							continue; |  | ||||||
| 
 |  | ||||||
| 						r.first->second.first = conn.first; |  | ||||||
| 						Module *inst_module = module->design->module(cell->type); |  | ||||||
| 						Wire *wire = inst_module->wire(conn.first); |  | ||||||
| 						log_assert(wire); |  | ||||||
| 						auto jt = wire->attributes.find("\\abc9_arrival"); |  | ||||||
| 						if (jt != wire->attributes.end()) { |  | ||||||
| 							if (jt->second.flags != 0) |  | ||||||
| 								log_error("Attribute 'abc9_arrival' on port '%s' of module '%s' is not an integer.\n", log_id(wire), log_id(cell->type)); |  | ||||||
| 							r.first->second.second = jt->second.as_int(); |  | ||||||
| 						} |  | ||||||
| 						log_assert(d == sigmap(d)); |  | ||||||
| 						break; |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 				else |  | ||||||
| 					d = cell->getPort(r.first->second.first); |  | ||||||
| 
 |  | ||||||
| 				auto &rhs = ff_bits.at(d); |  | ||||||
| 
 |  | ||||||
| 				auto it = cell->attributes.find(ID(abc9_mergeability)); |  | ||||||
| 				log_assert(it != cell->attributes.end()); |  | ||||||
| 				std::get<1>(rhs) = it->second.as_int(); |  | ||||||
| 				cell->attributes.erase(it); |  | ||||||
| 
 |  | ||||||
| 				it = cell->attributes.find(ID(abc9_init)); |  | ||||||
| 				log_assert(it != cell->attributes.end()); |  | ||||||
| 				log_assert(GetSize(it->second) == 1); |  | ||||||
| 				if (it->second[0] == State::S1) |  | ||||||
| 					std::get<2>(rhs) = 1; |  | ||||||
| 				else if (it->second[0] == State::S0) |  | ||||||
| 					std::get<2>(rhs) = 0; |  | ||||||
| 				else { |  | ||||||
| 					log_assert(it->second[0] == State::Sx); |  | ||||||
| 					std::get<2>(rhs) = 0; |  | ||||||
| 				} |  | ||||||
| 				cell->attributes.erase(it); |  | ||||||
| 
 |  | ||||||
| 				const SigBit &q = std::get<0>(rhs); |  | ||||||
| 				auto arrival = r.first->second.second; |  | ||||||
| 				if (arrival) |  | ||||||
| 					arrival_times[q] = arrival; |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			for (auto &it : bit_users) | 			for (auto &it : bit_users) | ||||||
| 				if (bit_drivers.count(it.first)) | 				if (bit_drivers.count(it.first)) | ||||||
| 					for (auto driver_cell : bit_drivers.at(it.first)) | 					for (auto driver_cell : bit_drivers.at(it.first)) | ||||||
|  | @ -501,11 +445,11 @@ struct XAigerWriter | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				// Connect <cell>.$abc9_currQ (inserted by abc9_map.v) as an input to the flop box
 | 				// Connect <cell>.abc9_ff.Q (inserted by abc9_map.v) as the last input to the flop box
 | ||||||
| 				if (box_module->get_bool_attribute("\\abc9_flop")) { | 				if (box_module->get_bool_attribute("\\abc9_flop")) { | ||||||
| 					SigSpec rhs = module->wire(stringf("%s.$abc9_currQ", cell->name.c_str())); | 					SigSpec rhs = module->wire(stringf("%s.abc9_ff.Q", cell->name.c_str())); | ||||||
| 					if (rhs.empty()) | 					if (rhs.empty()) | ||||||
| 						log_error("'%s.$abc9_currQ' is not a wire present in module '%s'.\n", log_id(cell), log_id(module)); | 						log_error("'%s.abc9_ff.Q' is not a wire present in module '%s'.\n", log_id(cell), log_id(module)); | ||||||
| 
 | 
 | ||||||
| 					for (auto b : rhs) { | 					for (auto b : rhs) { | ||||||
| 						SigBit I = sigmap(b); | 						SigBit I = sigmap(b); | ||||||
|  | @ -553,7 +497,8 @@ struct XAigerWriter | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for (const auto &i : ff_bits) { | 		for (const auto &i : ff_bits) { | ||||||
| 			const SigBit &q = std::get<0>(i.second); | 			const Cell *cell = i.second; | ||||||
|  | 			const SigBit &q = sigmap(cell->getPort("\\Q")); | ||||||
| 			aig_m++, aig_i++; | 			aig_m++, aig_i++; | ||||||
| 			log_assert(!aig_map.count(q)); | 			log_assert(!aig_map.count(q)); | ||||||
| 			aig_map[q] = 2*aig_m; | 			aig_map[q] = 2*aig_m; | ||||||
|  | @ -742,7 +687,7 @@ struct XAigerWriter | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				// For flops only, create an extra 1-bit input that drives a new wire
 | 				// For flops only, create an extra 1-bit input that drives a new wire
 | ||||||
| 				//   called "<cell>.$abc9_currQ" that is used below
 | 				//   called "<cell>.abc9_ff.Q" that is used below
 | ||||||
| 				if (box_module->get_bool_attribute("\\abc9_flop")) { | 				if (box_module->get_bool_attribute("\\abc9_flop")) { | ||||||
| 					log_assert(holes_cell); | 					log_assert(holes_cell); | ||||||
| 
 | 
 | ||||||
|  | @ -754,7 +699,8 @@ struct XAigerWriter | ||||||
| 						holes_wire->port_id = port_id++; | 						holes_wire->port_id = port_id++; | ||||||
| 						holes_module->ports.push_back(holes_wire->name); | 						holes_module->ports.push_back(holes_wire->name); | ||||||
| 					} | 					} | ||||||
| 					Wire *w = holes_module->addWire(stringf("%s.$abc9_currQ", cell->name.c_str())); | 					Wire *w = holes_module->addWire(stringf("%s.abc9_ff.Q", cell->name.c_str())); | ||||||
|  | 					log_assert(w); | ||||||
| 					holes_module->connect(w, holes_wire); | 					holes_module->connect(w, holes_wire); | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
|  | @ -774,13 +720,25 @@ struct XAigerWriter | ||||||
| 			write_s_buffer(ff_bits.size()); | 			write_s_buffer(ff_bits.size()); | ||||||
| 
 | 
 | ||||||
| 			for (const auto &i : ff_bits) { | 			for (const auto &i : ff_bits) { | ||||||
| 				const SigBit &q = std::get<0>(i.second); | 				const SigBit &d = i.first; | ||||||
| 				int mergeability = std::get<1>(i.second); | 				const Cell *cell = i.second; | ||||||
|  | 
 | ||||||
|  | 				int mergeability = cell->attributes.at(ID(abc9_mergeability)).as_int(); | ||||||
| 				log_assert(mergeability > 0); | 				log_assert(mergeability > 0); | ||||||
| 				write_r_buffer(mergeability); | 				write_r_buffer(mergeability); | ||||||
| 				int init = std::get<2>(i.second); | 
 | ||||||
| 				write_s_buffer(init); | 				Const init = cell->attributes.at(ID(abc9_init)); | ||||||
| 				write_i_buffer(arrival_times.at(q, 0)); | 				log_assert(GetSize(init) == 1); | ||||||
|  | 				if (init == State::S1) | ||||||
|  | 					write_s_buffer(1); | ||||||
|  | 				else if (init == State::S0) | ||||||
|  | 					write_s_buffer(0); | ||||||
|  | 				else { | ||||||
|  | 					log_assert(init == State::Sx); | ||||||
|  | 					write_s_buffer(0); | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				write_i_buffer(arrival_times.at(d, 0)); | ||||||
| 				//write_o_buffer(0);
 | 				//write_o_buffer(0);
 | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | @ -833,9 +791,9 @@ struct XAigerWriter | ||||||
| 						log_assert(pos != std::string::npos); | 						log_assert(pos != std::string::npos); | ||||||
| 						IdString driver = Q.wire->name.substr(0, pos); | 						IdString driver = Q.wire->name.substr(0, pos); | ||||||
| 						// And drive the signal that was previously driven by "DFF.Q" (typically
 | 						// And drive the signal that was previously driven by "DFF.Q" (typically
 | ||||||
| 						//   used to implement clock-enable functionality) with the "<cell>.$abc9_currQ"
 | 						//   used to implement clock-enable functionality) with the "<cell>.abc9_ff.Q"
 | ||||||
| 						//   wire (which itself is driven an input port) we inserted above
 | 						//   wire (which itself is driven an input port) we inserted above
 | ||||||
| 						Wire *currQ = holes_module->wire(stringf("%s.$abc9_currQ", driver.c_str())); | 						Wire *currQ = holes_module->wire(stringf("%s.abc9_ff.Q", driver.c_str())); | ||||||
| 						log_assert(currQ); | 						log_assert(currQ); | ||||||
| 						holes_module->connect(Q, currQ); | 						holes_module->connect(Q, currQ); | ||||||
| 						continue; | 						continue; | ||||||
|  |  | ||||||
|  | @ -249,7 +249,7 @@ struct abc9_output_filter | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string script_file, std::string exe_file, | void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string script_file, std::string exe_file, | ||||||
| 		bool cleanup, vector<int> lut_costs, bool keepff, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, | 		bool cleanup, vector<int> lut_costs, bool dff, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode, | ||||||
| 		bool show_tempdir, std::string box_file, std::string lut_file, | 		bool show_tempdir, std::string box_file, std::string lut_file, | ||||||
| 		std::string wire_delay, bool nomfs | 		std::string wire_delay, bool nomfs | ||||||
| ) | ) | ||||||
|  | @ -347,7 +347,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip | ||||||
| 		buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym"); | 		buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym"); | ||||||
| 		log_assert(!design->module(ID($__abc9__))); | 		log_assert(!design->module(ID($__abc9__))); | ||||||
| 		{ | 		{ | ||||||
| 			AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); | 			AigerReader reader(design, ifs, ID($__abc9__), "" /* clk_name */, /*buffer.c_str()*/ "" /* map_filename */, true /* wideports */); | ||||||
| 			reader.parse_xaiger(); | 			reader.parse_xaiger(); | ||||||
| 		} | 		} | ||||||
| 		ifs.close(); | 		ifs.close(); | ||||||
|  | @ -430,7 +430,13 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip | ||||||
| 			if (jt == abc9_box.end()) | 			if (jt == abc9_box.end()) | ||||||
| 				jt = abc9_box.insert(std::make_pair(cell->type, box_module && box_module->attributes.count(ID(abc9_box_id)))).first; | 				jt = abc9_box.insert(std::make_pair(cell->type, box_module && box_module->attributes.count(ID(abc9_box_id)))).first; | ||||||
| 			if (jt->second) { | 			if (jt->second) { | ||||||
| 				if (!keepff || !box_module->get_bool_attribute("\\abc9_flop")) | 				if (box_module->get_bool_attribute("\\abc9_flop")) { | ||||||
|  | 					if (dff) | ||||||
|  | 						boxes.emplace_back(cell); | ||||||
|  | 					else | ||||||
|  | 						box_module->set_bool_attribute("\\abc9_keep", false); | ||||||
|  | 				} | ||||||
|  | 				else | ||||||
| 					boxes.emplace_back(cell); | 					boxes.emplace_back(cell); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | @ -795,9 +801,9 @@ struct Abc9Pass : public Pass { | ||||||
| 		log("        generate netlist using luts. Use the specified costs for luts with 1,\n"); | 		log("        generate netlist using luts. Use the specified costs for luts with 1,\n"); | ||||||
| 		log("        2, 3, .. inputs.\n"); | 		log("        2, 3, .. inputs.\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("    -keepff\n"); | 		log("    -dff\n"); | ||||||
| 		log("        do not represent (* abc9_flop *) modules as boxes (and thus do not perform\n"); | 		log("        also pass $_ABC9_FF_ cells through ABC. modules with many clock domains\n"); | ||||||
| 		log("        any form of sequential synthesis).\n"); | 		log("        are marked as such and automatically partitioned by ABC.\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("    -nocleanup\n"); | 		log("    -nocleanup\n"); | ||||||
| 		log("        when this option is used, the temporary files created by this pass\n"); | 		log("        when this option is used, the temporary files created by this pass\n"); | ||||||
|  | @ -837,7 +843,7 @@ struct Abc9Pass : public Pass { | ||||||
| #endif | #endif | ||||||
| 		std::string script_file, clk_str, box_file, lut_file; | 		std::string script_file, clk_str, box_file, lut_file; | ||||||
| 		std::string delay_target, lutin_shared = "-S 1", wire_delay; | 		std::string delay_target, lutin_shared = "-S 1", wire_delay; | ||||||
| 		bool fast_mode = false, keepff = false, cleanup = true; | 		bool fast_mode = false, dff = false, cleanup = true; | ||||||
| 		bool show_tempdir = false; | 		bool show_tempdir = false; | ||||||
| 		bool nomfs = false; | 		bool nomfs = false; | ||||||
| 		vector<int> lut_costs; | 		vector<int> lut_costs; | ||||||
|  | @ -928,8 +934,8 @@ struct Abc9Pass : public Pass { | ||||||
| 				fast_mode = true; | 				fast_mode = true; | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (arg == "-keepff") { | 			if (arg == "-dff") { | ||||||
| 				keepff = true; | 				dff = true; | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (arg == "-nocleanup") { | 			if (arg == "-nocleanup") { | ||||||
|  | @ -985,16 +991,14 @@ struct Abc9Pass : public Pass { | ||||||
| 			typedef SigSpec clkdomain_t; | 			typedef SigSpec clkdomain_t; | ||||||
| 			dict<clkdomain_t, int> clk_to_mergeability; | 			dict<clkdomain_t, int> clk_to_mergeability; | ||||||
| 
 | 
 | ||||||
| 
 | 			if (dff) | ||||||
| 			if (!keepff) |  | ||||||
| 				for (auto cell : module->selected_cells()) { | 				for (auto cell : module->selected_cells()) { | ||||||
| 					auto inst_module = design->module(cell->type); | 					if (cell->type != "$__ABC9_FF_") | ||||||
| 					if (!inst_module || !inst_module->get_bool_attribute("\\abc9_flop")) |  | ||||||
| 						continue; | 						continue; | ||||||
| 
 | 
 | ||||||
| 					Wire *abc9_clock_wire = module->wire(stringf("%s.$abc9_clock", cell->name.c_str())); | 					Wire *abc9_clock_wire = module->wire(stringf("%s.clock", cell->name.c_str())); | ||||||
| 					if (abc9_clock_wire == NULL) | 					if (abc9_clock_wire == NULL) | ||||||
| 						log_error("'%s$abc9_clock' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); | 						log_error("'%s.clock' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); | ||||||
| 					SigSpec abc9_clock = assign_map(abc9_clock_wire); | 					SigSpec abc9_clock = assign_map(abc9_clock_wire); | ||||||
| 
 | 
 | ||||||
| 					clkdomain_t key(abc9_clock); | 					clkdomain_t key(abc9_clock); | ||||||
|  | @ -1003,19 +1007,26 @@ struct Abc9Pass : public Pass { | ||||||
| 					auto r2 YS_ATTRIBUTE(unused) = cell->attributes.insert(std::make_pair(ID(abc9_mergeability), r.first->second)); | 					auto r2 YS_ATTRIBUTE(unused) = cell->attributes.insert(std::make_pair(ID(abc9_mergeability), r.first->second)); | ||||||
| 					log_assert(r2.second); | 					log_assert(r2.second); | ||||||
| 
 | 
 | ||||||
| 					Wire *abc9_init_wire = module->wire(stringf("%s.$abc9_init", cell->name.c_str())); | 					Wire *abc9_init_wire = module->wire(stringf("%s.init", cell->name.c_str())); | ||||||
| 					if (abc9_init_wire == NULL) | 					if (abc9_init_wire == NULL) | ||||||
| 						log_error("'%s.$abc9_init' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); | 						log_error("'%s.init' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); | ||||||
| 					log_assert(GetSize(abc9_init_wire) == 1); | 					log_assert(GetSize(abc9_init_wire) == 1); | ||||||
| 					SigSpec abc9_init = assign_map(abc9_init_wire); | 					SigSpec abc9_init = assign_map(abc9_init_wire); | ||||||
| 					if (!abc9_init.is_fully_const()) | 					if (!abc9_init.is_fully_const()) | ||||||
| 						log_error("'%s.$abc9_init' is not a constant wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); | 						log_error("'%s.init' is not a constant wire present in module '%s'.\n", cell->name.c_str(), log_id(module)); | ||||||
| 					r2 = cell->attributes.insert(std::make_pair(ID(abc9_init), abc9_init.as_const())); | 					r2 = cell->attributes.insert(std::make_pair(ID(abc9_init), abc9_init.as_const())); | ||||||
| 					log_assert(r2.second); | 					log_assert(r2.second); | ||||||
| 				} | 				} | ||||||
|  | 			else | ||||||
|  | 				for (auto cell : module->selected_cells()) { | ||||||
|  | 					auto inst_module = design->module(cell->type); | ||||||
|  | 					if (!inst_module || !inst_module->get_bool_attribute("\\abc9_flop")) | ||||||
|  | 						continue; | ||||||
|  | 					cell->set_bool_attribute("\\abc9_keep"); | ||||||
|  | 				} | ||||||
| 
 | 
 | ||||||
| 			design->selected_active_module = module->name.str(); | 			design->selected_active_module = module->name.str(); | ||||||
| 			abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, keepff, | 			abc9_module(design, module, script_file, exe_file, cleanup, lut_costs, dff, | ||||||
| 					delay_target, lutin_shared, fast_mode, show_tempdir, | 					delay_target, lutin_shared, fast_mode, show_tempdir, | ||||||
| 					box_file, lut_file, wire_delay, nomfs); | 					box_file, lut_file, wire_delay, nomfs); | ||||||
| 			design->selected_active_module.clear(); | 			design->selected_active_module.clear(); | ||||||
|  |  | ||||||
|  | @ -51,29 +51,29 @@ | ||||||
| //                ||                  || | //                ||                  || | ||||||
| //                ||      /\/\/\/\    || | //                ||      /\/\/\/\    || | ||||||
| //           D  -->>-----<        >   || | //           D  -->>-----<        >   || | ||||||
| //           R  -->>-----<  Comb. >   ||        +----------+ | //           R  -->>-----<  Comb. >   ||        +-----------+ | ||||||
| //          CE  -->>-----<  logic >--->>-- $Q --|$__ABC_FF_|--+-->> Q | //          CE  -->>-----<  logic >--->>-- $Q --|$__ABC9_FF_|--+-->> Q | ||||||
| // $abc9_currQ +-->>-----<        >   ||        +----------+  | | //   abc9_ff.Q +-->>-----<        >   ||        +-----------+  | | ||||||
| //             |  ||      \/\/\/\/    ||                       | | //             |  ||      \/\/\/\/    ||                       | | ||||||
| //             |  ||                  ||                       | | //             |  ||                  ||                       | | ||||||
| //             |  ++==================++                       | | //             |  ++==================++                       | | ||||||
| //             |                                               | | //             |                                               | | ||||||
| //             +----------------------------------------------+ | //             +-----------------------------------------------+ | ||||||
| // | // | ||||||
| // The purpose of the following FD* rules are to wrap the flop with: | // The purpose of the following FD* rules are to wrap the flop with: | ||||||
| // (a) a special $__ABC9_FF_ in front of the FD*'s output, indicating to abc9 | // (a) a special $__ABC9_FF_ in front of the FD*'s output, indicating to abc9 | ||||||
| //     the connectivity of its basic D-Q flop | //     the connectivity of its basic D-Q flop | ||||||
| // (b) an optional $__ABC9_ASYNC_ cell in front of $__ABC_FF_'s output to | // (b) an optional $__ABC9_ASYNC_ cell in front of $__ABC_FF_'s output to | ||||||
| //     capture asynchronous behaviour | //     capture asynchronous behaviour | ||||||
| // (c) a special _TECHMAP_REPLACE_.$abc9_clock wire to capture its clock | // (c) a special _TECHMAP_REPLACE_.abc9_ff.clock wire to capture its clock | ||||||
| //     domain and polarity (used when partitioning the module so that `abc9' only | //     domain and polarity (used when partitioning the module so that `abc9' only | ||||||
| //     performs sequential synthesis (with reachability analysis) correctly on | //     performs sequential synthesis (with reachability analysis) correctly on | ||||||
| //     one domain at a time) and also used to infer the optional delay target | //     one domain at a time) and also used to infer the optional delay target | ||||||
| //     from the (* abc9_clock_period = %d *) attribute attached to any wire | //     from the (* abc9_clock_period = %d *) attribute attached to any wire | ||||||
| //     within | //     within | ||||||
| // (d) a special _TECHMAP_REPLACE_.$abc9_init wire to encode the flop's initial | // (d) a special _TECHMAP_REPLACE_.abc9_ff.init wire to encode the flop's initial | ||||||
| //     state | //     state | ||||||
| // (e) a special _TECHMAP_REPLACE_.$abc9_currQ wire that will be used for feedback | // (e) a special _TECHMAP_REPLACE_.abc9_ff.Q wire that will be used for feedback | ||||||
| //     into the (combinatorial) FD* cell to facilitate clock-enable behaviour | //     into the (combinatorial) FD* cell to facilitate clock-enable behaviour | ||||||
| // | // | ||||||
| // In order to perform sequential synthesis, `abc9' also requires that | // In order to perform sequential synthesis, `abc9' also requires that | ||||||
|  | @ -108,12 +108,12 @@ module FDRE (output Q, input C, CE, D, R); | ||||||
|     ); |     ); | ||||||
|   end |   end | ||||||
|   endgenerate |   endgenerate | ||||||
|   $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ)); |   $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ)); | ||||||
| 
 | 
 | ||||||
|   // Special signals |   // Special signals | ||||||
|   wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; |   wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED}; | ||||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; |   wire [0:0] abc9_ff.init = 1'b0; | ||||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; |   wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ; | ||||||
| endmodule | endmodule | ||||||
| module FDRE_1 (output Q, input C, CE, D, R); | module FDRE_1 (output Q, input C, CE, D, R); | ||||||
|   parameter [0:0] INIT = 1'b0; |   parameter [0:0] INIT = 1'b0; | ||||||
|  | @ -135,12 +135,12 @@ module FDRE_1 (output Q, input C, CE, D, R); | ||||||
|     ); |     ); | ||||||
|   end |   end | ||||||
|   endgenerate |   endgenerate | ||||||
|   $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ)); |   $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ)); | ||||||
| 
 | 
 | ||||||
|   // Special signals |   // Special signals | ||||||
|   wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; |   wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */}; | ||||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; |   wire [0:0] abc9_ff.init = 1'b0; | ||||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; |   wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module FDSE (output Q, input C, CE, D, S); | module FDSE (output Q, input C, CE, D, S); | ||||||
|  | @ -171,12 +171,12 @@ module FDSE (output Q, input C, CE, D, S); | ||||||
|       .D(D), .Q($Q), .C(C), .CE(CE), .S(S) |       .D(D), .Q($Q), .C(C), .CE(CE), .S(S) | ||||||
|     ); |     ); | ||||||
|   end endgenerate |   end endgenerate | ||||||
|   $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ)); |   $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ)); | ||||||
| 
 | 
 | ||||||
|   // Special signals |   // Special signals | ||||||
|   wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; |   wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED}; | ||||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; |   wire [0:0] abc9_ff.init = 1'b0; | ||||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; |   wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ; | ||||||
| endmodule | endmodule | ||||||
| module FDSE_1 (output Q, input C, CE, D, S); | module FDSE_1 (output Q, input C, CE, D, S); | ||||||
|   parameter [0:0] INIT = 1'b1; |   parameter [0:0] INIT = 1'b1; | ||||||
|  | @ -197,12 +197,12 @@ module FDSE_1 (output Q, input C, CE, D, S); | ||||||
|       .D(D), .Q($Q), .C(C), .CE(CE), .S(S) |       .D(D), .Q($Q), .C(C), .CE(CE), .S(S) | ||||||
|     ); |     ); | ||||||
|   end endgenerate |   end endgenerate | ||||||
|   $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ)); |   $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ)); | ||||||
| 
 | 
 | ||||||
|   // Special signals |   // Special signals | ||||||
|   wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; |   wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */}; | ||||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; |   wire [0:0] abc9_ff.init = 1'b0; | ||||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; |   wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module FDCE (output Q, input C, CE, D, CLR); | module FDCE (output Q, input C, CE, D, CLR); | ||||||
|  | @ -210,7 +210,7 @@ module FDCE (output Q, input C, CE, D, CLR); | ||||||
|   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; | ||||||
|   parameter [0:0] IS_CLR_INVERTED = 1'b0; |   parameter [0:0] IS_CLR_INVERTED = 1'b0; | ||||||
|   wire QQ, $Q, $abc9_currQ; |   wire QQ, $Q, $QQ; | ||||||
|   generate if (INIT == 1'b1) begin |   generate if (INIT == 1'b1) begin | ||||||
|     assign Q = ~QQ; |     assign Q = ~QQ; | ||||||
|     FDPE #( |     FDPE #( | ||||||
|  | @ -227,7 +227,7 @@ module FDCE (output Q, input C, CE, D, CLR); | ||||||
|                                             //     $__ABC9_ASYNC1 below |                                             //     $__ABC9_ASYNC1 below | ||||||
|     ); |     ); | ||||||
|     // Since this is an async flop, async behaviour is dealt with here |     // Since this is an async flop, async behaviour is dealt with here | ||||||
|     $__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ)); |     $__ABC9_ASYNC1 abc_async (.A($QQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ)); | ||||||
|   end |   end | ||||||
|   else begin |   else begin | ||||||
|     assign Q = QQ; |     assign Q = QQ; | ||||||
|  | @ -245,18 +245,18 @@ module FDCE (output Q, input C, CE, D, CLR); | ||||||
|                                            //     $__ABC9_ASYNC0 below |                                            //     $__ABC9_ASYNC0 below | ||||||
|     ); |     ); | ||||||
|     // Since this is an async flop, async behaviour is dealt with here |     // Since this is an async flop, async behaviour is dealt with here | ||||||
|     $__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ)); |     $__ABC9_ASYNC0 abc_async (.A($QQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ)); | ||||||
|   end endgenerate |   end endgenerate | ||||||
|   $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ)); |   $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ)); | ||||||
| 
 | 
 | ||||||
|   // Special signals |   // Special signals | ||||||
|   wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; |   wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED}; | ||||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; |   wire [0:0] abc9_ff.init = 1'b0; | ||||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; |   wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ; | ||||||
| endmodule | endmodule | ||||||
| module FDCE_1 (output Q, input C, CE, D, CLR); | module FDCE_1 (output Q, input C, CE, D, CLR); | ||||||
|   parameter [0:0] INIT = 1'b0; |   parameter [0:0] INIT = 1'b0; | ||||||
|   wire QQ, $Q, $abc9_currQ; |   wire QQ, $Q, $QQ; | ||||||
|   generate if (INIT == 1'b1) begin |   generate if (INIT == 1'b1) begin | ||||||
|     assign Q = ~QQ; |     assign Q = ~QQ; | ||||||
|     FDPE_1 #( |     FDPE_1 #( | ||||||
|  | @ -269,7 +269,7 @@ module FDCE_1 (output Q, input C, CE, D, CLR); | ||||||
|                                             //     behaviour is captured by |                                             //     behaviour is captured by | ||||||
|                                             //     $__ABC9_ASYNC1 below |                                             //     $__ABC9_ASYNC1 below | ||||||
|     ); |     ); | ||||||
|     $__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(CLR), .Y(QQ)); |     $__ABC9_ASYNC1 abc_async (.A($QQ), .S(CLR), .Y(QQ)); | ||||||
|   end |   end | ||||||
|   else begin |   else begin | ||||||
|     assign Q = QQ; |     assign Q = QQ; | ||||||
|  | @ -283,14 +283,14 @@ module FDCE_1 (output Q, input C, CE, D, CLR); | ||||||
|                                            //     behaviour is captured by |                                            //     behaviour is captured by | ||||||
|                                            //     $__ABC9_ASYNC0 below |                                            //     $__ABC9_ASYNC0 below | ||||||
|     ); |     ); | ||||||
|     $__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(CLR), .Y(QQ)); |     $__ABC9_ASYNC0 abc_async (.A($QQ), .S(CLR), .Y(QQ)); | ||||||
|   end endgenerate |   end endgenerate | ||||||
|   $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ)); |   $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ)); | ||||||
| 
 | 
 | ||||||
|   // Special signals |   // Special signals | ||||||
|   wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; |   wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */}; | ||||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; |   wire [0:0] abc9_ff.init = 1'b0; | ||||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; |   wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module FDPE (output Q, input C, CE, D, PRE); | module FDPE (output Q, input C, CE, D, PRE); | ||||||
|  | @ -298,7 +298,7 @@ module FDPE (output Q, input C, CE, D, PRE); | ||||||
|   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; | ||||||
|   parameter [0:0] IS_PRE_INVERTED = 1'b0; |   parameter [0:0] IS_PRE_INVERTED = 1'b0; | ||||||
|   wire QQ, $Q, $abc9_currQ; |   wire QQ, $Q, $QQ; | ||||||
|   generate if (INIT == 1'b1) begin |   generate if (INIT == 1'b1) begin | ||||||
|     assign Q = ~QQ; |     assign Q = ~QQ; | ||||||
|     FDCE #( |     FDCE #( | ||||||
|  | @ -314,7 +314,7 @@ module FDPE (output Q, input C, CE, D, PRE); | ||||||
|                                             //     behaviour is captured by |                                             //     behaviour is captured by | ||||||
|                                             //     $__ABC9_ASYNC0 below |                                             //     $__ABC9_ASYNC0 below | ||||||
|     ); |     ); | ||||||
|     $__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ)); |     $__ABC9_ASYNC0 abc_async (.A($QQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ)); | ||||||
|   end |   end | ||||||
|   else begin |   else begin | ||||||
|     assign Q = QQ; |     assign Q = QQ; | ||||||
|  | @ -331,18 +331,18 @@ module FDPE (output Q, input C, CE, D, PRE); | ||||||
|                                            //     behaviour is captured by |                                            //     behaviour is captured by | ||||||
|                                            //     $__ABC9_ASYNC1 below |                                            //     $__ABC9_ASYNC1 below | ||||||
|     ); |     ); | ||||||
|     $__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ)); |     $__ABC9_ASYNC1 abc_async (.A($QQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ)); | ||||||
|   end endgenerate |   end endgenerate | ||||||
|   $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ)); |   $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ)); | ||||||
| 
 | 
 | ||||||
|   // Special signals |   // Special signals | ||||||
|   wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; |   wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED}; | ||||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; |   wire [0:0] abc9_ff.init = 1'b0; | ||||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; |   wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ; | ||||||
| endmodule | endmodule | ||||||
| module FDPE_1 (output Q, input C, CE, D, PRE); | module FDPE_1 (output Q, input C, CE, D, PRE); | ||||||
|   parameter [0:0] INIT = 1'b1; |   parameter [0:0] INIT = 1'b1; | ||||||
|   wire QQ, $Q, $abc9_currQ; |   wire QQ, $Q, $QQ; | ||||||
|   generate if (INIT == 1'b1) begin |   generate if (INIT == 1'b1) begin | ||||||
|     assign Q = ~QQ; |     assign Q = ~QQ; | ||||||
|     FDCE_1 #( |     FDCE_1 #( | ||||||
|  | @ -355,7 +355,7 @@ module FDPE_1 (output Q, input C, CE, D, PRE); | ||||||
|                                             //     behaviour is captured by |                                             //     behaviour is captured by | ||||||
|                                             //     $__ABC9_ASYNC0 below |                                             //     $__ABC9_ASYNC0 below | ||||||
|     ); |     ); | ||||||
|     $__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(PRE), .Y(QQ)); |     $__ABC9_ASYNC0 abc_async (.A($QQ), .S(PRE), .Y(QQ)); | ||||||
|   end |   end | ||||||
|   else begin |   else begin | ||||||
|     assign Q = QQ; |     assign Q = QQ; | ||||||
|  | @ -369,14 +369,14 @@ module FDPE_1 (output Q, input C, CE, D, PRE); | ||||||
|                                            //     behaviour is captured by |                                            //     behaviour is captured by | ||||||
|                                            //     $__ABC9_ASYNC1 below |                                            //     $__ABC9_ASYNC1 below | ||||||
|     ); |     ); | ||||||
|     $__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(PRE), .Y(QQ)); |     $__ABC9_ASYNC1 abc_async (.A($QQ), .S(PRE), .Y(QQ)); | ||||||
|   end endgenerate |   end endgenerate | ||||||
|   $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ)); |   $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ)); | ||||||
| 
 | 
 | ||||||
|   // Special signals |   // Special signals | ||||||
|   wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; |   wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */}; | ||||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; |   wire [0:0] abc9_ff.init = 1'b0; | ||||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; |   wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ; | ||||||
| endmodule | endmodule | ||||||
| `endif | `endif | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -108,7 +108,7 @@ struct SynthXilinxPass : public ScriptPass | ||||||
| 		log("        flatten design before synthesis\n"); | 		log("        flatten design before synthesis\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("    -dff\n"); | 		log("    -dff\n"); | ||||||
| 		log("        enable sequential synthesis with 'abc9'\n"); | 		log("        run 'abc9' with -dff option\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("    -retime\n"); | 		log("    -retime\n"); | ||||||
| 		log("        run 'abc' with -dff option\n"); | 		log("        run 'abc' with -dff option\n"); | ||||||
|  | @ -559,8 +559,8 @@ struct SynthXilinxPass : public ScriptPass | ||||||
| 					abc9_opts += " -lut +/xilinx/abc9_xc7_nowide.lut"; | 					abc9_opts += " -lut +/xilinx/abc9_xc7_nowide.lut"; | ||||||
| 				else | 				else | ||||||
| 					abc9_opts += " -lut +/xilinx/abc9_xc7.lut"; | 					abc9_opts += " -lut +/xilinx/abc9_xc7.lut"; | ||||||
| 				if (!dff_mode) | 				if (dff_mode) | ||||||
| 					abc9_opts += " -keepff"; | 					abc9_opts += " -dff"; | ||||||
| 				run("abc9" + abc9_opts); | 				run("abc9" + abc9_opts); | ||||||
| 				run("techmap -map +/xilinx/abc9_unmap.v"); | 				run("techmap -map +/xilinx/abc9_unmap.v"); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue