mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	Merge remote-tracking branch 'origin/xaig_dff' into eddie/abc9_refactor
This commit is contained in:
		
						commit
						921ff0f5e3
					
				
					 8 changed files with 295 additions and 255 deletions
				
			
		|  | @ -376,10 +376,11 @@ Verilog Attributes and non-standard features | ||||||
| - The port attribute ``abc9_arrival`` specifies an integer (for output ports | - The port attribute ``abc9_arrival`` specifies an integer (for output ports | ||||||
|   only) to be used as the arrival time of this sequential port. It can be used, |   only) to be used as the arrival time of this sequential port. It can be used, | ||||||
|   for example, to specify the clk-to-Q delay of a flip-flop for consideration |   for example, to specify the clk-to-Q delay of a flip-flop for consideration | ||||||
|   during techmapping. |   during `abc9` techmapping. | ||||||
| 
 | 
 | ||||||
| - The module attribute ``abc9_flop`` is a boolean marking the module as a | - The module attribute ``abc9_flop`` is a boolean marking the module as a | ||||||
|   whitebox that describes the synchronous behaviour of a flip-flop. |   flip-flop. This allows `abc9` to analyse its contents in order to perform | ||||||
|  |   sequential synthesis. | ||||||
| 
 | 
 | ||||||
| - The frontend sets attributes ``always_comb``, ``always_latch`` and | - The frontend sets attributes ``always_comb``, ``always_latch`` and | ||||||
|   ``always_ff`` on processes derived from SystemVerilog style always blocks |   ``always_ff`` on processes derived from SystemVerilog style always blocks | ||||||
|  |  | ||||||
|  | @ -787,6 +787,14 @@ struct AigerBackend : 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"); | ||||||
| 
 | 
 | ||||||
|  | 		if (!design->selected_whole_module(top_module)) | ||||||
|  | 			log_cmd_error("Can't handle partially selected module %s!\n", log_id(top_module)); | ||||||
|  | 
 | ||||||
|  | 		if (!top_module->processes.empty()) | ||||||
|  | 			log_error("Found unmapped processes in module %s: unmapped processes are not supported in AIGER backend!\n", log_id(top_module)); | ||||||
|  | 		if (!top_module->memories.empty()) | ||||||
|  | 			log_error("Found unmapped memories in module %s: unmapped memories are not supported in AIGER backend!\n", log_id(top_module)); | ||||||
|  | 
 | ||||||
| 		AigerWriter writer(top_module, zinit_mode, imode, omode, bmode, lmode); | 		AigerWriter writer(top_module, zinit_mode, imode, omode, bmode, lmode); | ||||||
| 		writer.write_aiger(*f, ascii_mode, miter_mode, symbols_mode); | 		writer.write_aiger(*f, ascii_mode, miter_mode, symbols_mode); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -137,7 +137,7 @@ struct XAigerWriter | ||||||
| 		return a; | 		return a; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	XAigerWriter(Module *module) : module(module), 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; | ||||||
|  | @ -157,12 +157,8 @@ struct XAigerWriter | ||||||
| 			if (wire->get_bool_attribute(ID::keep)) | 			if (wire->get_bool_attribute(ID::keep)) | ||||||
| 				sigmap.add(wire); | 				sigmap.add(wire); | ||||||
| 
 | 
 | ||||||
| 		// First, collect all the ports in port_id order
 | 
 | ||||||
| 		//   since module->wires() could be sorted
 | 		for (auto wire : module->wires()) | ||||||
| 		//   alphabetically
 |  | ||||||
| 		for (auto port : module->ports) { |  | ||||||
| 			auto wire = module->wire(port); |  | ||||||
| 			log_assert(wire); |  | ||||||
| 			for (int i = 0; i < GetSize(wire); i++) | 			for (int i = 0; i < GetSize(wire); i++) | ||||||
| 			{ | 			{ | ||||||
| 				SigBit wirebit(wire, i); | 				SigBit wirebit(wire, i); | ||||||
|  | @ -176,6 +172,9 @@ struct XAigerWriter | ||||||
| 					continue; | 					continue; | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
|  | 				undriven_bits.insert(bit); | ||||||
|  | 				unused_bits.insert(bit); | ||||||
|  | 
 | ||||||
| 				if (wire->port_input) | 				if (wire->port_input) | ||||||
| 					input_bits.insert(bit); | 					input_bits.insert(bit); | ||||||
| 
 | 
 | ||||||
|  | @ -185,19 +184,6 @@ struct XAigerWriter | ||||||
| 					output_bits.insert(wirebit); | 					output_bits.insert(wirebit); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		for (auto wire : module->wires()) |  | ||||||
| 			for (int i = 0; i < GetSize(wire); i++) |  | ||||||
| 			{ |  | ||||||
| 				SigBit wirebit(wire, i); |  | ||||||
| 				SigBit bit = sigmap(wirebit); |  | ||||||
| 
 |  | ||||||
| 				if (bit.wire) { |  | ||||||
| 					undriven_bits.insert(bit); |  | ||||||
| 					unused_bits.insert(bit); |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 
 | 
 | ||||||
| 		for (auto cell : module->cells()) { | 		for (auto cell : module->cells()) { | ||||||
| 			if (cell->type == "$_NOT_") | 			if (cell->type == "$_NOT_") | ||||||
|  | @ -402,12 +388,20 @@ struct XAigerWriter | ||||||
| 			undriven_bits.erase(bit); | 			undriven_bits.erase(bit); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		if (holes_mode) { | ||||||
|  | 			struct sort_by_port_id { | ||||||
|  | 				bool operator()(const RTLIL::SigBit& a, const RTLIL::SigBit& b) const { | ||||||
|  | 					return a.wire->port_id < b.wire->port_id; | ||||||
|  | 				} | ||||||
|  | 			}; | ||||||
|  | 			input_bits.sort(sort_by_port_id()); | ||||||
|  | 			output_bits.sort(sort_by_port_id()); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		aig_map[State::S0] = 0; | 		aig_map[State::S0] = 0; | ||||||
| 		aig_map[State::S1] = 1; | 		aig_map[State::S1] = 1; | ||||||
| 
 | 
 | ||||||
| 		// pool<> iterates in LIFO order...
 | 		for (const auto &bit : input_bits) { | ||||||
| 		for (int i = input_bits.size()-1; i >= 0; i--) { |  | ||||||
| 			const auto &bit = *input_bits.element(i); |  | ||||||
| 			aig_m++, aig_i++; | 			aig_m++, aig_i++; | ||||||
| 			log_assert(!aig_map.count(bit)); | 			log_assert(!aig_map.count(bit)); | ||||||
| 			aig_map[bit] = 2*aig_m; | 			aig_map[bit] = 2*aig_m; | ||||||
|  | @ -435,9 +429,7 @@ struct XAigerWriter | ||||||
| 			aig_outputs.push_back(bit2aig(bit)); | 			aig_outputs.push_back(bit2aig(bit)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// pool<> iterates in LIFO order...
 | 		for (const auto &bit : output_bits) { | ||||||
| 		for (int i = output_bits.size()-1; i >= 0; i--) { |  | ||||||
| 			const auto &bit = *output_bits.element(i); |  | ||||||
| 			ordered_outputs[bit] = aig_o++; | 			ordered_outputs[bit] = aig_o++; | ||||||
| 			aig_outputs.push_back(bit2aig(bit)); | 			aig_outputs.push_back(bit2aig(bit)); | ||||||
| 		} | 		} | ||||||
|  | @ -618,7 +610,7 @@ struct XAigerWriter | ||||||
| 
 | 
 | ||||||
| 			if (holes_module) { | 			if (holes_module) { | ||||||
| 				std::stringstream a_buffer; | 				std::stringstream a_buffer; | ||||||
| 				XAigerWriter writer(holes_module); | 				XAigerWriter writer(holes_module, true /* holes_mode */); | ||||||
| 				writer.write_aiger(a_buffer, false /*ascii_mode*/); | 				writer.write_aiger(a_buffer, false /*ascii_mode*/); | ||||||
| 
 | 
 | ||||||
| 				f << "a"; | 				f << "a"; | ||||||
|  | @ -654,17 +646,13 @@ struct XAigerWriter | ||||||
| 		module->design->scratchpad_set_int("write_xaiger.num_outputs", output_bits.size()); | 		module->design->scratchpad_set_int("write_xaiger.num_outputs", output_bits.size()); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void write_map(std::ostream &f, bool verbose_map) | 	void write_map(std::ostream &f) | ||||||
| 	{ | 	{ | ||||||
| 		dict<int, string> input_lines; | 		dict<int, string> input_lines; | ||||||
| 		dict<int, string> output_lines; | 		dict<int, string> output_lines; | ||||||
| 		dict<int, string> wire_lines; |  | ||||||
| 
 | 
 | ||||||
| 		for (auto wire : module->wires()) | 		for (auto wire : module->wires()) | ||||||
| 		{ | 		{ | ||||||
| 			//if (!verbose_map && wire->name[0] == '$')
 |  | ||||||
| 			//	continue;
 |  | ||||||
| 
 |  | ||||||
| 			SigSpec sig = sigmap(wire); | 			SigSpec sig = sigmap(wire); | ||||||
| 
 | 
 | ||||||
| 			for (int i = 0; i < GetSize(wire); i++) | 			for (int i = 0; i < GetSize(wire); i++) | ||||||
|  | @ -682,14 +670,6 @@ struct XAigerWriter | ||||||
| 					output_lines[o] += stringf("output %d %d %s %d\n", o - GetSize(co_bits), i, log_id(wire), init); | 					output_lines[o] += stringf("output %d %d %s %d\n", o - GetSize(co_bits), i, log_id(wire), init); | ||||||
| 					continue; | 					continue; | ||||||
| 				} | 				} | ||||||
| 
 |  | ||||||
| 				if (verbose_map) { |  | ||||||
| 					if (aig_map.count(sig[i]) == 0) |  | ||||||
| 						continue; |  | ||||||
| 
 |  | ||||||
| 					int a = aig_map.at(sig[i]); |  | ||||||
| 					wire_lines[a] += stringf("wire %d %d %s\n", a, i, log_id(wire)); |  | ||||||
| 				} |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -706,10 +686,6 @@ struct XAigerWriter | ||||||
| 		for (auto &it : output_lines) | 		for (auto &it : output_lines) | ||||||
| 			f << it.second; | 			f << it.second; | ||||||
| 		log_assert(output_lines.size() == output_bits.size()); | 		log_assert(output_lines.size() == output_bits.size()); | ||||||
| 
 |  | ||||||
| 		wire_lines.sort(); |  | ||||||
| 		for (auto &it : wire_lines) |  | ||||||
| 			f << it.second; |  | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -721,8 +697,10 @@ struct XAigerBackend : public Backend { | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("    write_xaiger [options] [filename]\n"); | 		log("    write_xaiger [options] [filename]\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("Write the current design to an XAIGER file. The design must be flattened and\n"); | 		log("Write the top module (according to the (* top *) attribute or if only one module\n"); | ||||||
| 		log("all unsupported cells will be converted into psuedo-inputs and pseudo-outputs.\n"); | 		log("is currently selected) to an XAIGER file. Any non $_NOT_, $_AND_, $_ABC9_FF_, or"); | ||||||
|  | 		log("non (* abc9_box_id *) cells will be converted into psuedo-inputs and\n"); | ||||||
|  | 		log("pseudo-outputs.\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("    -ascii\n"); | 		log("    -ascii\n"); | ||||||
| 		log("        write ASCII version of AIGER format\n"); | 		log("        write ASCII version of AIGER format\n"); | ||||||
|  | @ -730,14 +708,10 @@ struct XAigerBackend : public Backend { | ||||||
| 		log("    -map <filename>\n"); | 		log("    -map <filename>\n"); | ||||||
| 		log("        write an extra file with port and box symbols\n"); | 		log("        write an extra file with port and box symbols\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("    -vmap <filename>\n"); |  | ||||||
| 		log("        like -map, but more verbose\n"); |  | ||||||
| 		log("\n"); |  | ||||||
| 	} | 	} | ||||||
| 	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 verbose_map = false; |  | ||||||
| 		std::string map_filename; | 		std::string map_filename; | ||||||
| 
 | 
 | ||||||
| 		log_header(design, "Executing XAIGER backend.\n"); | 		log_header(design, "Executing XAIGER backend.\n"); | ||||||
|  | @ -753,11 +727,6 @@ struct XAigerBackend : public Backend { | ||||||
| 				map_filename = args[++argidx]; | 				map_filename = args[++argidx]; | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (map_filename.empty() && args[argidx] == "-vmap" && argidx+1 < args.size()) { |  | ||||||
| 				map_filename = args[++argidx]; |  | ||||||
| 				verbose_map = true; |  | ||||||
| 				continue; |  | ||||||
| 			} |  | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| 		extra_args(f, filename, args, argidx, !ascii_mode); | 		extra_args(f, filename, args, argidx, !ascii_mode); | ||||||
|  | @ -767,6 +736,14 @@ 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"); | ||||||
| 
 | 
 | ||||||
|  | 		if (!design->selected_whole_module(top_module)) | ||||||
|  | 			log_cmd_error("Can't handle partially selected module %s!\n", log_id(top_module)); | ||||||
|  | 
 | ||||||
|  | 		if (!top_module->processes.empty()) | ||||||
|  | 			log_error("Found unmapped processes in module %s: unmapped processes are not supported in XAIGER backend!\n", log_id(top_module)); | ||||||
|  | 		if (!top_module->memories.empty()) | ||||||
|  | 			log_error("Found unmapped memories in module %s: unmapped memories are not supported in XAIGER backend!\n", log_id(top_module)); | ||||||
|  | 
 | ||||||
| 		XAigerWriter writer(top_module); | 		XAigerWriter writer(top_module); | ||||||
| 		writer.write_aiger(*f, ascii_mode); | 		writer.write_aiger(*f, ascii_mode); | ||||||
| 
 | 
 | ||||||
|  | @ -775,7 +752,7 @@ struct XAigerBackend : public Backend { | ||||||
| 			mapf.open(map_filename.c_str(), std::ofstream::trunc); | 			mapf.open(map_filename.c_str(), std::ofstream::trunc); | ||||||
| 			if (mapf.fail()) | 			if (mapf.fail()) | ||||||
| 				log_error("Can't open file `%s' for writing: %s\n", map_filename.c_str(), strerror(errno)); | 				log_error("Can't open file `%s' for writing: %s\n", map_filename.c_str(), strerror(errno)); | ||||||
| 			writer.write_map(mapf, verbose_map); | 			writer.write_map(mapf); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } XAigerBackend; | } XAigerBackend; | ||||||
|  |  | ||||||
|  | @ -1514,7 +1514,47 @@ struct AbcPass : public Pass { | ||||||
| #endif | #endif | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 		size_t argidx; | 		// get arguments from scratchpad first, then override by command arguments
 | ||||||
|  | 		std::string lut_arg, luts_arg, g_arg; | ||||||
|  | 		exe_file = design->scratchpad_get_string("abc.exe", exe_file /* inherit default value if not set */); | ||||||
|  | 		script_file = design->scratchpad_get_string("abc.script", script_file); | ||||||
|  | 		liberty_file = design->scratchpad_get_string("abc.liberty", liberty_file); | ||||||
|  | 		constr_file = design->scratchpad_get_string("abc.constr", constr_file); | ||||||
|  | 		if (design->scratchpad.count("abc.D")) { | ||||||
|  | 			delay_target = "-D " + design->scratchpad_get_string("abc.D"); | ||||||
|  | 		} | ||||||
|  | 		if (design->scratchpad.count("abc.I")) { | ||||||
|  | 			sop_inputs = "-I " + design->scratchpad_get_string("abc.I"); | ||||||
|  | 		} | ||||||
|  | 		if (design->scratchpad.count("abc.P")) { | ||||||
|  | 			sop_products = "-P " + design->scratchpad_get_string("abc.P"); | ||||||
|  | 		} | ||||||
|  | 		if (design->scratchpad.count("abc.S")) { | ||||||
|  | 			lutin_shared = "-S " + design->scratchpad_get_string("abc.S"); | ||||||
|  | 		} | ||||||
|  | 		lut_arg = design->scratchpad_get_string("abc.lut", lut_arg); | ||||||
|  | 		luts_arg = design->scratchpad_get_string("abc.luts", luts_arg); | ||||||
|  | 		sop_mode = design->scratchpad_get_bool("abc.sop", sop_mode); | ||||||
|  | 		map_mux4 = design->scratchpad_get_bool("abc.mux4", map_mux4); | ||||||
|  | 		map_mux8 = design->scratchpad_get_bool("abc.mux8", map_mux8); | ||||||
|  | 		map_mux16 = design->scratchpad_get_bool("abc.mux16", map_mux16); | ||||||
|  | 		abc_dress = design->scratchpad_get_bool("abc.dress", abc_dress); | ||||||
|  | 		g_arg = design->scratchpad_get_string("abc.g", g_arg); | ||||||
|  | 
 | ||||||
|  | 		fast_mode = design->scratchpad_get_bool("abc.fast", fast_mode); | ||||||
|  | 		dff_mode = design->scratchpad_get_bool("abc.dff", dff_mode); | ||||||
|  | 		if (design->scratchpad.count("abc.clk")) { | ||||||
|  | 			clk_str = design->scratchpad_get_string("abc.clk"); | ||||||
|  | 			dff_mode = true; | ||||||
|  | 		} | ||||||
|  | 		keepff = design->scratchpad_get_bool("abc.keepff", keepff); | ||||||
|  | 		cleanup = !design->scratchpad_get_bool("abc.nocleanup", !cleanup); | ||||||
|  | 		keepff = design->scratchpad_get_bool("abc.keepff", keepff); | ||||||
|  | 		show_tempdir = design->scratchpad_get_bool("abc.showtmp", show_tempdir); | ||||||
|  | 		markgroups = design->scratchpad_get_bool("abc.markgroups", markgroups); | ||||||
|  | 
 | ||||||
|  | 		size_t argidx, g_argidx; | ||||||
|  | 		bool g_arg_from_cmd = false; | ||||||
| 		char pwd [PATH_MAX]; | 		char pwd [PATH_MAX]; | ||||||
| 		if (!getcwd(pwd, sizeof(pwd))) { | 		if (!getcwd(pwd, sizeof(pwd))) { | ||||||
| 			log_cmd_error("getcwd failed: %s\n", strerror(errno)); | 			log_cmd_error("getcwd failed: %s\n", strerror(errno)); | ||||||
|  | @ -1528,23 +1568,14 @@ struct AbcPass : public Pass { | ||||||
| 			} | 			} | ||||||
| 			if (arg == "-script" && argidx+1 < args.size()) { | 			if (arg == "-script" && argidx+1 < args.size()) { | ||||||
| 				script_file = args[++argidx]; | 				script_file = args[++argidx]; | ||||||
| 				rewrite_filename(script_file); |  | ||||||
| 				if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+') |  | ||||||
| 					script_file = std::string(pwd) + "/" + script_file; |  | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (arg == "-liberty" && argidx+1 < args.size()) { | 			if (arg == "-liberty" && argidx+1 < args.size()) { | ||||||
| 				liberty_file = args[++argidx]; | 				liberty_file = args[++argidx]; | ||||||
| 				rewrite_filename(liberty_file); |  | ||||||
| 				if (!liberty_file.empty() && !is_absolute_path(liberty_file)) |  | ||||||
| 					liberty_file = std::string(pwd) + "/" + liberty_file; |  | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (arg == "-constr" && argidx+1 < args.size()) { | 			if (arg == "-constr" && argidx+1 < args.size()) { | ||||||
| 				rewrite_filename(constr_file); |  | ||||||
| 				constr_file = args[++argidx]; | 				constr_file = args[++argidx]; | ||||||
| 				if (!constr_file.empty() && !is_absolute_path(constr_file)) |  | ||||||
| 					constr_file = std::string(pwd) + "/" + constr_file; |  | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (arg == "-D" && argidx+1 < args.size()) { | 			if (arg == "-D" && argidx+1 < args.size()) { | ||||||
|  | @ -1564,37 +1595,11 @@ struct AbcPass : public Pass { | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (arg == "-lut" && argidx+1 < args.size()) { | 			if (arg == "-lut" && argidx+1 < args.size()) { | ||||||
| 				string arg = args[++argidx]; | 				lut_arg = args[++argidx]; | ||||||
| 				size_t pos = arg.find_first_of(':'); |  | ||||||
| 				int lut_mode = 0, lut_mode2 = 0; |  | ||||||
| 				if (pos != string::npos) { |  | ||||||
| 					lut_mode = atoi(arg.substr(0, pos).c_str()); |  | ||||||
| 					lut_mode2 = atoi(arg.substr(pos+1).c_str()); |  | ||||||
| 				} else { |  | ||||||
| 					lut_mode = atoi(arg.c_str()); |  | ||||||
| 					lut_mode2 = lut_mode; |  | ||||||
| 				} |  | ||||||
| 				lut_costs.clear(); |  | ||||||
| 				for (int i = 0; i < lut_mode; i++) |  | ||||||
| 					lut_costs.push_back(1); |  | ||||||
| 				for (int i = lut_mode; i < lut_mode2; i++) |  | ||||||
| 					lut_costs.push_back(2 << (i - lut_mode)); |  | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (arg == "-luts" && argidx+1 < args.size()) { | 			if (arg == "-luts" && argidx+1 < args.size()) { | ||||||
| 				lut_costs.clear(); | 				luts_arg = args[++argidx]; | ||||||
| 				for (auto &tok : split_tokens(args[++argidx], ",")) { |  | ||||||
| 					auto parts = split_tokens(tok, ":"); |  | ||||||
| 					if (GetSize(parts) == 0 && !lut_costs.empty()) |  | ||||||
| 						lut_costs.push_back(lut_costs.back()); |  | ||||||
| 					else if (GetSize(parts) == 1) |  | ||||||
| 						lut_costs.push_back(atoi(parts.at(0).c_str())); |  | ||||||
| 					else if (GetSize(parts) == 2) |  | ||||||
| 						while (GetSize(lut_costs) < std::atoi(parts.at(0).c_str())) |  | ||||||
| 							lut_costs.push_back(atoi(parts.at(1).c_str())); |  | ||||||
| 					else |  | ||||||
| 						log_cmd_error("Invalid -luts syntax.\n"); |  | ||||||
| 				} |  | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (arg == "-sop") { | 			if (arg == "-sop") { | ||||||
|  | @ -1618,123 +1623,9 @@ struct AbcPass : public Pass { | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (arg == "-g" && argidx+1 < args.size()) { | 			if (arg == "-g" && argidx+1 < args.size()) { | ||||||
| 				for (auto g : split_tokens(args[++argidx], ",")) { | 				g_arg = args[++argidx]; | ||||||
| 					vector<string> gate_list; | 				g_argidx = argidx; | ||||||
| 					bool remove_gates = false; | 				g_arg_from_cmd = true; | ||||||
| 					if (GetSize(g) > 0 && g[0] == '-') { |  | ||||||
| 						remove_gates = true; |  | ||||||
| 						g = g.substr(1); |  | ||||||
| 					} |  | ||||||
| 					if (g == "AND") goto ok_gate; |  | ||||||
| 					if (g == "NAND") goto ok_gate; |  | ||||||
| 					if (g == "OR") goto ok_gate; |  | ||||||
| 					if (g == "NOR") goto ok_gate; |  | ||||||
| 					if (g == "XOR") goto ok_gate; |  | ||||||
| 					if (g == "XNOR") goto ok_gate; |  | ||||||
| 					if (g == "ANDNOT") goto ok_gate; |  | ||||||
| 					if (g == "ORNOT") goto ok_gate; |  | ||||||
| 					if (g == "MUX") goto ok_gate; |  | ||||||
| 					if (g == "NMUX") goto ok_gate; |  | ||||||
| 					if (g == "AOI3") goto ok_gate; |  | ||||||
| 					if (g == "OAI3") goto ok_gate; |  | ||||||
| 					if (g == "AOI4") goto ok_gate; |  | ||||||
| 					if (g == "OAI4") goto ok_gate; |  | ||||||
| 					if (g == "simple") { |  | ||||||
| 						gate_list.push_back("AND"); |  | ||||||
| 						gate_list.push_back("OR"); |  | ||||||
| 						gate_list.push_back("XOR"); |  | ||||||
| 						gate_list.push_back("MUX"); |  | ||||||
| 						goto ok_alias; |  | ||||||
| 					} |  | ||||||
| 					if (g == "cmos2") { |  | ||||||
| 						if (!remove_gates) |  | ||||||
| 							cmos_cost = true; |  | ||||||
| 						gate_list.push_back("NAND"); |  | ||||||
| 						gate_list.push_back("NOR"); |  | ||||||
| 						goto ok_alias; |  | ||||||
| 					} |  | ||||||
| 					if (g == "cmos3") { |  | ||||||
| 						if (!remove_gates) |  | ||||||
| 							cmos_cost = true; |  | ||||||
| 						gate_list.push_back("NAND"); |  | ||||||
| 						gate_list.push_back("NOR"); |  | ||||||
| 						gate_list.push_back("AOI3"); |  | ||||||
| 						gate_list.push_back("OAI3"); |  | ||||||
| 						goto ok_alias; |  | ||||||
| 					} |  | ||||||
| 					if (g == "cmos4") { |  | ||||||
| 						if (!remove_gates) |  | ||||||
| 							cmos_cost = true; |  | ||||||
| 						gate_list.push_back("NAND"); |  | ||||||
| 						gate_list.push_back("NOR"); |  | ||||||
| 						gate_list.push_back("AOI3"); |  | ||||||
| 						gate_list.push_back("OAI3"); |  | ||||||
| 						gate_list.push_back("AOI4"); |  | ||||||
| 						gate_list.push_back("OAI4"); |  | ||||||
| 						goto ok_alias; |  | ||||||
| 					} |  | ||||||
| 					if (g == "cmos") { |  | ||||||
| 						if (!remove_gates) |  | ||||||
| 							cmos_cost = true; |  | ||||||
| 						gate_list.push_back("NAND"); |  | ||||||
| 						gate_list.push_back("NOR"); |  | ||||||
| 						gate_list.push_back("AOI3"); |  | ||||||
| 						gate_list.push_back("OAI3"); |  | ||||||
| 						gate_list.push_back("AOI4"); |  | ||||||
| 						gate_list.push_back("OAI4"); |  | ||||||
| 						gate_list.push_back("NMUX"); |  | ||||||
| 						gate_list.push_back("MUX"); |  | ||||||
| 						gate_list.push_back("XOR"); |  | ||||||
| 						gate_list.push_back("XNOR"); |  | ||||||
| 						goto ok_alias; |  | ||||||
| 					} |  | ||||||
| 					if (g == "gates") { |  | ||||||
| 						gate_list.push_back("AND"); |  | ||||||
| 						gate_list.push_back("NAND"); |  | ||||||
| 						gate_list.push_back("OR"); |  | ||||||
| 						gate_list.push_back("NOR"); |  | ||||||
| 						gate_list.push_back("XOR"); |  | ||||||
| 						gate_list.push_back("XNOR"); |  | ||||||
| 						gate_list.push_back("ANDNOT"); |  | ||||||
| 						gate_list.push_back("ORNOT"); |  | ||||||
| 						goto ok_alias; |  | ||||||
| 					} |  | ||||||
| 					if (g == "aig") { |  | ||||||
| 						gate_list.push_back("AND"); |  | ||||||
| 						gate_list.push_back("NAND"); |  | ||||||
| 						gate_list.push_back("OR"); |  | ||||||
| 						gate_list.push_back("NOR"); |  | ||||||
| 						gate_list.push_back("ANDNOT"); |  | ||||||
| 						gate_list.push_back("ORNOT"); |  | ||||||
| 						goto ok_alias; |  | ||||||
| 					} |  | ||||||
| 					if (g == "all") { |  | ||||||
| 						gate_list.push_back("AND"); |  | ||||||
| 						gate_list.push_back("NAND"); |  | ||||||
| 						gate_list.push_back("OR"); |  | ||||||
| 						gate_list.push_back("NOR"); |  | ||||||
| 						gate_list.push_back("XOR"); |  | ||||||
| 						gate_list.push_back("XNOR"); |  | ||||||
| 						gate_list.push_back("ANDNOT"); |  | ||||||
| 						gate_list.push_back("ORNOT"); |  | ||||||
| 						gate_list.push_back("AOI3"); |  | ||||||
| 						gate_list.push_back("OAI3"); |  | ||||||
| 						gate_list.push_back("AOI4"); |  | ||||||
| 						gate_list.push_back("OAI4"); |  | ||||||
| 						gate_list.push_back("MUX"); |  | ||||||
| 						gate_list.push_back("NMUX"); |  | ||||||
| 					} |  | ||||||
| 					cmd_error(args, argidx, stringf("Unsupported gate type: %s", g.c_str())); |  | ||||||
| 				ok_gate: |  | ||||||
| 					gate_list.push_back(g); |  | ||||||
| 				ok_alias: |  | ||||||
| 					for (auto gate : gate_list) { |  | ||||||
| 						if (remove_gates) |  | ||||||
| 							enabled_gates.erase(gate); |  | ||||||
| 						else |  | ||||||
| 							enabled_gates.insert(gate); |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (arg == "-fast") { | 			if (arg == "-fast") { | ||||||
|  | @ -1770,6 +1661,174 @@ struct AbcPass : public Pass { | ||||||
| 		} | 		} | ||||||
| 		extra_args(args, argidx, design); | 		extra_args(args, argidx, design); | ||||||
| 
 | 
 | ||||||
|  | 		rewrite_filename(script_file); | ||||||
|  | 		if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+') | ||||||
|  | 			script_file = std::string(pwd) + "/" + script_file; | ||||||
|  | 		rewrite_filename(liberty_file); | ||||||
|  | 		if (!liberty_file.empty() && !is_absolute_path(liberty_file)) | ||||||
|  | 			liberty_file = std::string(pwd) + "/" + liberty_file; | ||||||
|  | 		rewrite_filename(constr_file); | ||||||
|  | 		if (!constr_file.empty() && !is_absolute_path(constr_file)) | ||||||
|  | 			constr_file = std::string(pwd) + "/" + constr_file; | ||||||
|  | 
 | ||||||
|  | 		// handle -lut argument
 | ||||||
|  | 		if (!lut_arg.empty()) { | ||||||
|  | 			size_t pos = lut_arg.find_first_of(':'); | ||||||
|  | 			int lut_mode = 0, lut_mode2 = 0; | ||||||
|  | 			if (pos != string::npos) { | ||||||
|  | 				lut_mode = atoi(lut_arg.substr(0, pos).c_str()); | ||||||
|  | 				lut_mode2 = atoi(lut_arg.substr(pos+1).c_str()); | ||||||
|  | 			} else { | ||||||
|  | 				lut_mode = atoi(lut_arg.c_str()); | ||||||
|  | 				lut_mode2 = lut_mode; | ||||||
|  | 			} | ||||||
|  | 			lut_costs.clear(); | ||||||
|  | 			for (int i = 0; i < lut_mode; i++) | ||||||
|  | 				lut_costs.push_back(1); | ||||||
|  | 			for (int i = lut_mode; i < lut_mode2; i++) | ||||||
|  | 				lut_costs.push_back(2 << (i - lut_mode)); | ||||||
|  | 		} | ||||||
|  | 		//handle -luts argument
 | ||||||
|  | 		if (!luts_arg.empty()){ | ||||||
|  | 			lut_costs.clear(); | ||||||
|  | 			for (auto &tok : split_tokens(luts_arg, ",")) { | ||||||
|  | 				auto parts = split_tokens(tok, ":"); | ||||||
|  | 				if (GetSize(parts) == 0 && !lut_costs.empty()) | ||||||
|  | 					lut_costs.push_back(lut_costs.back()); | ||||||
|  | 				else if (GetSize(parts) == 1) | ||||||
|  | 					lut_costs.push_back(atoi(parts.at(0).c_str())); | ||||||
|  | 				else if (GetSize(parts) == 2) | ||||||
|  | 					while (GetSize(lut_costs) < std::atoi(parts.at(0).c_str())) | ||||||
|  | 						lut_costs.push_back(atoi(parts.at(1).c_str())); | ||||||
|  | 				else | ||||||
|  | 					log_cmd_error("Invalid -luts syntax.\n"); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// handle -g argument
 | ||||||
|  | 		if (!g_arg.empty()){ | ||||||
|  | 			for (auto g : split_tokens(g_arg, ",")) { | ||||||
|  | 				vector<string> gate_list; | ||||||
|  | 				bool remove_gates = false; | ||||||
|  | 				if (GetSize(g) > 0 && g[0] == '-') { | ||||||
|  | 					remove_gates = true; | ||||||
|  | 					g = g.substr(1); | ||||||
|  | 				} | ||||||
|  | 				if (g == "AND") goto ok_gate; | ||||||
|  | 				if (g == "NAND") goto ok_gate; | ||||||
|  | 				if (g == "OR") goto ok_gate; | ||||||
|  | 				if (g == "NOR") goto ok_gate; | ||||||
|  | 				if (g == "XOR") goto ok_gate; | ||||||
|  | 				if (g == "XNOR") goto ok_gate; | ||||||
|  | 				if (g == "ANDNOT") goto ok_gate; | ||||||
|  | 				if (g == "ORNOT") goto ok_gate; | ||||||
|  | 				if (g == "MUX") goto ok_gate; | ||||||
|  | 				if (g == "NMUX") goto ok_gate; | ||||||
|  | 				if (g == "AOI3") goto ok_gate; | ||||||
|  | 				if (g == "OAI3") goto ok_gate; | ||||||
|  | 				if (g == "AOI4") goto ok_gate; | ||||||
|  | 				if (g == "OAI4") goto ok_gate; | ||||||
|  | 				if (g == "simple") { | ||||||
|  | 					gate_list.push_back("AND"); | ||||||
|  | 					gate_list.push_back("OR"); | ||||||
|  | 					gate_list.push_back("XOR"); | ||||||
|  | 					gate_list.push_back("MUX"); | ||||||
|  | 					goto ok_alias; | ||||||
|  | 				} | ||||||
|  | 				if (g == "cmos2") { | ||||||
|  | 					if (!remove_gates) | ||||||
|  | 						cmos_cost = true; | ||||||
|  | 					gate_list.push_back("NAND"); | ||||||
|  | 					gate_list.push_back("NOR"); | ||||||
|  | 					goto ok_alias; | ||||||
|  | 				} | ||||||
|  | 				if (g == "cmos3") { | ||||||
|  | 					if (!remove_gates) | ||||||
|  | 						cmos_cost = true; | ||||||
|  | 					gate_list.push_back("NAND"); | ||||||
|  | 					gate_list.push_back("NOR"); | ||||||
|  | 					gate_list.push_back("AOI3"); | ||||||
|  | 					gate_list.push_back("OAI3"); | ||||||
|  | 					goto ok_alias; | ||||||
|  | 				} | ||||||
|  | 				if (g == "cmos4") { | ||||||
|  | 					if (!remove_gates) | ||||||
|  | 						cmos_cost = true; | ||||||
|  | 					gate_list.push_back("NAND"); | ||||||
|  | 					gate_list.push_back("NOR"); | ||||||
|  | 					gate_list.push_back("AOI3"); | ||||||
|  | 					gate_list.push_back("OAI3"); | ||||||
|  | 					gate_list.push_back("AOI4"); | ||||||
|  | 					gate_list.push_back("OAI4"); | ||||||
|  | 					goto ok_alias; | ||||||
|  | 				} | ||||||
|  | 				if (g == "cmos") { | ||||||
|  | 					if (!remove_gates) | ||||||
|  | 						cmos_cost = true; | ||||||
|  | 					gate_list.push_back("NAND"); | ||||||
|  | 					gate_list.push_back("NOR"); | ||||||
|  | 					gate_list.push_back("AOI3"); | ||||||
|  | 					gate_list.push_back("OAI3"); | ||||||
|  | 					gate_list.push_back("AOI4"); | ||||||
|  | 					gate_list.push_back("OAI4"); | ||||||
|  | 					gate_list.push_back("NMUX"); | ||||||
|  | 					gate_list.push_back("MUX"); | ||||||
|  | 					gate_list.push_back("XOR"); | ||||||
|  | 					gate_list.push_back("XNOR"); | ||||||
|  | 					goto ok_alias; | ||||||
|  | 				} | ||||||
|  | 				if (g == "gates") { | ||||||
|  | 					gate_list.push_back("AND"); | ||||||
|  | 					gate_list.push_back("NAND"); | ||||||
|  | 					gate_list.push_back("OR"); | ||||||
|  | 					gate_list.push_back("NOR"); | ||||||
|  | 					gate_list.push_back("XOR"); | ||||||
|  | 					gate_list.push_back("XNOR"); | ||||||
|  | 					gate_list.push_back("ANDNOT"); | ||||||
|  | 					gate_list.push_back("ORNOT"); | ||||||
|  | 					goto ok_alias; | ||||||
|  | 				} | ||||||
|  | 				if (g == "aig") { | ||||||
|  | 					gate_list.push_back("AND"); | ||||||
|  | 					gate_list.push_back("NAND"); | ||||||
|  | 					gate_list.push_back("OR"); | ||||||
|  | 					gate_list.push_back("NOR"); | ||||||
|  | 					gate_list.push_back("ANDNOT"); | ||||||
|  | 					gate_list.push_back("ORNOT"); | ||||||
|  | 					goto ok_alias; | ||||||
|  | 				} | ||||||
|  | 				if (g == "all") { | ||||||
|  | 					gate_list.push_back("AND"); | ||||||
|  | 					gate_list.push_back("NAND"); | ||||||
|  | 					gate_list.push_back("OR"); | ||||||
|  | 					gate_list.push_back("NOR"); | ||||||
|  | 					gate_list.push_back("XOR"); | ||||||
|  | 					gate_list.push_back("XNOR"); | ||||||
|  | 					gate_list.push_back("ANDNOT"); | ||||||
|  | 					gate_list.push_back("ORNOT"); | ||||||
|  | 					gate_list.push_back("AOI3"); | ||||||
|  | 					gate_list.push_back("OAI3"); | ||||||
|  | 					gate_list.push_back("AOI4"); | ||||||
|  | 					gate_list.push_back("OAI4"); | ||||||
|  | 					gate_list.push_back("MUX"); | ||||||
|  | 					gate_list.push_back("NMUX"); | ||||||
|  | 				} | ||||||
|  | 				if (g_arg_from_cmd) | ||||||
|  | 					cmd_error(args, g_argidx, stringf("Unsupported gate type: %s", g.c_str())); | ||||||
|  | 				else | ||||||
|  | 					log_cmd_error("Unsupported gate type: %s", g.c_str()); | ||||||
|  | 			ok_gate: | ||||||
|  | 				gate_list.push_back(g); | ||||||
|  | 			ok_alias: | ||||||
|  | 				for (auto gate : gate_list) { | ||||||
|  | 					if (remove_gates) | ||||||
|  | 						enabled_gates.erase(gate); | ||||||
|  | 					else | ||||||
|  | 						enabled_gates.insert(gate); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		if (!lut_costs.empty() && !liberty_file.empty()) | 		if (!lut_costs.empty() && !liberty_file.empty()) | ||||||
| 			log_cmd_error("Got -lut and -liberty! These two options are exclusive.\n"); | 			log_cmd_error("Got -lut and -liberty! These two options are exclusive.\n"); | ||||||
| 		if (!constr_file.empty() && liberty_file.empty()) | 		if (!constr_file.empty() && liberty_file.empty()) | ||||||
|  |  | ||||||
|  | @ -40,7 +40,7 @@ struct Abc9Pass : public ScriptPass | ||||||
| 		log("    abc9 [options] [selection]\n"); | 		log("    abc9 [options] [selection]\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("This pass uses the ABC tool [1] for technology mapping of yosys's internal gate\n"); | 		log("This pass uses the ABC tool [1] for technology mapping of yosys's internal gate\n"); | ||||||
| 		log("library to a target architecture.\n"); | 		log("library to a target architecture. Only fully-selected modules are supported.\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("    -exe <command>\n"); | 		log("    -exe <command>\n"); | ||||||
| #ifdef ABCEXTERNAL | #ifdef ABCEXTERNAL | ||||||
|  | @ -113,11 +113,6 @@ struct Abc9Pass : public ScriptPass | ||||||
| 		log("        print the temp dir name in log. usually this is suppressed so that the\n"); | 		log("        print the temp dir name in log. usually this is suppressed so that the\n"); | ||||||
| 		log("        command output is identical across runs.\n"); | 		log("        command output is identical across runs.\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("    -markgroups\n"); |  | ||||||
| 		log("        set a 'abcgroup' attribute on all objects created by ABC. The value of\n"); |  | ||||||
| 		log("        this attribute is a unique integer for each ABC process started. This\n"); |  | ||||||
| 		log("        is useful for debugging the partitioning of clock domains.\n"); |  | ||||||
| 		log("\n"); |  | ||||||
| 		log("    -box <file>\n"); | 		log("    -box <file>\n"); | ||||||
| 		log("        pass this file with box library to ABC. Use with -lut.\n"); | 		log("        pass this file with box library to ABC. Use with -lut.\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
|  | @ -150,6 +145,25 @@ struct Abc9Pass : public ScriptPass | ||||||
| 		std::string run_from, run_to; | 		std::string run_from, run_to; | ||||||
| 		clear_flags(); | 		clear_flags(); | ||||||
| 
 | 
 | ||||||
|  | 		// get arguments from scratchpad first, then override by command arguments
 | ||||||
|  | 		std::string lut_arg, luts_arg; | ||||||
|  | 		exe_file = design->scratchpad_get_string("abc9.exe", exe_file /* inherit default value if not set */); | ||||||
|  | 		script_file = design->scratchpad_get_string("abc9.script", script_file); | ||||||
|  | 		if (design->scratchpad.count("abc9.D")) { | ||||||
|  | 			delay_target = "-D " + design->scratchpad_get_string("abc9.D"); | ||||||
|  | 		} | ||||||
|  | 		lut_arg = design->scratchpad_get_string("abc9.lut", lut_arg); | ||||||
|  | 		luts_arg = design->scratchpad_get_string("abc9.luts", luts_arg); | ||||||
|  | 		fast_mode = design->scratchpad_get_bool("abc9.fast", fast_mode); | ||||||
|  | 		dff_mode = design->scratchpad_get_bool("abc9.dff", dff_mode); | ||||||
|  | 		cleanup = !design->scratchpad_get_bool("abc9.nocleanup", !cleanup); | ||||||
|  | 		show_tempdir = design->scratchpad_get_bool("abc9.showtmp", show_tempdir); | ||||||
|  | 		box_file = design->scratchpad_get_string("abc9.box", box_file); | ||||||
|  | 		if (design->scratchpad.count("abc9.W")) { | ||||||
|  | 			wire_delay = "-W " + design->scratchpad_get_string("abc9.W"); | ||||||
|  | 		} | ||||||
|  | 		nomfs = design->scratchpad_get_bool("abc9.nomfs", nomfs); | ||||||
|  | 
 | ||||||
| 		size_t argidx; | 		size_t argidx; | ||||||
| 		for (argidx = 1; argidx < args.size(); argidx++) { | 		for (argidx = 1; argidx < args.size(); argidx++) { | ||||||
| 			std::string arg = args[argidx]; | 			std::string arg = args[argidx]; | ||||||
|  | @ -161,7 +175,7 @@ struct Abc9Pass : public ScriptPass | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (arg == "-fast" || /* arg == "-dff" || */ | 			if (arg == "-fast" || /* arg == "-dff" || */ | ||||||
| 					/* arg == "-nocleanup" || */ arg == "-showtmp" || arg == "-markgroups" || | 					/* arg == "-nocleanup" || */ arg == "-showtmp" || | ||||||
| 					arg == "-nomfs") { | 					arg == "-nomfs") { | ||||||
| 				map_cmd << " " << arg; | 				map_cmd << " " << arg; | ||||||
| 				continue; | 				continue; | ||||||
|  | @ -210,6 +224,10 @@ struct Abc9Pass : public ScriptPass | ||||||
| 				log("Skipping module %s as it contains processes.\n", log_id(mod)); | 				log("Skipping module %s as it contains processes.\n", log_id(mod)); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
|  | 			log_assert(!module->attributes.count(ID(abc9_box_id))); | ||||||
|  | 
 | ||||||
|  | 			if (!design->selected_whole_module(module)) | ||||||
|  | 				log_error("Can't handle partially selected module %s!\n", log_id(module)); | ||||||
| 
 | 
 | ||||||
| 			active_design->selection().select(mod); | 			active_design->selection().select(mod); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -63,7 +63,6 @@ extern "C" int Abc_RealMain(int argc, char *argv[]); | ||||||
| USING_YOSYS_NAMESPACE | USING_YOSYS_NAMESPACE | ||||||
| PRIVATE_NAMESPACE_BEGIN | PRIVATE_NAMESPACE_BEGIN | ||||||
| 
 | 
 | ||||||
| bool markgroups; |  | ||||||
| int map_autoidx; | int map_autoidx; | ||||||
| 
 | 
 | ||||||
| inline std::string remap_name(RTLIL::IdString abc9_name) | inline std::string remap_name(RTLIL::IdString abc9_name) | ||||||
|  | @ -349,11 +348,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip | ||||||
| 		if (mapped_mod == NULL) | 		if (mapped_mod == NULL) | ||||||
| 			log_error("ABC output file does not contain a module `$__abc9__'.\n"); | 			log_error("ABC output file does not contain a module `$__abc9__'.\n"); | ||||||
| 
 | 
 | ||||||
| 		for (auto &it : mapped_mod->wires_) { | 		for (auto wire : mapped_mod->wires()) | ||||||
| 			RTLIL::Wire *w = it.second; | 			module->addWire(remap_name(w->name), GetSize(w)); | ||||||
| 			RTLIL::Wire *remap_wire = module->addWire(remap_name(w->name), GetSize(w)); |  | ||||||
| 			if (markgroups) remap_wire->attributes[ID(abcgroup)] = map_autoidx; |  | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		for (auto it = module->cells_.begin(); it != module->cells_.end(); ) | 		for (auto it = module->cells_.begin(); it != module->cells_.end(); ) | ||||||
| 			if (it->second->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_))) | 			if (it->second->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_))) | ||||||
|  | @ -416,7 +412,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip | ||||||
| 				} | 				} | ||||||
| 				else | 				else | ||||||
| 					log_abort(); | 					log_abort(); | ||||||
| 				if (cell && markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; |  | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			cell_stats[mapped_cell->type]++; | 			cell_stats[mapped_cell->type]++; | ||||||
|  | @ -429,7 +424,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip | ||||||
| 					SigSpec my_a = module->wires_.at(remap_name(mapped_cell->getPort(ID::A).as_wire()->name)); | 					SigSpec my_a = module->wires_.at(remap_name(mapped_cell->getPort(ID::A).as_wire()->name)); | ||||||
| 					SigSpec my_y = module->wires_.at(remap_name(mapped_cell->getPort(ID::Y).as_wire()->name)); | 					SigSpec my_y = module->wires_.at(remap_name(mapped_cell->getPort(ID::Y).as_wire()->name)); | ||||||
| 					module->connect(my_y, my_a); | 					module->connect(my_y, my_a); | ||||||
| 					if (markgroups) mapped_cell->attributes[ID(abcgroup)] = map_autoidx; |  | ||||||
| 					log_abort(); | 					log_abort(); | ||||||
| 					continue; | 					continue; | ||||||
| 				} | 				} | ||||||
|  | @ -441,7 +435,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *module, std::string scrip | ||||||
| 				cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type); | 				cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; |  | ||||||
| 			if (existing_cell) { | 			if (existing_cell) { | ||||||
| 				cell->parameters = existing_cell->parameters; | 				cell->parameters = existing_cell->parameters; | ||||||
| 				cell->attributes = existing_cell->attributes; | 				cell->attributes = existing_cell->attributes; | ||||||
|  | @ -660,8 +653,6 @@ struct Abc9MapPass : public Pass { | ||||||
| 		log("        set delay target. the string {D} in the default scripts above is\n"); | 		log("        set delay target. the string {D} in the default scripts above is\n"); | ||||||
| 		log("        replaced by this option when used, and an empty string otherwise\n"); | 		log("        replaced by this option when used, and an empty string otherwise\n"); | ||||||
| 		log("        (indicating best possible delay).\n"); | 		log("        (indicating best possible delay).\n"); | ||||||
| //		log("        This also replaces 'dretime' with 'dretime; retime -o {D}' in the\n");
 |  | ||||||
| //		log("        default scripts above.\n");
 |  | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| //		log("    -S <num>\n");
 | //		log("    -S <num>\n");
 | ||||||
| //		log("        maximum number of LUT inputs shared.\n");
 | //		log("        maximum number of LUT inputs shared.\n");
 | ||||||
|  | @ -683,28 +674,14 @@ struct Abc9MapPass : 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("    -dff\n");
 | 		log("    -dff\n"); | ||||||
| //		log("        also pass $_DFF_?_ and $_DFFE_??_ cells through ABC. modules with many\n");
 | 		log("        also pass $_ABC9_FF_ cells through to ABC. modules with many clock\n"); | ||||||
| //		log("        clock domains are automatically partitioned in clock domains and each\n");
 | 		log("        domains are marked as such and automatically partitioned by ABC.\n"); | ||||||
| //		log("        domain is passed through ABC independently.\n");
 | 		log("\n"); | ||||||
| //		log("\n");
 |  | ||||||
| //		log("    -clk [!]<clock-signal-name>[,[!]<enable-signal-name>]\n");
 |  | ||||||
| //		log("        use only the specified clock domain. this is like -dff, but only FF\n");
 |  | ||||||
| //		log("        cells that belong to the specified clock domain are used.\n");
 |  | ||||||
| //		log("\n");
 |  | ||||||
| //		log("    -keepff\n");
 |  | ||||||
| //		log("        set the \"keep\" attribute on flip-flop output wires. (and thus preserve\n");
 |  | ||||||
| //		log("        them, for example for equivalence checking.)\n");
 |  | ||||||
| //		log("\n");
 |  | ||||||
| 		log("    -showtmp\n"); | 		log("    -showtmp\n"); | ||||||
| 		log("        print the temp dir name in log. usually this is suppressed so that the\n"); | 		log("        print the temp dir name in log. usually this is suppressed so that the\n"); | ||||||
| 		log("        command output is identical across runs.\n"); | 		log("        command output is identical across runs.\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("    -markgroups\n"); |  | ||||||
| 		log("        set a 'abcgroup' attribute on all objects created by ABC. The value of\n"); |  | ||||||
| 		log("        this attribute is a unique integer for each ABC process started. This\n"); |  | ||||||
| 		log("        is useful for debugging the partitioning of clock domains.\n"); |  | ||||||
| 		log("\n"); |  | ||||||
| 		log("    -box <file>\n"); | 		log("    -box <file>\n"); | ||||||
| 		log("        pass this file with box library to ABC. Use with -lut.\n"); | 		log("        pass this file with box library to ABC. Use with -lut.\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
|  | @ -737,7 +714,6 @@ struct Abc9MapPass : public Pass { | ||||||
| 		bool show_tempdir = false; | 		bool show_tempdir = false; | ||||||
| 		bool nomfs = false; | 		bool nomfs = false; | ||||||
| 		vector<int> lut_costs; | 		vector<int> lut_costs; | ||||||
| 		markgroups = false; |  | ||||||
| 
 | 
 | ||||||
| #if 0 | #if 0 | ||||||
| 		cleanup = false; | 		cleanup = false; | ||||||
|  | @ -828,10 +804,6 @@ struct Abc9MapPass : public Pass { | ||||||
| 				show_tempdir = true; | 				show_tempdir = true; | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			if (arg == "-markgroups") { |  | ||||||
| 				markgroups = true; |  | ||||||
| 				continue; |  | ||||||
| 			} |  | ||||||
| 			if (arg == "-box" && argidx+1 < args.size()) { | 			if (arg == "-box" && argidx+1 < args.size()) { | ||||||
| 				box_file = args[++argidx]; | 				box_file = args[++argidx]; | ||||||
| 				continue; | 				continue; | ||||||
|  | @ -871,6 +843,9 @@ struct Abc9MapPass : public Pass { | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | 			if (!design->selected_whole_module(mod)) | ||||||
|  | 				log_error("Can't handle partially selected module %s!\n", log_id(module)); | ||||||
|  | 
 | ||||||
| 			abc9_module(design, mod, script_file, exe_file, lut_costs, | 			abc9_module(design, mod, script_file, exe_file, lut_costs, | ||||||
| 					delay_target, lutin_shared, fast_mode, show_tempdir, | 					delay_target, lutin_shared, fast_mode, show_tempdir, | ||||||
| 					box_file, lut_file, wire_delay, nomfs, tempdir_name); | 					box_file, lut_file, wire_delay, nomfs, tempdir_name); | ||||||
|  |  | ||||||
|  | @ -128,6 +128,8 @@ static void run_ice40_opts(Module *module) | ||||||
| 							new_attr.insert(std::make_pair(a.first, a.second)); | 							new_attr.insert(std::make_pair(a.first, a.second)); | ||||||
| 						else if (a.first.in(ID(SB_LUT4.name), ID::keep, ID(module_not_derived))) | 						else if (a.first.in(ID(SB_LUT4.name), ID::keep, ID(module_not_derived))) | ||||||
| 							continue; | 							continue; | ||||||
|  | 						else if (a.first.begins_with("\\SB_CARRY.\\")) | ||||||
|  | 							continue; | ||||||
| 						else | 						else | ||||||
| 							log_abort(); | 							log_abort(); | ||||||
| 					cell->attributes = std::move(new_attr); | 					cell->attributes = std::move(new_attr); | ||||||
|  |  | ||||||
|  | @ -58,7 +58,7 @@ $__ABC9_ASYNC0 1000 1   2   1 | ||||||
| # Box 1001 : $__ABC9_ASYNC1 | # Box 1001 : $__ABC9_ASYNC1 | ||||||
| #            (private cell to emulate async behaviour of FDP*) | #            (private cell to emulate async behaviour of FDP*) | ||||||
| # name         ID   w/b ins outs | # name         ID   w/b ins outs | ||||||
| $__ABC9_ASYNC1 1001 1 2 1 | $__ABC9_ASYNC1 1001 1   2   1 | ||||||
| #A S | #A S | ||||||
| 0  764 # Y | 0  764 # Y | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue