mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	Add "mutate -mode inv", various other mutate improvements
Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
		
							parent
							
								
									ea8ee24140
								
							
						
					
					
						commit
						8e6b69d7bb
					
				
					 1 changed files with 213 additions and 99 deletions
				
			
		|  | @ -34,10 +34,16 @@ struct mutate_opts_t { | ||||||
| 	std::string mode; | 	std::string mode; | ||||||
| 	IdString module, cell, port; | 	IdString module, cell, port; | ||||||
| 	int bit = -1; | 	int bit = -1; | ||||||
|  | 
 | ||||||
|  | 	IdString ctrl_name; | ||||||
|  | 	int ctrl_width, ctrl_value; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| void database_add(std::vector<mutate_t> &database, const mutate_opts_t &opts, const mutate_t &entry) | void database_add(std::vector<mutate_t> &database, const mutate_opts_t &opts, const mutate_t &entry) | ||||||
| { | { | ||||||
|  | 	if (!opts.mode.empty() && opts.mode != entry.mode) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
| 	if (!opts.module.empty() && opts.module != entry.modname) | 	if (!opts.module.empty() && opts.module != entry.modname) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
|  | @ -57,70 +63,8 @@ void database_reduce(std::vector<mutate_t> &database, const mutate_opts_t &opts, | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct MutatePass : public Pass { | void mutate_list(Design *design, const mutate_opts_t &opts, const string &filename, int N) | ||||||
| 	MutatePass() : Pass("mutate", "generate or apply design mutations") { } | { | ||||||
| 	void help() YS_OVERRIDE |  | ||||||
| 	{ |  | ||||||
| 		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 |  | ||||||
| 		log("\n"); |  | ||||||
| 		log("    mutate -list N [options] [selection]\n"); |  | ||||||
| 		log("\n"); |  | ||||||
| 		log("Create a list of N mutations using an even sampling.\n"); |  | ||||||
| 		log("\n"); |  | ||||||
| 		log("    -o filename\n"); |  | ||||||
| 		log("        Write list to this file instead of console output\n"); |  | ||||||
| 		log("\n"); |  | ||||||
| 		log("\n"); |  | ||||||
| 		log("    mutate -mode MODE [options]\n"); |  | ||||||
| 		log("\n"); |  | ||||||
| 		log("Apply the given mutation.\n"); |  | ||||||
| 		log("\n"); |  | ||||||
| 	} |  | ||||||
| 	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE |  | ||||||
| 	{ |  | ||||||
| 		mutate_opts_t opts; |  | ||||||
| 		string filename; |  | ||||||
| 		int N = -1; |  | ||||||
| 
 |  | ||||||
| 		log_header(design, "Executing MUTATE pass.\n"); |  | ||||||
| 
 |  | ||||||
| 		size_t argidx; |  | ||||||
| 		for (argidx = 1; argidx < args.size(); argidx++) |  | ||||||
| 		{ |  | ||||||
| 			if (args[argidx] == "-list" && argidx+1 < args.size()) { |  | ||||||
| 				N = atoi(args[++argidx].c_str()); |  | ||||||
| 				continue; |  | ||||||
| 			} |  | ||||||
| 			if (args[argidx] == "-o" && argidx+1 < args.size()) { |  | ||||||
| 				filename = args[++argidx]; |  | ||||||
| 				continue; |  | ||||||
| 			} |  | ||||||
| 			if (args[argidx] == "-mode" && argidx+1 < args.size()) { |  | ||||||
| 				opts.mode = args[++argidx]; |  | ||||||
| 				continue; |  | ||||||
| 			} |  | ||||||
| 			if (args[argidx] == "-module" && argidx+1 < args.size()) { |  | ||||||
| 				opts.module = RTLIL::escape_id(args[++argidx]); |  | ||||||
| 				continue; |  | ||||||
| 			} |  | ||||||
| 			if (args[argidx] == "-cell" && argidx+1 < args.size()) { |  | ||||||
| 				opts.cell = RTLIL::escape_id(args[++argidx]); |  | ||||||
| 				continue; |  | ||||||
| 			} |  | ||||||
| 			if (args[argidx] == "-port" && argidx+1 < args.size()) { |  | ||||||
| 				opts.port = RTLIL::escape_id(args[++argidx]); |  | ||||||
| 				continue; |  | ||||||
| 			} |  | ||||||
| 			if (args[argidx] == "-bit" && argidx+1 < args.size()) { |  | ||||||
| 				opts.bit = atoi(args[++argidx].c_str()); |  | ||||||
| 				continue; |  | ||||||
| 			} |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 		extra_args(args, argidx, design); |  | ||||||
| 
 |  | ||||||
| 		if (N >= 0) |  | ||||||
| 		{ |  | ||||||
| 	std::vector<mutate_t> database; | 	std::vector<mutate_t> database; | ||||||
| 
 | 
 | ||||||
| 	for (auto module : design->selected_modules()) | 	for (auto module : design->selected_modules()) | ||||||
|  | @ -218,7 +162,177 @@ struct MutatePass : public Pass { | ||||||
| 		else | 		else | ||||||
| 			fout << str << std::endl; | 			fout << str << std::endl; | ||||||
| 	} | 	} | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|  | SigSpec mutate_ctrl_sig(Module *module, IdString name, int width) | ||||||
|  | { | ||||||
|  | 	Wire *ctrl_wire = module->wire(name); | ||||||
|  | 
 | ||||||
|  | 	if (ctrl_wire == nullptr) | ||||||
|  | 	{ | ||||||
|  | 		log("Adding ctrl port %s to module %s.\n", log_id(name), log_id(module)); | ||||||
|  | 
 | ||||||
|  | 		ctrl_wire = module->addWire(name, width); | ||||||
|  | 		ctrl_wire->port_input = true; | ||||||
|  | 		module->fixup_ports(); | ||||||
|  | 
 | ||||||
|  | 		for (auto mod : module->design->modules()) | ||||||
|  | 		for (auto cell : mod->cells()) | ||||||
|  | 		{ | ||||||
|  | 			if (cell->type != module->name) | ||||||
|  | 				continue; | ||||||
|  | 
 | ||||||
|  | 			SigSpec ctrl = mutate_ctrl_sig(mod, name, width); | ||||||
|  | 
 | ||||||
|  | 			log("Connecting ctrl port to cell %s in module %s.\n", log_id(cell), log_id(mod)); | ||||||
|  | 			cell->setPort(name, ctrl); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	log_assert(GetSize(ctrl_wire) == width); | ||||||
|  | 	return ctrl_wire; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SigBit mutate_ctrl(Module *module, const mutate_opts_t &opts) | ||||||
|  | { | ||||||
|  | 	if (opts.ctrl_name.empty()) | ||||||
|  | 		return State::S1; | ||||||
|  | 
 | ||||||
|  | 	SigSpec sig = mutate_ctrl_sig(module, opts.ctrl_name, opts.ctrl_width); | ||||||
|  | 	return module->Eq(NEW_ID, sig, Const(opts.ctrl_value, GetSize(sig))); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SigSpec mutate_ctrl_mux(Module *module, const mutate_opts_t &opts, SigSpec unchanged_sig, SigSpec changed_sig) | ||||||
|  | { | ||||||
|  | 	SigBit ctrl_bit = mutate_ctrl(module, opts); | ||||||
|  | 	if (ctrl_bit == State::S0) | ||||||
|  | 		return unchanged_sig; | ||||||
|  | 	if (ctrl_bit == State::S1) | ||||||
|  | 		return changed_sig; | ||||||
|  | 	return module->Mux(NEW_ID, unchanged_sig, changed_sig, ctrl_bit); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void mutate_inv(Design *design, const mutate_opts_t &opts) | ||||||
|  | { | ||||||
|  | 	Module *module = design->module(opts.module); | ||||||
|  | 	Cell *cell = module->cell(opts.cell); | ||||||
|  | 
 | ||||||
|  | 	SigBit bit = cell->getPort(opts.port)[opts.bit]; | ||||||
|  | 	SigBit inbit, outbit; | ||||||
|  | 
 | ||||||
|  | 	if (cell->input(opts.port)) | ||||||
|  | 	{ | ||||||
|  | 		log("Add input inverter at %s.%s.%s[%d].\n", log_id(module), log_id(cell), log_id(opts.port), opts.bit); | ||||||
|  | 		SigBit outbit = module->Not(NEW_ID, bit); | ||||||
|  | 		bit = mutate_ctrl_mux(module, opts, bit, outbit); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		log("Add output inverter at %s.%s.%s[%d].\n", log_id(module), log_id(cell), log_id(opts.port), opts.bit); | ||||||
|  | 		SigBit inbit = module->addWire(NEW_ID); | ||||||
|  | 		SigBit outbit = module->Not(NEW_ID, inbit); | ||||||
|  | 		module->connect(bit, mutate_ctrl_mux(module, opts, inbit, outbit)); | ||||||
|  | 		bit = inbit; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	SigSpec s = cell->getPort(opts.port); | ||||||
|  | 	s[opts.bit] = bit; | ||||||
|  | 	cell->setPort(opts.port, s); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct MutatePass : public Pass { | ||||||
|  | 	MutatePass() : Pass("mutate", "generate or apply design mutations") { } | ||||||
|  | 	void help() YS_OVERRIDE | ||||||
|  | 	{ | ||||||
|  | 		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("    mutate -list N [options] [selection]\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("Create a list of N mutations using an even sampling.\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("    -o filename\n"); | ||||||
|  | 		log("        Write list to this file instead of console output\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("    -mode name\n"); | ||||||
|  | 		log("    -module name\n"); | ||||||
|  | 		log("    -cell name\n"); | ||||||
|  | 		log("    -port name\n"); | ||||||
|  | 		log("    -bit int\n"); | ||||||
|  | 		log("        Filter list of mutation candidates to those matching\n"); | ||||||
|  | 		log("        the given parameters.\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("    mutate -mode MODE [options]\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("Apply the given mutation.\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("    -ctrl name width value\n"); | ||||||
|  | 		log("        Add a control signal with the given name and width. The mutation is\n"); | ||||||
|  | 		log("        activated if the control signal equals the given value.\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("    -module name\n"); | ||||||
|  | 		log("    -cell name\n"); | ||||||
|  | 		log("    -port name\n"); | ||||||
|  | 		log("    -bit int\n"); | ||||||
|  | 		log("        Mutation parameters, as generated by 'mutate -list N'.\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 	} | ||||||
|  | 	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE | ||||||
|  | 	{ | ||||||
|  | 		mutate_opts_t opts; | ||||||
|  | 		string filename; | ||||||
|  | 		int N = -1; | ||||||
|  | 
 | ||||||
|  | 		log_header(design, "Executing MUTATE pass.\n"); | ||||||
|  | 
 | ||||||
|  | 		size_t argidx; | ||||||
|  | 		for (argidx = 1; argidx < args.size(); argidx++) | ||||||
|  | 		{ | ||||||
|  | 			if (args[argidx] == "-list" && argidx+1 < args.size()) { | ||||||
|  | 				N = atoi(args[++argidx].c_str()); | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			if (args[argidx] == "-o" && argidx+1 < args.size()) { | ||||||
|  | 				filename = args[++argidx]; | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			if (args[argidx] == "-mode" && argidx+1 < args.size()) { | ||||||
|  | 				opts.mode = args[++argidx]; | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			if (args[argidx] == "-ctrl" && argidx+3 < args.size()) { | ||||||
|  | 				opts.ctrl_name = RTLIL::escape_id(args[++argidx]); | ||||||
|  | 				opts.ctrl_width = atoi(args[++argidx].c_str()); | ||||||
|  | 				opts.ctrl_value = atoi(args[++argidx].c_str()); | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			if (args[argidx] == "-module" && argidx+1 < args.size()) { | ||||||
|  | 				opts.module = RTLIL::escape_id(args[++argidx]); | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			if (args[argidx] == "-cell" && argidx+1 < args.size()) { | ||||||
|  | 				opts.cell = RTLIL::escape_id(args[++argidx]); | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			if (args[argidx] == "-port" && argidx+1 < args.size()) { | ||||||
|  | 				opts.port = RTLIL::escape_id(args[++argidx]); | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			if (args[argidx] == "-bit" && argidx+1 < args.size()) { | ||||||
|  | 				opts.bit = atoi(args[++argidx].c_str()); | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		extra_args(args, argidx, design); | ||||||
|  | 
 | ||||||
|  | 		if (N >= 0) { | ||||||
|  | 			mutate_list(design, opts, filename, N); | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (opts.mode == "inv") { | ||||||
|  | 			mutate_inv(design, opts); | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue