mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-30 19:22:31 +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, pair<SigBit, SigBit>> and_map; | ||||
| 	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; | ||||
| 
 | ||||
| 	vector<pair<int, int>> aig_gates; | ||||
|  | @ -204,7 +204,6 @@ struct XAigerWriter | |||
| 		dict<SigBit, pool<IdString>> bit_drivers, bit_users; | ||||
| 		TopoSort<IdString, RTLIL::sort_by_id_str> toposort; | ||||
| 		bool abc9_box_seen = false; | ||||
| 		std::vector<Cell*> flop_boxes; | ||||
| 
 | ||||
| 		for (auto cell : module->selected_cells()) { | ||||
| 			if (cell->type == "$_NOT_") | ||||
|  | @ -236,14 +235,17 @@ struct XAigerWriter | |||
| 				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 Q = sigmap(cell->getPort("\\Q").as_bit()); | ||||
| 				unused_bits.erase(D); | ||||
| 				undriven_bits.erase(Q); | ||||
| 				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); | ||||
| 				continue; | ||||
| 			} | ||||
|  | @ -252,14 +254,25 @@ struct XAigerWriter | |||
| 			if (inst_module) { | ||||
| 				bool abc9_box = inst_module->attributes.count("\\abc9_box_id"); | ||||
| 				bool abc9_flop = inst_module->get_bool_attribute("\\abc9_flop"); | ||||
| 				// The lack of an abc9_mergeability attribute indicates that
 | ||||
| 				//   we do want to keep this flop, so do not treat it as a box
 | ||||
| 				if (abc9_flop && !cell->attributes.count("\\abc9_mergeability")) | ||||
| 				if (abc9_box && cell->get_bool_attribute("\\abc9_keep")) | ||||
| 					abc9_box = false; | ||||
| 
 | ||||
| 				for (const auto &conn : cell->connections()) { | ||||
| 					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) { | ||||
| 						int arrival = 0; | ||||
| 						auto it = port_wire->attributes.find("\\abc9_arrival"); | ||||
|  | @ -272,25 +285,11 @@ struct XAigerWriter | |||
| 							for (auto bit : sigmap(conn.second)) | ||||
| 								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) { | ||||
| 					abc9_box_seen = true; | ||||
| 
 | ||||
| 					toposort.node(cell->name); | ||||
| 
 | ||||
| 					if (abc9_flop) | ||||
| 						flop_boxes.push_back(cell); | ||||
| 					continue; | ||||
| 				} | ||||
| 			} | ||||
|  | @ -321,61 +320,6 @@ struct XAigerWriter | |||
| 		} | ||||
| 
 | ||||
| 		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) | ||||
| 				if (bit_drivers.count(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")) { | ||||
| 					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()) | ||||
| 						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) { | ||||
| 						SigBit I = sigmap(b); | ||||
|  | @ -553,7 +497,8 @@ struct XAigerWriter | |||
| 		} | ||||
| 
 | ||||
| 		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++; | ||||
| 			log_assert(!aig_map.count(q)); | ||||
| 			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
 | ||||
| 				//   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")) { | ||||
| 					log_assert(holes_cell); | ||||
| 
 | ||||
|  | @ -754,7 +699,8 @@ struct XAigerWriter | |||
| 						holes_wire->port_id = port_id++; | ||||
| 						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); | ||||
| 				} | ||||
| 
 | ||||
|  | @ -774,13 +720,25 @@ struct XAigerWriter | |||
| 			write_s_buffer(ff_bits.size()); | ||||
| 
 | ||||
| 			for (const auto &i : ff_bits) { | ||||
| 				const SigBit &q = std::get<0>(i.second); | ||||
| 				int mergeability = std::get<1>(i.second); | ||||
| 				const SigBit &d = i.first; | ||||
| 				const Cell *cell = i.second; | ||||
| 
 | ||||
| 				int mergeability = cell->attributes.at(ID(abc9_mergeability)).as_int(); | ||||
| 				log_assert(mergeability > 0); | ||||
| 				write_r_buffer(mergeability); | ||||
| 				int init = std::get<2>(i.second); | ||||
| 				write_s_buffer(init); | ||||
| 				write_i_buffer(arrival_times.at(q, 0)); | ||||
| 
 | ||||
| 				Const init = cell->attributes.at(ID(abc9_init)); | ||||
| 				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);
 | ||||
| 			} | ||||
| 
 | ||||
|  | @ -833,9 +791,9 @@ struct XAigerWriter | |||
| 						log_assert(pos != std::string::npos); | ||||
| 						IdString driver = Q.wire->name.substr(0, pos); | ||||
| 						// 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 *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); | ||||
| 						holes_module->connect(Q, currQ); | ||||
| 						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, | ||||
| 		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, | ||||
| 		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"); | ||||
| 		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(); | ||||
| 		} | ||||
| 		ifs.close(); | ||||
|  | @ -430,7 +430,13 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip | |||
| 			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; | ||||
| 			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); | ||||
| 			} | ||||
| 		} | ||||
|  | @ -795,9 +801,9 @@ struct Abc9Pass : public Pass { | |||
| 		log("        generate netlist using luts. Use the specified costs for luts with 1,\n"); | ||||
| 		log("        2, 3, .. inputs.\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -keepff\n"); | ||||
| 		log("        do not represent (* abc9_flop *) modules as boxes (and thus do not perform\n"); | ||||
| 		log("        any form of sequential synthesis).\n"); | ||||
| 		log("    -dff\n"); | ||||
| 		log("        also pass $_ABC9_FF_ cells through ABC. modules with many clock domains\n"); | ||||
| 		log("        are marked as such and automatically partitioned by ABC.\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -nocleanup\n"); | ||||
| 		log("        when this option is used, the temporary files created by this pass\n"); | ||||
|  | @ -837,7 +843,7 @@ struct Abc9Pass : public Pass { | |||
| #endif | ||||
| 		std::string script_file, clk_str, box_file, lut_file; | ||||
| 		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 nomfs = false; | ||||
| 		vector<int> lut_costs; | ||||
|  | @ -928,8 +934,8 @@ struct Abc9Pass : public Pass { | |||
| 				fast_mode = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-keepff") { | ||||
| 				keepff = true; | ||||
| 			if (arg == "-dff") { | ||||
| 				dff = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-nocleanup") { | ||||
|  | @ -985,16 +991,14 @@ struct Abc9Pass : public Pass { | |||
| 			typedef SigSpec clkdomain_t; | ||||
| 			dict<clkdomain_t, int> clk_to_mergeability; | ||||
| 
 | ||||
| 
 | ||||
| 			if (!keepff) | ||||
| 			if (dff) | ||||
| 				for (auto cell : module->selected_cells()) { | ||||
| 					auto inst_module = design->module(cell->type); | ||||
| 					if (!inst_module || !inst_module->get_bool_attribute("\\abc9_flop")) | ||||
| 					if (cell->type != "$__ABC9_FF_") | ||||
| 						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) | ||||
| 						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); | ||||
| 
 | ||||
| 					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)); | ||||
| 					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) | ||||
| 						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); | ||||
| 					SigSpec abc9_init = assign_map(abc9_init_wire); | ||||
| 					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())); | ||||
| 					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(); | ||||
| 			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, | ||||
| 					box_file, lut_file, wire_delay, nomfs); | ||||
| 			design->selected_active_module.clear(); | ||||
|  |  | |||
|  | @ -51,29 +51,29 @@ | |||
| //                ||                  || | ||||
| //                ||      /\/\/\/\    || | ||||
| //           D  -->>-----<        >   || | ||||
| //           R  -->>-----<  Comb. >   ||        +----------+ | ||||
| //          CE  -->>-----<  logic >--->>-- $Q --|$__ABC_FF_|--+-->> Q | ||||
| // $abc9_currQ +-->>-----<        >   ||        +----------+  | | ||||
| //           R  -->>-----<  Comb. >   ||        +-----------+ | ||||
| //          CE  -->>-----<  logic >--->>-- $Q --|$__ABC9_FF_|--+-->> Q | ||||
| //   abc9_ff.Q +-->>-----<        >   ||        +-----------+  | | ||||
| //             |  ||      \/\/\/\/    ||                       | | ||||
| //             |  ||                  ||                       | | ||||
| //             |  ++==================++                       | | ||||
| //             |                                               | | ||||
| //             +----------------------------------------------+ | ||||
| //             +-----------------------------------------------+ | ||||
| // | ||||
| // 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 | ||||
| //     the connectivity of its basic D-Q flop | ||||
| // (b) an optional $__ABC9_ASYNC_ cell in front of $__ABC_FF_'s output to | ||||
| //     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 | ||||
| //     performs sequential synthesis (with reachability analysis) correctly on | ||||
| //     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 | ||||
| //     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 | ||||
| // (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 | ||||
| // | ||||
| // In order to perform sequential synthesis, `abc9' also requires that | ||||
|  | @ -108,12 +108,12 @@ module FDRE (output Q, input C, CE, D, R); | |||
|     ); | ||||
|   end | ||||
|   endgenerate | ||||
|   $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ)); | ||||
|   $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ)); | ||||
| 
 | ||||
|   // Special signals | ||||
|   wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; | ||||
|   wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED}; | ||||
|   wire [0:0] abc9_ff.init = 1'b0; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ; | ||||
| endmodule | ||||
| module FDRE_1 (output Q, input C, CE, D, R); | ||||
|   parameter [0:0] INIT = 1'b0; | ||||
|  | @ -135,12 +135,12 @@ module FDRE_1 (output Q, input C, CE, D, R); | |||
|     ); | ||||
|   end | ||||
|   endgenerate | ||||
|   $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ)); | ||||
|   $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ)); | ||||
| 
 | ||||
|   // Special signals | ||||
|   wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; | ||||
|   wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */}; | ||||
|   wire [0:0] abc9_ff.init = 1'b0; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ; | ||||
| endmodule | ||||
| 
 | ||||
| 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) | ||||
|     ); | ||||
|   end endgenerate | ||||
|   $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ)); | ||||
|   $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ)); | ||||
| 
 | ||||
|   // Special signals | ||||
|   wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; | ||||
|   wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED}; | ||||
|   wire [0:0] abc9_ff.init = 1'b0; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ; | ||||
| endmodule | ||||
| module FDSE_1 (output Q, input C, CE, D, S); | ||||
|   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) | ||||
|     ); | ||||
|   end endgenerate | ||||
|   $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ)); | ||||
|   $__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ)); | ||||
| 
 | ||||
|   // Special signals | ||||
|   wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ; | ||||
|   wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */}; | ||||
|   wire [0:0] abc9_ff.init = 1'b0; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ; | ||||
| endmodule | ||||
| 
 | ||||
| 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_D_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 | ||||
|     assign Q = ~QQ; | ||||
|     FDPE #( | ||||
|  | @ -227,7 +227,7 @@ module FDCE (output Q, input C, CE, D, CLR); | |||
|                                             //     $__ABC9_ASYNC1 below | ||||
|     ); | ||||
|     // 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 | ||||
|   else begin | ||||
|     assign Q = QQ; | ||||
|  | @ -245,18 +245,18 @@ module FDCE (output Q, input C, CE, D, CLR); | |||
|                                            //     $__ABC9_ASYNC0 below | ||||
|     ); | ||||
|     // 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 | ||||
|   $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ)); | ||||
|   $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ)); | ||||
| 
 | ||||
|   // Special signals | ||||
|   wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; | ||||
|   wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED}; | ||||
|   wire [0:0] abc9_ff.init = 1'b0; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ; | ||||
| endmodule | ||||
| module FDCE_1 (output Q, input C, CE, D, CLR); | ||||
|   parameter [0:0] INIT = 1'b0; | ||||
|   wire QQ, $Q, $abc9_currQ; | ||||
|   wire QQ, $Q, $QQ; | ||||
|   generate if (INIT == 1'b1) begin | ||||
|     assign Q = ~QQ; | ||||
|     FDPE_1 #( | ||||
|  | @ -269,7 +269,7 @@ module FDCE_1 (output Q, input C, CE, D, CLR); | |||
|                                             //     behaviour is captured by | ||||
|                                             //     $__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 | ||||
|   else begin | ||||
|     assign Q = QQ; | ||||
|  | @ -283,14 +283,14 @@ module FDCE_1 (output Q, input C, CE, D, CLR); | |||
|                                            //     behaviour is captured by | ||||
|                                            //     $__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 | ||||
|   $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ)); | ||||
|   $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ)); | ||||
| 
 | ||||
|   // Special signals | ||||
|   wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; | ||||
|   wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */}; | ||||
|   wire [0:0] abc9_ff.init = 1'b0; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ; | ||||
| endmodule | ||||
| 
 | ||||
| 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_D_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 | ||||
|     assign Q = ~QQ; | ||||
|     FDCE #( | ||||
|  | @ -314,7 +314,7 @@ module FDPE (output Q, input C, CE, D, PRE); | |||
|                                             //     behaviour is captured by | ||||
|                                             //     $__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 | ||||
|   else begin | ||||
|     assign Q = QQ; | ||||
|  | @ -331,18 +331,18 @@ module FDPE (output Q, input C, CE, D, PRE); | |||
|                                            //     behaviour is captured by | ||||
|                                            //     $__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 | ||||
|   $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ)); | ||||
|   $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ)); | ||||
| 
 | ||||
|   // Special signals | ||||
|   wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED}; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; | ||||
|   wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED}; | ||||
|   wire [0:0] abc9_ff.init = 1'b0; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ; | ||||
| endmodule | ||||
| module FDPE_1 (output Q, input C, CE, D, PRE); | ||||
|   parameter [0:0] INIT = 1'b1; | ||||
|   wire QQ, $Q, $abc9_currQ; | ||||
|   wire QQ, $Q, $QQ; | ||||
|   generate if (INIT == 1'b1) begin | ||||
|     assign Q = ~QQ; | ||||
|     FDCE_1 #( | ||||
|  | @ -355,7 +355,7 @@ module FDPE_1 (output Q, input C, CE, D, PRE); | |||
|                                             //     behaviour is captured by | ||||
|                                             //     $__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 | ||||
|   else begin | ||||
|     assign Q = QQ; | ||||
|  | @ -369,14 +369,14 @@ module FDPE_1 (output Q, input C, CE, D, PRE); | |||
|                                            //     behaviour is captured by | ||||
|                                            //     $__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 | ||||
|   $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ)); | ||||
|   $__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ)); | ||||
| 
 | ||||
|   // Special signals | ||||
|   wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */}; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ; | ||||
|   wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */}; | ||||
|   wire [0:0] abc9_ff.init = 1'b0; | ||||
|   wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ; | ||||
| endmodule | ||||
| `endif | ||||
| 
 | ||||
|  |  | |||
|  | @ -108,7 +108,7 @@ struct SynthXilinxPass : public ScriptPass | |||
| 		log("        flatten design before synthesis\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -dff\n"); | ||||
| 		log("        enable sequential synthesis with 'abc9'\n"); | ||||
| 		log("        run 'abc9' with -dff option\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -retime\n"); | ||||
| 		log("        run 'abc' with -dff option\n"); | ||||
|  | @ -559,8 +559,8 @@ struct SynthXilinxPass : public ScriptPass | |||
| 					abc9_opts += " -lut +/xilinx/abc9_xc7_nowide.lut"; | ||||
| 				else | ||||
| 					abc9_opts += " -lut +/xilinx/abc9_xc7.lut"; | ||||
| 				if (!dff_mode) | ||||
| 					abc9_opts += " -keepff"; | ||||
| 				if (dff_mode) | ||||
| 					abc9_opts += " -dff"; | ||||
| 				run("abc9" + abc9_opts); | ||||
| 				run("techmap -map +/xilinx/abc9_unmap.v"); | ||||
| 			} | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue