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 | ||||
|   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 | ||||
|   during techmapping. | ||||
|   during `abc9` techmapping. | ||||
| 
 | ||||
| - 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 | ||||
|   ``always_ff`` on processes derived from SystemVerilog style always blocks | ||||
|  |  | |||
|  | @ -787,6 +787,14 @@ struct AigerBackend : public Backend { | |||
| 		if (top_module == nullptr) | ||||
| 			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); | ||||
| 		writer.write_aiger(*f, ascii_mode, miter_mode, symbols_mode); | ||||
| 
 | ||||
|  |  | |||
|  | @ -137,7 +137,7 @@ struct XAigerWriter | |||
| 		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> unused_bits; | ||||
|  | @ -157,12 +157,8 @@ struct XAigerWriter | |||
| 			if (wire->get_bool_attribute(ID::keep)) | ||||
| 				sigmap.add(wire); | ||||
| 
 | ||||
| 		// First, collect all the ports in port_id order
 | ||||
| 		//   since module->wires() could be sorted
 | ||||
| 		//   alphabetically
 | ||||
| 		for (auto port : module->ports) { | ||||
| 			auto wire = module->wire(port); | ||||
| 			log_assert(wire); | ||||
| 
 | ||||
| 		for (auto wire : module->wires()) | ||||
| 			for (int i = 0; i < GetSize(wire); i++) | ||||
| 			{ | ||||
| 				SigBit wirebit(wire, i); | ||||
|  | @ -176,6 +172,9 @@ struct XAigerWriter | |||
| 					continue; | ||||
| 				} | ||||
| 
 | ||||
| 				undriven_bits.insert(bit); | ||||
| 				unused_bits.insert(bit); | ||||
| 
 | ||||
| 				if (wire->port_input) | ||||
| 					input_bits.insert(bit); | ||||
| 
 | ||||
|  | @ -185,19 +184,6 @@ struct XAigerWriter | |||
| 					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()) { | ||||
| 			if (cell->type == "$_NOT_") | ||||
|  | @ -402,12 +388,20 @@ struct XAigerWriter | |||
| 			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::S1] = 1; | ||||
| 
 | ||||
| 		// pool<> iterates in LIFO order...
 | ||||
| 		for (int i = input_bits.size()-1; i >= 0; i--) { | ||||
| 			const auto &bit = *input_bits.element(i); | ||||
| 		for (const auto &bit : input_bits) { | ||||
| 			aig_m++, aig_i++; | ||||
| 			log_assert(!aig_map.count(bit)); | ||||
| 			aig_map[bit] = 2*aig_m; | ||||
|  | @ -435,9 +429,7 @@ struct XAigerWriter | |||
| 			aig_outputs.push_back(bit2aig(bit)); | ||||
| 		} | ||||
| 
 | ||||
| 		// pool<> iterates in LIFO order...
 | ||||
| 		for (int i = output_bits.size()-1; i >= 0; i--) { | ||||
| 			const auto &bit = *output_bits.element(i); | ||||
| 		for (const auto &bit : output_bits) { | ||||
| 			ordered_outputs[bit] = aig_o++; | ||||
| 			aig_outputs.push_back(bit2aig(bit)); | ||||
| 		} | ||||
|  | @ -618,7 +610,7 @@ struct XAigerWriter | |||
| 
 | ||||
| 			if (holes_module) { | ||||
| 				std::stringstream a_buffer; | ||||
| 				XAigerWriter writer(holes_module); | ||||
| 				XAigerWriter writer(holes_module, true /* holes_mode */); | ||||
| 				writer.write_aiger(a_buffer, false /*ascii_mode*/); | ||||
| 
 | ||||
| 				f << "a"; | ||||
|  | @ -654,17 +646,13 @@ struct XAigerWriter | |||
| 		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> output_lines; | ||||
| 		dict<int, string> wire_lines; | ||||
| 
 | ||||
| 		for (auto wire : module->wires()) | ||||
| 		{ | ||||
| 			//if (!verbose_map && wire->name[0] == '$')
 | ||||
| 			//	continue;
 | ||||
| 
 | ||||
| 			SigSpec sig = sigmap(wire); | ||||
| 
 | ||||
| 			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); | ||||
| 					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) | ||||
| 			f << it.second; | ||||
| 		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("    write_xaiger [options] [filename]\n"); | ||||
| 		log("\n"); | ||||
| 		log("Write the current design to an XAIGER file. The design must be flattened and\n"); | ||||
| 		log("all unsupported cells will be converted into psuedo-inputs and pseudo-outputs.\n"); | ||||
| 		log("Write the top module (according to the (* top *) attribute or if only one module\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("    -ascii\n"); | ||||
| 		log("        write ASCII version of AIGER format\n"); | ||||
|  | @ -730,14 +708,10 @@ struct XAigerBackend : public Backend { | |||
| 		log("    -map <filename>\n"); | ||||
| 		log("        write an extra file with port and box symbols\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 | ||||
| 	{ | ||||
| 		bool ascii_mode = false; | ||||
| 		bool verbose_map = false; | ||||
| 		std::string map_filename; | ||||
| 
 | ||||
| 		log_header(design, "Executing XAIGER backend.\n"); | ||||
|  | @ -753,11 +727,6 @@ struct XAigerBackend : public Backend { | |||
| 				map_filename = args[++argidx]; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (map_filename.empty() && args[argidx] == "-vmap" && argidx+1 < args.size()) { | ||||
| 				map_filename = args[++argidx]; | ||||
| 				verbose_map = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
| 		extra_args(f, filename, args, argidx, !ascii_mode); | ||||
|  | @ -767,6 +736,14 @@ struct XAigerBackend : public Backend { | |||
| 		if (top_module == nullptr) | ||||
| 			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); | ||||
| 		writer.write_aiger(*f, ascii_mode); | ||||
| 
 | ||||
|  | @ -775,7 +752,7 @@ struct XAigerBackend : public Backend { | |||
| 			mapf.open(map_filename.c_str(), std::ofstream::trunc); | ||||
| 			if (mapf.fail()) | ||||
| 				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; | ||||
|  |  | |||
|  | @ -1514,7 +1514,47 @@ struct AbcPass : public Pass { | |||
| #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]; | ||||
| 		if (!getcwd(pwd, sizeof(pwd))) { | ||||
| 			log_cmd_error("getcwd failed: %s\n", strerror(errno)); | ||||
|  | @ -1528,23 +1568,14 @@ struct AbcPass : public Pass { | |||
| 			} | ||||
| 			if (arg == "-script" && argidx+1 < args.size()) { | ||||
| 				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; | ||||
| 			} | ||||
| 			if (arg == "-liberty" && argidx+1 < args.size()) { | ||||
| 				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; | ||||
| 			} | ||||
| 			if (arg == "-constr" && argidx+1 < args.size()) { | ||||
| 				rewrite_filename(constr_file); | ||||
| 				constr_file = args[++argidx]; | ||||
| 				if (!constr_file.empty() && !is_absolute_path(constr_file)) | ||||
| 					constr_file = std::string(pwd) + "/" + constr_file; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-D" && argidx+1 < args.size()) { | ||||
|  | @ -1564,37 +1595,11 @@ struct AbcPass : public Pass { | |||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-lut" && argidx+1 < args.size()) { | ||||
| 				string 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)); | ||||
| 				lut_arg = args[++argidx]; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-luts" && argidx+1 < args.size()) { | ||||
| 				lut_costs.clear(); | ||||
| 				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"); | ||||
| 				} | ||||
| 				luts_arg = args[++argidx]; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-sop") { | ||||
|  | @ -1618,7 +1623,91 @@ struct AbcPass : public Pass { | |||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-g" && argidx+1 < args.size()) { | ||||
| 				for (auto g : split_tokens(args[++argidx], ",")) { | ||||
| 				g_arg = args[++argidx]; | ||||
| 				g_argidx = argidx; | ||||
| 				g_arg_from_cmd = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-fast") { | ||||
| 				fast_mode = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-dff") { | ||||
| 				dff_mode = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-clk" && argidx+1 < args.size()) { | ||||
| 				clk_str = args[++argidx]; | ||||
| 				dff_mode = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-keepff") { | ||||
| 				keepff = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-nocleanup") { | ||||
| 				cleanup = false; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-showtmp") { | ||||
| 				show_tempdir = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-markgroups") { | ||||
| 				markgroups = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
| 		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] == '-') { | ||||
|  | @ -1724,7 +1813,10 @@ struct AbcPass : public Pass { | |||
| 					gate_list.push_back("MUX"); | ||||
| 					gate_list.push_back("NMUX"); | ||||
| 				} | ||||
| 					cmd_error(args, argidx, stringf("Unsupported gate type: %s", g.c_str())); | ||||
| 				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: | ||||
|  | @ -1735,40 +1827,7 @@ struct AbcPass : public Pass { | |||
| 						enabled_gates.insert(gate); | ||||
| 				} | ||||
| 			} | ||||
| 				continue; | ||||
| 		} | ||||
| 			if (arg == "-fast") { | ||||
| 				fast_mode = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-dff") { | ||||
| 				dff_mode = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-clk" && argidx+1 < args.size()) { | ||||
| 				clk_str = args[++argidx]; | ||||
| 				dff_mode = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-keepff") { | ||||
| 				keepff = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-nocleanup") { | ||||
| 				cleanup = false; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-showtmp") { | ||||
| 				show_tempdir = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-markgroups") { | ||||
| 				markgroups = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
| 		extra_args(args, argidx, design); | ||||
| 
 | ||||
| 		if (!lut_costs.empty() && !liberty_file.empty()) | ||||
| 			log_cmd_error("Got -lut and -liberty! These two options are exclusive.\n"); | ||||
|  |  | |||
|  | @ -40,7 +40,7 @@ struct Abc9Pass : public ScriptPass | |||
| 		log("    abc9 [options] [selection]\n"); | ||||
| 		log("\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("    -exe <command>\n"); | ||||
| #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("        command output is identical across runs.\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("        pass this file with box library to ABC. Use with -lut.\n"); | ||||
| 		log("\n"); | ||||
|  | @ -150,6 +145,25 @@ struct Abc9Pass : public ScriptPass | |||
| 		std::string run_from, run_to; | ||||
| 		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; | ||||
| 		for (argidx = 1; argidx < args.size(); argidx++) { | ||||
| 			std::string arg = args[argidx]; | ||||
|  | @ -161,7 +175,7 @@ struct Abc9Pass : public ScriptPass | |||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-fast" || /* arg == "-dff" || */ | ||||
| 					/* arg == "-nocleanup" || */ arg == "-showtmp" || arg == "-markgroups" || | ||||
| 					/* arg == "-nocleanup" || */ arg == "-showtmp" || | ||||
| 					arg == "-nomfs") { | ||||
| 				map_cmd << " " << arg; | ||||
| 				continue; | ||||
|  | @ -210,6 +224,10 @@ struct Abc9Pass : public ScriptPass | |||
| 				log("Skipping module %s as it contains processes.\n", log_id(mod)); | ||||
| 				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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -63,7 +63,6 @@ extern "C" int Abc_RealMain(int argc, char *argv[]); | |||
| USING_YOSYS_NAMESPACE | ||||
| PRIVATE_NAMESPACE_BEGIN | ||||
| 
 | ||||
| bool markgroups; | ||||
| int map_autoidx; | ||||
| 
 | ||||
| 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) | ||||
| 			log_error("ABC output file does not contain a module `$__abc9__'.\n"); | ||||
| 
 | ||||
| 		for (auto &it : mapped_mod->wires_) { | ||||
| 			RTLIL::Wire *w = it.second; | ||||
| 			RTLIL::Wire *remap_wire = module->addWire(remap_name(w->name), GetSize(w)); | ||||
| 			if (markgroups) remap_wire->attributes[ID(abcgroup)] = map_autoidx; | ||||
| 		} | ||||
| 		for (auto wire : mapped_mod->wires()) | ||||
| 			module->addWire(remap_name(w->name), GetSize(w)); | ||||
| 
 | ||||
| 		for (auto it = module->cells_.begin(); it != module->cells_.end(); ) | ||||
| 			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 | ||||
| 					log_abort(); | ||||
| 				if (cell && markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; | ||||
| 				continue; | ||||
| 			} | ||||
| 			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_y = module->wires_.at(remap_name(mapped_cell->getPort(ID::Y).as_wire()->name)); | ||||
| 					module->connect(my_y, my_a); | ||||
| 					if (markgroups) mapped_cell->attributes[ID(abcgroup)] = map_autoidx; | ||||
| 					log_abort(); | ||||
| 					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); | ||||
| 			} | ||||
| 
 | ||||
| 			if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx; | ||||
| 			if (existing_cell) { | ||||
| 				cell->parameters = existing_cell->parameters; | ||||
| 				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("        replaced by this option when used, and an empty string otherwise\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("    -S <num>\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("        2, 3, .. inputs.\n"); | ||||
| 		log("\n"); | ||||
| //		log("    -dff\n");
 | ||||
| //		log("        also pass $_DFF_?_ and $_DFFE_??_ cells through ABC. modules with many\n");
 | ||||
| //		log("        clock domains are automatically partitioned in clock domains and each\n");
 | ||||
| //		log("        domain is passed through ABC independently.\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("    -dff\n"); | ||||
| 		log("        also pass $_ABC9_FF_ cells through to ABC. modules with many clock\n"); | ||||
| 		log("        domains are marked as such and automatically partitioned by ABC.\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -showtmp\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("\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("        pass this file with box library to ABC. Use with -lut.\n"); | ||||
| 		log("\n"); | ||||
|  | @ -737,7 +714,6 @@ struct Abc9MapPass : public Pass { | |||
| 		bool show_tempdir = false; | ||||
| 		bool nomfs = false; | ||||
| 		vector<int> lut_costs; | ||||
| 		markgroups = false; | ||||
| 
 | ||||
| #if 0 | ||||
| 		cleanup = false; | ||||
|  | @ -828,10 +804,6 @@ struct Abc9MapPass : public Pass { | |||
| 				show_tempdir = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-markgroups") { | ||||
| 				markgroups = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-box" && argidx+1 < args.size()) { | ||||
| 				box_file = args[++argidx]; | ||||
| 				continue; | ||||
|  | @ -871,6 +843,9 @@ struct Abc9MapPass : public Pass { | |||
| 				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, | ||||
| 					delay_target, lutin_shared, fast_mode, show_tempdir, | ||||
| 					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)); | ||||
| 						else if (a.first.in(ID(SB_LUT4.name), ID::keep, ID(module_not_derived))) | ||||
| 							continue; | ||||
| 						else if (a.first.begins_with("\\SB_CARRY.\\")) | ||||
| 							continue; | ||||
| 						else | ||||
| 							log_abort(); | ||||
| 					cell->attributes = std::move(new_attr); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue