mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	This commit is contained in:
		
						commit
						d57c85111f
					
				
					 6 changed files with 169 additions and 78 deletions
				
			
		|  | @ -216,6 +216,7 @@ int main(int argc, char **argv) | ||||||
| 		printf("    -D <header_id>[:<filename>]\n"); | 		printf("    -D <header_id>[:<filename>]\n"); | ||||||
| 		printf("        dump the design when printing the specified log header to a file.\n"); | 		printf("        dump the design when printing the specified log header to a file.\n"); | ||||||
| 		printf("        yosys_dump_<header_id>.il is used as filename if none is specified.\n"); | 		printf("        yosys_dump_<header_id>.il is used as filename if none is specified.\n"); | ||||||
|  | 		printf("        Use 'ALL' as <header_id> to dump at every header.\n"); | ||||||
| 		printf("\n"); | 		printf("\n"); | ||||||
| 		printf("    -V\n"); | 		printf("    -V\n"); | ||||||
| 		printf("        print version information and exit\n"); | 		printf("        print version information and exit\n"); | ||||||
|  | @ -322,6 +323,15 @@ int main(int argc, char **argv) | ||||||
| 		case 'D': | 		case 'D': | ||||||
| 			{ | 			{ | ||||||
| 				auto args = split_tokens(optarg, ":"); | 				auto args = split_tokens(optarg, ":"); | ||||||
|  | 				if (!args.empty() && args[0] == "ALL") { | ||||||
|  | 					if (GetSize(args) != 1) { | ||||||
|  | 						fprintf(stderr, "Invalid number of tokens in -D ALL.\n"); | ||||||
|  | 						exit(1); | ||||||
|  | 					} | ||||||
|  | 					log_hdump_all = true; | ||||||
|  | 				} else { | ||||||
|  | 					if (!args.empty() && !args[0].empty() && args[0].back() == '.') | ||||||
|  | 						args[0].pop_back(); | ||||||
| 					if (GetSize(args) == 1) | 					if (GetSize(args) == 1) | ||||||
| 						args.push_back("yosys_dump_" + args[0] + ".il"); | 						args.push_back("yosys_dump_" + args[0] + ".il"); | ||||||
| 					if (GetSize(args) != 2) { | 					if (GetSize(args) != 2) { | ||||||
|  | @ -330,6 +340,7 @@ int main(int argc, char **argv) | ||||||
| 					} | 					} | ||||||
| 					log_hdump[args[0]].insert(args[1]); | 					log_hdump[args[0]].insert(args[1]); | ||||||
| 				} | 				} | ||||||
|  | 			} | ||||||
| 			break; | 			break; | ||||||
| 		default: | 		default: | ||||||
| 			fprintf(stderr, "Run '%s -h' for help.\n", argv[0]); | 			fprintf(stderr, "Run '%s -h' for help.\n", argv[0]); | ||||||
|  |  | ||||||
|  | @ -41,6 +41,7 @@ YOSYS_NAMESPACE_BEGIN | ||||||
| std::vector<FILE*> log_files; | std::vector<FILE*> log_files; | ||||||
| std::vector<std::ostream*> log_streams; | std::vector<std::ostream*> log_streams; | ||||||
| std::map<std::string, std::set<std::string>> log_hdump; | std::map<std::string, std::set<std::string>> log_hdump; | ||||||
|  | bool log_hdump_all = false; | ||||||
| FILE *log_errfile = NULL; | FILE *log_errfile = NULL; | ||||||
| SHA1 *log_hasher = NULL; | SHA1 *log_hasher = NULL; | ||||||
| 
 | 
 | ||||||
|  | @ -159,6 +160,9 @@ void logv_header(RTLIL::Design *design, const char *format, va_list ap) | ||||||
| 	logv(format, ap); | 	logv(format, ap); | ||||||
| 	log_flush(); | 	log_flush(); | ||||||
| 
 | 
 | ||||||
|  | 	if (log_hdump_all) | ||||||
|  | 		log_hdump[header_id].insert("yosys_dump_" + header_id + ".il"); | ||||||
|  | 
 | ||||||
| 	if (log_hdump.count(header_id) && design != nullptr) | 	if (log_hdump.count(header_id) && design != nullptr) | ||||||
| 		for (auto &filename : log_hdump.at(header_id)) { | 		for (auto &filename : log_hdump.at(header_id)) { | ||||||
| 			log("Dumping current design to '%s'.\n", filename.c_str()); | 			log("Dumping current design to '%s'.\n", filename.c_str()); | ||||||
|  |  | ||||||
|  | @ -48,6 +48,7 @@ struct log_cmd_error_exception { }; | ||||||
| extern std::vector<FILE*> log_files; | extern std::vector<FILE*> log_files; | ||||||
| extern std::vector<std::ostream*> log_streams; | extern std::vector<std::ostream*> log_streams; | ||||||
| extern std::map<std::string, std::set<std::string>> log_hdump; | extern std::map<std::string, std::set<std::string>> log_hdump; | ||||||
|  | extern bool log_hdump_all; | ||||||
| extern FILE *log_errfile; | extern FILE *log_errfile; | ||||||
| extern SHA1 *log_hasher; | extern SHA1 *log_hasher; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -33,6 +33,7 @@ struct proc_dlatch_db_t | ||||||
| 	Module *module; | 	Module *module; | ||||||
| 	SigMap sigmap; | 	SigMap sigmap; | ||||||
| 
 | 
 | ||||||
|  | 	dict<Cell*, vector<SigBit>> mux_srcbits; | ||||||
| 	dict<SigBit, pair<Cell*, int>> mux_drivers; | 	dict<SigBit, pair<Cell*, int>> mux_drivers; | ||||||
| 	dict<SigBit, int> sigusers; | 	dict<SigBit, int> sigusers; | ||||||
| 
 | 
 | ||||||
|  | @ -40,10 +41,24 @@ struct proc_dlatch_db_t | ||||||
| 	{ | 	{ | ||||||
| 		for (auto cell : module->cells()) | 		for (auto cell : module->cells()) | ||||||
| 		{ | 		{ | ||||||
| 			if (cell->type.in("$mux", "$pmux")) { | 			if (cell->type.in("$mux", "$pmux")) | ||||||
|  | 			{ | ||||||
| 				auto sig_y = sigmap(cell->getPort("\\Y")); | 				auto sig_y = sigmap(cell->getPort("\\Y")); | ||||||
| 				for (int i = 0; i < GetSize(sig_y); i++) | 				for (int i = 0; i < GetSize(sig_y); i++) | ||||||
| 					mux_drivers[sig_y[i]] = pair<Cell*, int>(cell, i); | 					mux_drivers[sig_y[i]] = pair<Cell*, int>(cell, i); | ||||||
|  | 
 | ||||||
|  | 				pool<SigBit> mux_srcbits_pool; | ||||||
|  | 				for (auto bit : sigmap(cell->getPort("\\A"))) | ||||||
|  | 					mux_srcbits_pool.insert(bit); | ||||||
|  | 				for (auto bit : sigmap(cell->getPort("\\B"))) | ||||||
|  | 					mux_srcbits_pool.insert(bit); | ||||||
|  | 
 | ||||||
|  | 				vector<SigBit> mux_srcbits_vec; | ||||||
|  | 				for (auto bit : mux_srcbits_pool) | ||||||
|  | 					if (bit.wire != nullptr) | ||||||
|  | 						mux_srcbits_vec.push_back(bit); | ||||||
|  | 
 | ||||||
|  | 				mux_srcbits[cell].swap(mux_srcbits_vec); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			for (auto &conn : cell->connections()) | 			for (auto &conn : cell->connections()) | ||||||
|  | @ -58,6 +73,42 @@ struct proc_dlatch_db_t | ||||||
| 					sigusers[bit]++; | 					sigusers[bit]++; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	bool quickcheck(const SigSpec &haystack, const SigSpec &needle) | ||||||
|  | 	{ | ||||||
|  | 		pool<SigBit> haystack_bits = sigmap(haystack).to_sigbit_pool(); | ||||||
|  | 		pool<SigBit> needle_bits = sigmap(needle).to_sigbit_pool(); | ||||||
|  | 
 | ||||||
|  | 		pool<Cell*> cells_queue, cells_visited; | ||||||
|  | 		pool<SigBit> bits_queue, bits_visited; | ||||||
|  | 
 | ||||||
|  | 		bits_queue = haystack_bits; | ||||||
|  | 		while (!bits_queue.empty()) | ||||||
|  | 		{ | ||||||
|  | 			for (auto &bit : bits_queue) { | ||||||
|  | 				auto it = mux_drivers.find(bit); | ||||||
|  | 				if (it != mux_drivers.end()) | ||||||
|  | 					if (!cells_visited.count(it->second.first)) | ||||||
|  | 						cells_queue.insert(it->second.first); | ||||||
|  | 				bits_visited.insert(bit); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			bits_queue.clear(); | ||||||
|  | 
 | ||||||
|  | 			for (auto c : cells_queue) { | ||||||
|  | 				for (auto bit : mux_srcbits[c]) { | ||||||
|  | 					if (needle_bits.count(bit)) | ||||||
|  | 						return true; | ||||||
|  | 					if (!bits_visited.count(bit)) | ||||||
|  | 						bits_queue.insert(bit); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			cells_queue.clear(); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	struct rule_node_t | 	struct rule_node_t | ||||||
| 	{ | 	{ | ||||||
| 		// a node is true if "signal" equals "match" and [any
 | 		// a node is true if "signal" equals "match" and [any
 | ||||||
|  | @ -218,9 +269,17 @@ void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc) | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for (auto ss : sr->actions) { | 		for (auto ss : sr->actions) | ||||||
|  | 		{ | ||||||
| 			db.sigmap.apply(ss.first); | 			db.sigmap.apply(ss.first); | ||||||
| 			db.sigmap.apply(ss.second); | 			db.sigmap.apply(ss.second); | ||||||
|  | 
 | ||||||
|  | 			if (!db.quickcheck(ss.second, ss.first)) { | ||||||
|  | 				nolatches_bits.first.append(ss.first); | ||||||
|  | 				nolatches_bits.second.append(ss.second); | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
| 			for (int i = 0; i < GetSize(ss.first); i++) | 			for (int i = 0; i < GetSize(ss.first); i++) | ||||||
| 				latches_out_in[ss.first[i]] = ss.second[i]; | 				latches_out_in[ss.first[i]] = ss.second[i]; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -25,22 +25,11 @@ | ||||||
| USING_YOSYS_NAMESPACE | USING_YOSYS_NAMESPACE | ||||||
| PRIVATE_NAMESPACE_BEGIN | PRIVATE_NAMESPACE_BEGIN | ||||||
| 
 | 
 | ||||||
| bool check_label(bool &active, std::string run_from, std::string run_to, std::string label) | struct PrepPass : public ScriptPass | ||||||
| { | { | ||||||
| 	if (!run_from.empty() && run_from == run_to) { | 	PrepPass() : ScriptPass("prep", "generic synthesis script") { } | ||||||
| 		active = (label == run_from); |  | ||||||
| 	} else { |  | ||||||
| 		if (label == run_from) |  | ||||||
| 			active = true; |  | ||||||
| 		if (label == run_to) |  | ||||||
| 			active = false; |  | ||||||
| 	} |  | ||||||
| 	return active; |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| struct PrepPass : public Pass { | 	virtual void help() YS_OVERRIDE | ||||||
| 	PrepPass() : Pass("prep", "generic synthesis script") { } |  | ||||||
| 	virtual void help() |  | ||||||
| 	{ | 	{ | ||||||
| 		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 | 		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
|  | @ -53,6 +42,10 @@ struct PrepPass : public Pass { | ||||||
| 		log("    -top <module>\n"); | 		log("    -top <module>\n"); | ||||||
| 		log("        use the specified module as top module (default='top')\n"); | 		log("        use the specified module as top module (default='top')\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
|  | 		log("    -flatten\n"); | ||||||
|  | 		log("        flatten the design before synthesis. this will pass '-auto-top' to\n"); | ||||||
|  | 		log("        'hierarchy' if no top module is specified.\n"); | ||||||
|  | 		log("\n"); | ||||||
| 		log("    -nordff\n"); | 		log("    -nordff\n"); | ||||||
| 		log("        passed to 'memory_dff'. prohibits merging of FFs into memory read ports\n"); | 		log("        passed to 'memory_dff'. prohibits merging of FFs into memory read ports\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
|  | @ -63,31 +56,23 @@ struct PrepPass : public Pass { | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("The following commands are executed by this synthesis command:\n"); | 		log("The following commands are executed by this synthesis command:\n"); | ||||||
| 		log("\n"); | 		help_script(); | ||||||
| 		log("    begin:\n"); |  | ||||||
| 		log("        hierarchy -check [-top <top>]\n"); |  | ||||||
| 		log("\n"); |  | ||||||
| 		log("    prep:\n"); |  | ||||||
| 		log("        proc\n"); |  | ||||||
| 		log("        opt_expr -keepdc\n"); |  | ||||||
| 		log("        opt_clean\n"); |  | ||||||
| 		log("        check\n"); |  | ||||||
| 		log("        opt -keepdc\n"); |  | ||||||
| 		log("        wreduce\n"); |  | ||||||
| 		log("        memory_dff [-nordff]\n"); |  | ||||||
| 		log("        opt_clean\n"); |  | ||||||
| 		log("        memory_collect\n"); |  | ||||||
| 		log("        opt -keepdc -fast\n"); |  | ||||||
| 		log("\n"); |  | ||||||
| 		log("    check:\n"); |  | ||||||
| 		log("        stat\n"); |  | ||||||
| 		log("        check\n"); |  | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 	} | 	} | ||||||
| 	virtual void execute(std::vector<std::string> args, RTLIL::Design *design) | 
 | ||||||
|  | 	string top_module, fsm_opts, memory_opts; | ||||||
|  | 	bool flatten; | ||||||
|  | 
 | ||||||
|  | 	virtual void clear_flags() YS_OVERRIDE | ||||||
| 	{ | 	{ | ||||||
| 		std::string top_module, memory_opts; | 		top_module.clear(); | ||||||
| 		std::string run_from, run_to; | 		memory_opts.clear(); | ||||||
|  | 		flatten = false; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	virtual void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE | ||||||
|  | 	{ | ||||||
|  | 		string run_from, run_to; | ||||||
| 
 | 
 | ||||||
| 		size_t argidx; | 		size_t argidx; | ||||||
| 		for (argidx = 1; argidx < args.size(); argidx++) | 		for (argidx = 1; argidx < args.size(); argidx++) | ||||||
|  | @ -107,6 +92,10 @@ struct PrepPass : public Pass { | ||||||
| 				} | 				} | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
|  | 			if (args[argidx] == "-flatten") { | ||||||
|  | 				flatten = true; | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
| 			if (args[argidx] == "-nordff") { | 			if (args[argidx] == "-nordff") { | ||||||
| 				memory_opts += " -nordff"; | 				memory_opts += " -nordff"; | ||||||
| 				continue; | 				continue; | ||||||
|  | @ -118,41 +107,54 @@ struct PrepPass : public Pass { | ||||||
| 		if (!design->full_selection()) | 		if (!design->full_selection()) | ||||||
| 			log_cmd_error("This comannd only operates on fully selected designs!\n"); | 			log_cmd_error("This comannd only operates on fully selected designs!\n"); | ||||||
| 
 | 
 | ||||||
| 		bool active = run_from.empty(); |  | ||||||
| 
 |  | ||||||
| 		log_header(design, "Executing PREP pass.\n"); | 		log_header(design, "Executing PREP pass.\n"); | ||||||
| 		log_push(); | 		log_push(); | ||||||
| 
 | 
 | ||||||
| 		if (check_label(active, run_from, run_to, "begin")) | 		run_script(design, run_from, run_to); | ||||||
| 		{ |  | ||||||
| 			if (top_module.empty()) |  | ||||||
| 				Pass::call(design, stringf("hierarchy -check")); |  | ||||||
| 			else |  | ||||||
| 				Pass::call(design, stringf("hierarchy -check -top %s", top_module.c_str())); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (check_label(active, run_from, run_to, "coarse")) |  | ||||||
| 		{ |  | ||||||
| 			Pass::call(design, "proc"); |  | ||||||
| 			Pass::call(design, "opt_expr -keepdc"); |  | ||||||
| 			Pass::call(design, "opt_clean"); |  | ||||||
| 			Pass::call(design, "check"); |  | ||||||
| 			Pass::call(design, "opt -keepdc"); |  | ||||||
| 			Pass::call(design, "wreduce"); |  | ||||||
| 			Pass::call(design, "memory_dff" + memory_opts); |  | ||||||
| 			Pass::call(design, "opt_clean"); |  | ||||||
| 			Pass::call(design, "memory_collect"); |  | ||||||
| 			Pass::call(design, "opt -keepdc -fast"); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if (check_label(active, run_from, run_to, "check")) |  | ||||||
| 		{ |  | ||||||
| 			Pass::call(design, "stat"); |  | ||||||
| 			Pass::call(design, "check"); |  | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		log_pop(); | 		log_pop(); | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	virtual void script() YS_OVERRIDE | ||||||
|  | 	{ | ||||||
|  | 
 | ||||||
|  | 		if (check_label("begin")) | ||||||
|  | 		{ | ||||||
|  | 			if (help_mode) { | ||||||
|  | 				run("hierarchy -check [-top <top>]"); | ||||||
|  | 			} else { | ||||||
|  | 				if (top_module.empty()) { | ||||||
|  | 					if (flatten) | ||||||
|  | 						run("hierarchy -check -auto-top"); | ||||||
|  | 					else | ||||||
|  | 						run("hierarchy -check"); | ||||||
|  | 				} else | ||||||
|  | 					run(stringf("hierarchy -check -top %s", top_module.c_str())); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (check_label("coarse")) | ||||||
|  | 		{ | ||||||
|  | 			run("proc"); | ||||||
|  | 			if (help_mode || flatten) | ||||||
|  | 				run("flatten", "(if -flatten)"); | ||||||
|  | 			run("opt_expr -keepdc"); | ||||||
|  | 			run("opt_clean"); | ||||||
|  | 			run("check"); | ||||||
|  | 			run("opt -keepdc"); | ||||||
|  | 			run("wreduce"); | ||||||
|  | 			run("memory_dff" + (help_mode ? " [-nordff]" : memory_opts)); | ||||||
|  | 			run("opt_clean"); | ||||||
|  | 			run("memory_collect"); | ||||||
|  | 			run("opt -keepdc -fast"); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (check_label("check")) | ||||||
|  | 		{ | ||||||
|  | 			run("stat"); | ||||||
|  | 			run("check"); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| } PrepPass; | } PrepPass; | ||||||
| 
 | 
 | ||||||
| PRIVATE_NAMESPACE_END | PRIVATE_NAMESPACE_END | ||||||
|  |  | ||||||
|  | @ -41,6 +41,10 @@ struct SynthPass : public ScriptPass | ||||||
| 		log("    -top <module>\n"); | 		log("    -top <module>\n"); | ||||||
| 		log("        use the specified module as top module (default='top')\n"); | 		log("        use the specified module as top module (default='top')\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
|  | 		log("    -flatten\n"); | ||||||
|  | 		log("        flatten the design before synthesis. this will pass '-auto-top' to\n"); | ||||||
|  | 		log("        'hierarchy' if no top module is specified.\n"); | ||||||
|  | 		log("\n"); | ||||||
| 		log("    -encfile <file>\n"); | 		log("    -encfile <file>\n"); | ||||||
| 		log("        passed to 'fsm_recode' via 'fsm'\n"); | 		log("        passed to 'fsm_recode' via 'fsm'\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
|  | @ -68,8 +72,8 @@ struct SynthPass : public ScriptPass | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	std::string top_module, fsm_opts, memory_opts; | 	string top_module, fsm_opts, memory_opts; | ||||||
| 	bool noalumacc, nofsm, noabc; | 	bool flatten, noalumacc, nofsm, noabc; | ||||||
| 
 | 
 | ||||||
| 	virtual void clear_flags() YS_OVERRIDE | 	virtual void clear_flags() YS_OVERRIDE | ||||||
| 	{ | 	{ | ||||||
|  | @ -77,6 +81,7 @@ struct SynthPass : public ScriptPass | ||||||
| 		fsm_opts.clear(); | 		fsm_opts.clear(); | ||||||
| 		memory_opts.clear(); | 		memory_opts.clear(); | ||||||
| 
 | 
 | ||||||
|  | 		flatten = false; | ||||||
| 		noalumacc = false; | 		noalumacc = false; | ||||||
| 		nofsm = false; | 		nofsm = false; | ||||||
| 		noabc = false; | 		noabc = false; | ||||||
|  | @ -109,6 +114,10 @@ struct SynthPass : public ScriptPass | ||||||
| 				} | 				} | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
|  | 			if (args[argidx] == "-flatten") { | ||||||
|  | 				flatten = true; | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
| 			if (args[argidx] == "-nofsm") { | 			if (args[argidx] == "-nofsm") { | ||||||
| 				nofsm = true; | 				nofsm = true; | ||||||
| 				continue; | 				continue; | ||||||
|  | @ -147,9 +156,12 @@ struct SynthPass : public ScriptPass | ||||||
| 			if (help_mode) { | 			if (help_mode) { | ||||||
| 				run("hierarchy -check [-top <top>]"); | 				run("hierarchy -check [-top <top>]"); | ||||||
| 			} else { | 			} else { | ||||||
| 				if (top_module.empty()) | 				if (top_module.empty()) { | ||||||
| 					run(stringf("hierarchy -check")); | 					if (flatten) | ||||||
|  | 						run("hierarchy -check -auto-top"); | ||||||
| 					else | 					else | ||||||
|  | 						run("hierarchy -check"); | ||||||
|  | 				} else | ||||||
| 					run(stringf("hierarchy -check -top %s", top_module.c_str())); | 					run(stringf("hierarchy -check -top %s", top_module.c_str())); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | @ -157,6 +169,8 @@ struct SynthPass : public ScriptPass | ||||||
| 		if (check_label("coarse")) | 		if (check_label("coarse")) | ||||||
| 		{ | 		{ | ||||||
| 			run("proc"); | 			run("proc"); | ||||||
|  | 			if (help_mode || flatten) | ||||||
|  | 				run("flatten", "(if -flatten)"); | ||||||
| 			run("opt_expr"); | 			run("opt_expr"); | ||||||
| 			run("opt_clean"); | 			run("opt_clean"); | ||||||
| 			run("check"); | 			run("check"); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue