mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +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,123 +1623,9 @@ struct AbcPass : public Pass {
 | 
			
		|||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (arg == "-g" && argidx+1 < args.size()) {
 | 
			
		||||
				for (auto g : split_tokens(args[++argidx], ",")) {
 | 
			
		||||
					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");
 | 
			
		||||
					}
 | 
			
		||||
					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);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				g_arg = args[++argidx];
 | 
			
		||||
				g_argidx = argidx;
 | 
			
		||||
				g_arg_from_cmd = true;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (arg == "-fast") {
 | 
			
		||||
| 
						 | 
				
			
			@ -1770,6 +1661,174 @@ struct AbcPass : public Pass {
 | 
			
		|||
		}
 | 
			
		||||
		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())
 | 
			
		||||
			log_cmd_error("Got -lut and -liberty! These two options are exclusive.\n");
 | 
			
		||||
		if (!constr_file.empty() && liberty_file.empty())
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,7 +58,7 @@ $__ABC9_ASYNC0 1000 1   2   1
 | 
			
		|||
# Box 1001 : $__ABC9_ASYNC1
 | 
			
		||||
#            (private cell to emulate async behaviour of FDP*)
 | 
			
		||||
# name         ID   w/b ins outs
 | 
			
		||||
$__ABC9_ASYNC1 1001 1 2 1
 | 
			
		||||
$__ABC9_ASYNC1 1001 1   2   1
 | 
			
		||||
#A S
 | 
			
		||||
0  764 # Y
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue