mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	Added ScriptPass helper class for script-like passes
This commit is contained in:
		
							parent
							
								
									6cafd08ac1
								
							
						
					
					
						commit
						2553319081
					
				
					 5 changed files with 255 additions and 251 deletions
				
			
		| 
						 | 
					@ -80,6 +80,7 @@ Pass::pre_post_exec_state_t Pass::pre_execute()
 | 
				
			||||||
	state.begin_ns = PerformanceTimer::query();
 | 
						state.begin_ns = PerformanceTimer::query();
 | 
				
			||||||
	state.parent_pass = current_pass;
 | 
						state.parent_pass = current_pass;
 | 
				
			||||||
	current_pass = this;
 | 
						current_pass = this;
 | 
				
			||||||
 | 
						clear_flags();
 | 
				
			||||||
	return state;
 | 
						return state;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -99,6 +100,10 @@ void Pass::help()
 | 
				
			||||||
	log("\n");
 | 
						log("\n");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Pass::clear_flags()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Pass::cmd_log_args(const std::vector<std::string> &args)
 | 
					void Pass::cmd_log_args(const std::vector<std::string> &args)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (args.size() <= 1)
 | 
						if (args.size() <= 1)
 | 
				
			||||||
| 
						 | 
					@ -282,6 +287,60 @@ void Pass::call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::vec
 | 
				
			||||||
	design->selected_active_module = backup_selected_active_module;
 | 
						design->selected_active_module = backup_selected_active_module;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool ScriptPass::check_label(std::string label, std::string info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (active_design == nullptr) {
 | 
				
			||||||
 | 
							log("\n");
 | 
				
			||||||
 | 
							if (info.empty())
 | 
				
			||||||
 | 
								log("    %s:\n", label.c_str());
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								log("    %s:    %s\n", label.c_str(), info.c_str());
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							if (!active_run_from.empty() && active_run_from == active_run_to) {
 | 
				
			||||||
 | 
								block_active = (label == active_run_from);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								if (label == active_run_from)
 | 
				
			||||||
 | 
									block_active = true;
 | 
				
			||||||
 | 
								if (label == active_run_to)
 | 
				
			||||||
 | 
									block_active = false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return block_active;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ScriptPass::run(std::string command, std::string info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (active_design == nullptr) {
 | 
				
			||||||
 | 
							if (info.empty())
 | 
				
			||||||
 | 
								log("        %s\n", command.c_str());
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								log("        %s    %s\n", command.c_str(), info.c_str());
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							Pass::call(active_design, command);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ScriptPass::run_script(RTLIL::Design *design, std::string run_from, std::string run_to)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						help_mode = false;
 | 
				
			||||||
 | 
						active_design = design;
 | 
				
			||||||
 | 
						block_active = run_from.empty();
 | 
				
			||||||
 | 
						active_run_from = run_from;
 | 
				
			||||||
 | 
						active_run_to = run_to;
 | 
				
			||||||
 | 
						script();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ScriptPass::help_script()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						clear_flags();
 | 
				
			||||||
 | 
						help_mode = true;
 | 
				
			||||||
 | 
						active_design = nullptr;
 | 
				
			||||||
 | 
						block_active = true;
 | 
				
			||||||
 | 
						active_run_from.clear();
 | 
				
			||||||
 | 
						active_run_to.clear();
 | 
				
			||||||
 | 
						script();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Frontend::Frontend(std::string name, std::string short_help) :
 | 
					Frontend::Frontend(std::string name, std::string short_help) :
 | 
				
			||||||
		Pass(name.rfind("=", 0) == 0 ? name.substr(1) : "read_" + name, short_help),
 | 
							Pass(name.rfind("=", 0) == 0 ? name.substr(1) : "read_" + name, short_help),
 | 
				
			||||||
		frontend_name(name.rfind("=", 0) == 0 ? name.substr(1) : name)
 | 
							frontend_name(name.rfind("=", 0) == 0 ? name.substr(1) : name)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,6 +31,7 @@ struct Pass
 | 
				
			||||||
	virtual ~Pass();
 | 
						virtual ~Pass();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	virtual void help();
 | 
						virtual void help();
 | 
				
			||||||
 | 
						virtual void clear_flags();
 | 
				
			||||||
	virtual void execute(std::vector<std::string> args, RTLIL::Design *design) = 0;
 | 
						virtual void execute(std::vector<std::string> args, RTLIL::Design *design) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int call_counter;
 | 
						int call_counter;
 | 
				
			||||||
| 
						 | 
					@ -63,6 +64,22 @@ struct Pass
 | 
				
			||||||
	static void done_register();
 | 
						static void done_register();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ScriptPass : Pass
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						bool block_active, help_mode;
 | 
				
			||||||
 | 
						RTLIL::Design *active_design;
 | 
				
			||||||
 | 
						std::string active_run_from, active_run_to;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ScriptPass(std::string name, std::string short_help = "** document me **") : Pass(name, short_help) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						virtual void script() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool check_label(std::string label, std::string info = std::string());
 | 
				
			||||||
 | 
						void run(std::string command, std::string info = std::string());
 | 
				
			||||||
 | 
						void run_script(RTLIL::Design *design, std::string run_from = std::string(), std::string run_to = std::string());
 | 
				
			||||||
 | 
						void help_script();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Frontend : Pass
 | 
					struct Frontend : Pass
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	// for reading of here documents
 | 
						// for reading of here documents
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1100,8 +1100,8 @@ struct HistoryPass : public Pass {
 | 
				
			||||||
} HistoryPass;
 | 
					} HistoryPass;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ScriptPass : public Pass {
 | 
					struct ScriptCmdPass : public Pass {
 | 
				
			||||||
	ScriptPass() : Pass("script", "execute commands from script file") { }
 | 
						ScriptCmdPass() : Pass("script", "execute commands from script file") { }
 | 
				
			||||||
	virtual void help() {
 | 
						virtual void help() {
 | 
				
			||||||
		log("\n");
 | 
							log("\n");
 | 
				
			||||||
		log("    script <filename> [<from_label>:<to_label>]\n");
 | 
							log("    script <filename> [<from_label>:<to_label>]\n");
 | 
				
			||||||
| 
						 | 
					@ -1127,7 +1127,7 @@ struct ScriptPass : public Pass {
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			extra_args(args, 2, design, false);
 | 
								extra_args(args, 2, design, false);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
} ScriptPass;
 | 
					} ScriptCmdPass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
YOSYS_NAMESPACE_END
 | 
					YOSYS_NAMESPACE_END
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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 SynthPass : public ScriptPass
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!run_from.empty() && run_from == run_to) {
 | 
						SynthPass() : ScriptPass("synth", "generic synthesis script") { }
 | 
				
			||||||
		active = (label == run_from);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		if (label == run_from)
 | 
					 | 
				
			||||||
			active = true;
 | 
					 | 
				
			||||||
		if (label == run_to)
 | 
					 | 
				
			||||||
			active = false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return active;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct SynthPass : public Pass {
 | 
						virtual void help() YS_OVERRIDE
 | 
				
			||||||
	SynthPass() : Pass("synth", "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");
 | 
				
			||||||
| 
						 | 
					@ -75,49 +64,28 @@ struct SynthPass : 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("    coarse:\n");
 | 
					 | 
				
			||||||
		log("        proc\n");
 | 
					 | 
				
			||||||
		log("        opt_expr\n");
 | 
					 | 
				
			||||||
		log("        opt_clean\n");
 | 
					 | 
				
			||||||
		log("        check\n");
 | 
					 | 
				
			||||||
		log("        opt\n");
 | 
					 | 
				
			||||||
		log("        wreduce\n");
 | 
					 | 
				
			||||||
		log("        alumacc\n");
 | 
					 | 
				
			||||||
		log("        share\n");
 | 
					 | 
				
			||||||
		log("        opt\n");
 | 
					 | 
				
			||||||
		log("        fsm\n");
 | 
					 | 
				
			||||||
		log("        opt -fast\n");
 | 
					 | 
				
			||||||
		log("        memory -nomap\n");
 | 
					 | 
				
			||||||
		log("        opt_clean\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
					 | 
				
			||||||
		log("    fine:\n");
 | 
					 | 
				
			||||||
		log("        opt -fast -full\n");
 | 
					 | 
				
			||||||
		log("        memory_map\n");
 | 
					 | 
				
			||||||
		log("        opt -full\n");
 | 
					 | 
				
			||||||
		log("        techmap\n");
 | 
					 | 
				
			||||||
		log("        opt -fast\n");
 | 
					 | 
				
			||||||
	#ifdef YOSYS_ENABLE_ABC
 | 
					 | 
				
			||||||
		log("        abc -fast\n");
 | 
					 | 
				
			||||||
		log("        opt -fast\n");
 | 
					 | 
				
			||||||
	#endif
 | 
					 | 
				
			||||||
		log("\n");
 | 
					 | 
				
			||||||
		log("    check:\n");
 | 
					 | 
				
			||||||
		log("        hierarchy -check\n");
 | 
					 | 
				
			||||||
		log("        stat\n");
 | 
					 | 
				
			||||||
		log("        check\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
							log("\n");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
 | 
					
 | 
				
			||||||
 | 
						std::string top_module, fsm_opts, memory_opts;
 | 
				
			||||||
 | 
						bool noalumacc, nofsm, noabc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						virtual void clear_flags() YS_OVERRIDE
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		std::string top_module, fsm_opts, memory_opts;
 | 
							top_module.clear();
 | 
				
			||||||
		std::string run_from, run_to;
 | 
							fsm_opts.clear();
 | 
				
			||||||
		bool noalumacc = false;
 | 
							memory_opts.clear();
 | 
				
			||||||
		bool nofsm = false;
 | 
					
 | 
				
			||||||
		bool noabc = false;
 | 
							noalumacc = false;
 | 
				
			||||||
 | 
							nofsm = false;
 | 
				
			||||||
 | 
							noabc = false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						virtual void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							string run_from, run_to;
 | 
				
			||||||
 | 
							clear_flags();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		size_t argidx;
 | 
							size_t argidx;
 | 
				
			||||||
		for (argidx = 1; argidx < args.size(); argidx++)
 | 
							for (argidx = 1; argidx < args.size(); argidx++)
 | 
				
			||||||
| 
						 | 
					@ -164,62 +132,69 @@ struct SynthPass : 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("Executing SYNTH pass.\n");
 | 
							log_header("Executing SYNTH pass.\n");
 | 
				
			||||||
		log_push();
 | 
							log_push();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (check_label(active, run_from, run_to, "begin"))
 | 
							run_script(design, run_from, run_to);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							log_pop();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						virtual void script() YS_OVERRIDE
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (check_label("begin"))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (top_module.empty())
 | 
								if (help_mode) {
 | 
				
			||||||
				Pass::call(design, stringf("hierarchy -check"));
 | 
									run("hierarchy -check [-top <top>]");
 | 
				
			||||||
			else
 | 
								} else {
 | 
				
			||||||
				Pass::call(design, stringf("hierarchy -check -top %s", top_module.c_str()));
 | 
									if (top_module.empty())
 | 
				
			||||||
 | 
										run(stringf("hierarchy -check"));
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
										run(stringf("hierarchy -check -top %s", top_module.c_str()));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (check_label(active, run_from, run_to, "coarse"))
 | 
							if (check_label("coarse"))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Pass::call(design, "proc");
 | 
								run("proc");
 | 
				
			||||||
			Pass::call(design, "opt_expr");
 | 
								run("opt_expr");
 | 
				
			||||||
			Pass::call(design, "opt_clean");
 | 
								run("opt_clean");
 | 
				
			||||||
			Pass::call(design, "check");
 | 
								run("check");
 | 
				
			||||||
			Pass::call(design, "opt");
 | 
								run("opt");
 | 
				
			||||||
			Pass::call(design, "wreduce");
 | 
								run("wreduce");
 | 
				
			||||||
			if (!noalumacc)
 | 
								if (!noalumacc)
 | 
				
			||||||
				Pass::call(design, "alumacc");
 | 
									run("alumacc");
 | 
				
			||||||
			Pass::call(design, "share");
 | 
								run("share");
 | 
				
			||||||
			Pass::call(design, "opt");
 | 
								run("opt");
 | 
				
			||||||
			if (!nofsm)
 | 
								if (!nofsm)
 | 
				
			||||||
				Pass::call(design, "fsm" + fsm_opts);
 | 
									run("fsm" + fsm_opts);
 | 
				
			||||||
			Pass::call(design, "opt -fast");
 | 
								run("opt -fast");
 | 
				
			||||||
			Pass::call(design, "memory -nomap" + memory_opts);
 | 
								run("memory -nomap" + memory_opts);
 | 
				
			||||||
			Pass::call(design, "opt_clean");
 | 
								run("opt_clean");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (check_label(active, run_from, run_to, "fine"))
 | 
							if (check_label("fine"))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Pass::call(design, "opt -fast -full");
 | 
								run("opt -fast -full");
 | 
				
			||||||
			Pass::call(design, "memory_map");
 | 
								run("memory_map");
 | 
				
			||||||
			Pass::call(design, "opt -full");
 | 
								run("opt -full");
 | 
				
			||||||
			Pass::call(design, "techmap");
 | 
								run("techmap");
 | 
				
			||||||
			Pass::call(design, "opt -fast");
 | 
								run("opt -fast");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (!noabc) {
 | 
								if (!noabc) {
 | 
				
			||||||
		#ifdef YOSYS_ENABLE_ABC
 | 
							#ifdef YOSYS_ENABLE_ABC
 | 
				
			||||||
				Pass::call(design, "abc -fast");
 | 
									run("abc -fast");
 | 
				
			||||||
				Pass::call(design, "opt -fast");
 | 
									run("opt -fast");
 | 
				
			||||||
		#endif
 | 
							#endif
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (check_label(active, run_from, run_to, "check"))
 | 
							if (check_label("check"))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Pass::call(design, "hierarchy -check");
 | 
								run("hierarchy -check");
 | 
				
			||||||
			Pass::call(design, "stat");
 | 
								run("stat");
 | 
				
			||||||
			Pass::call(design, "check");
 | 
								run("check");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		log_pop();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
} SynthPass;
 | 
					} SynthPass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,18 +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 SynthIce40Pass : public ScriptPass
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (label == run_from)
 | 
						SynthIce40Pass() : ScriptPass("synth_ice40", "synthesis for iCE40 FPGAs") { }
 | 
				
			||||||
		active = true;
 | 
					 | 
				
			||||||
	if (label == run_to)
 | 
					 | 
				
			||||||
		active = false;
 | 
					 | 
				
			||||||
	return active;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct SynthIce40Pass : public Pass {
 | 
						virtual void help() YS_OVERRIDE
 | 
				
			||||||
	SynthIce40Pass() : Pass("synth_ice40", "synthesis for iCE40 FPGAs") { }
 | 
					 | 
				
			||||||
	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");
 | 
				
			||||||
| 
						 | 
					@ -77,73 +70,30 @@ struct SynthIce40Pass : 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("        read_verilog -lib +/ice40/cells_sim.v\n");
 | 
					 | 
				
			||||||
		log("        hierarchy -check -top <top>\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
					 | 
				
			||||||
		log("    flatten:         (unless -noflatten)\n");
 | 
					 | 
				
			||||||
		log("        proc\n");
 | 
					 | 
				
			||||||
		log("        flatten\n");
 | 
					 | 
				
			||||||
		log("        tribuf -logic\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
					 | 
				
			||||||
		log("    coarse:\n");
 | 
					 | 
				
			||||||
		log("        synth -run coarse\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
					 | 
				
			||||||
		log("    bram:            (skip if -nobram)\n");
 | 
					 | 
				
			||||||
		log("        memory_bram -rules +/ice40/brams.txt\n");
 | 
					 | 
				
			||||||
		log("        techmap -map +/ice40/brams_map.v\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
					 | 
				
			||||||
		log("    fine:\n");
 | 
					 | 
				
			||||||
		log("        opt -fast -mux_undef -undriven -fine\n");
 | 
					 | 
				
			||||||
		log("        memory_map\n");
 | 
					 | 
				
			||||||
		log("        opt -undriven -fine\n");
 | 
					 | 
				
			||||||
		log("        techmap -map +/techmap.v [-map +/ice40/arith_map.v]\n");
 | 
					 | 
				
			||||||
		log("        abc -dff     (only if -retime)\n");
 | 
					 | 
				
			||||||
		log("        ice40_opt\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
					 | 
				
			||||||
		log("    map_ffs:\n");
 | 
					 | 
				
			||||||
		log("        dffsr2dff\n");
 | 
					 | 
				
			||||||
		log("        dff2dffe -direct-match $_DFF_*\n");
 | 
					 | 
				
			||||||
		log("        techmap -map +/ice40/cells_map.v\n");
 | 
					 | 
				
			||||||
		log("        opt_expr -mux_undef\n");
 | 
					 | 
				
			||||||
		log("        simplemap\n");
 | 
					 | 
				
			||||||
		log("        ice40_ffinit\n");
 | 
					 | 
				
			||||||
		log("        ice40_ffssr\n");
 | 
					 | 
				
			||||||
		log("        ice40_opt -full\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
					 | 
				
			||||||
		log("    map_luts:\n");
 | 
					 | 
				
			||||||
		log("        abc          (only if -abc2)\n");
 | 
					 | 
				
			||||||
		log("        ice40_opt    (only if -abc2)\n");
 | 
					 | 
				
			||||||
		log("        abc -lut 4\n");
 | 
					 | 
				
			||||||
		log("        clean\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
					 | 
				
			||||||
		log("    map_cells:\n");
 | 
					 | 
				
			||||||
		log("        techmap -map +/ice40/cells_map.v\n");
 | 
					 | 
				
			||||||
		log("        clean\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
					 | 
				
			||||||
		log("    check:\n");
 | 
					 | 
				
			||||||
		log("        hierarchy -check\n");
 | 
					 | 
				
			||||||
		log("        stat\n");
 | 
					 | 
				
			||||||
		log("        check -noinit\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
					 | 
				
			||||||
		log("    blif:\n");
 | 
					 | 
				
			||||||
		log("        write_blif -gates -attr -param <file-name>\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
					 | 
				
			||||||
		log("    edif:\n");
 | 
					 | 
				
			||||||
		log("        write_edif <file-name>\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
							log("\n");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
 | 
					
 | 
				
			||||||
 | 
						string top_opt = "-auto-top";
 | 
				
			||||||
 | 
						string blif_file, edif_file;
 | 
				
			||||||
 | 
						bool nocarry, nobram, flatten, retime, abc2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						virtual void clear_flags() YS_OVERRIDE
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							top_opt = "-auto-top";
 | 
				
			||||||
 | 
							blif_file = "";
 | 
				
			||||||
 | 
							edif_file = "";
 | 
				
			||||||
 | 
							nocarry = false;
 | 
				
			||||||
 | 
							nobram = false;
 | 
				
			||||||
 | 
							flatten = true;
 | 
				
			||||||
 | 
							retime = false;
 | 
				
			||||||
 | 
							abc2 = false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						virtual void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		std::string top_opt = "-auto-top";
 | 
					 | 
				
			||||||
		std::string run_from, run_to;
 | 
							std::string run_from, run_to;
 | 
				
			||||||
		std::string blif_file, edif_file;
 | 
							clear_flags();
 | 
				
			||||||
		bool nocarry = false;
 | 
					 | 
				
			||||||
		bool nobram = false;
 | 
					 | 
				
			||||||
		bool flatten = true;
 | 
					 | 
				
			||||||
		bool retime = false;
 | 
					 | 
				
			||||||
		bool abc2 = false;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		size_t argidx;
 | 
							size_t argidx;
 | 
				
			||||||
		for (argidx = 1; argidx < args.size(); argidx++)
 | 
							for (argidx = 1; argidx < args.size(); argidx++)
 | 
				
			||||||
| 
						 | 
					@ -199,98 +149,101 @@ struct SynthIce40Pass : 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("Executing SYNTH_ICE40 pass.\n");
 | 
							log_header("Executing SYNTH_ICE40 pass.\n");
 | 
				
			||||||
		log_push();
 | 
							log_push();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (check_label(active, run_from, run_to, "begin"))
 | 
							run_script(design, run_from, run_to);
 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Pass::call(design, "read_verilog -lib +/ice40/cells_sim.v");
 | 
					 | 
				
			||||||
			Pass::call(design, stringf("hierarchy -check %s", top_opt.c_str()));
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (flatten && check_label(active, run_from, run_to, "flatten"))
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Pass::call(design, "proc");
 | 
					 | 
				
			||||||
			Pass::call(design, "flatten");
 | 
					 | 
				
			||||||
			Pass::call(design, "tribuf -logic");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (check_label(active, run_from, run_to, "coarse"))
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Pass::call(design, "synth -run coarse");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (!nobram && check_label(active, run_from, run_to, "bram"))
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Pass::call(design, "memory_bram -rules +/ice40/brams.txt");
 | 
					 | 
				
			||||||
			Pass::call(design, "techmap -map +/ice40/brams_map.v");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (check_label(active, run_from, run_to, "fine"))
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Pass::call(design, "opt -fast -mux_undef -undriven -fine");
 | 
					 | 
				
			||||||
			Pass::call(design, "memory_map");
 | 
					 | 
				
			||||||
			Pass::call(design, "opt -undriven -fine");
 | 
					 | 
				
			||||||
			if (nocarry)
 | 
					 | 
				
			||||||
				Pass::call(design, "techmap");
 | 
					 | 
				
			||||||
			else
 | 
					 | 
				
			||||||
				Pass::call(design, "techmap -map +/techmap.v -map +/ice40/arith_map.v");
 | 
					 | 
				
			||||||
			if (retime)
 | 
					 | 
				
			||||||
				Pass::call(design, "abc -dff");
 | 
					 | 
				
			||||||
			Pass::call(design, "ice40_opt");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (check_label(active, run_from, run_to, "map_ffs"))
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Pass::call(design, "dffsr2dff");
 | 
					 | 
				
			||||||
			Pass::call(design, "dff2dffe -direct-match $_DFF_*");
 | 
					 | 
				
			||||||
			Pass::call(design, "techmap -map +/ice40/cells_map.v");
 | 
					 | 
				
			||||||
			Pass::call(design, "opt_expr -mux_undef");
 | 
					 | 
				
			||||||
			Pass::call(design, "simplemap");
 | 
					 | 
				
			||||||
			Pass::call(design, "ice40_ffinit");
 | 
					 | 
				
			||||||
			Pass::call(design, "ice40_ffssr");
 | 
					 | 
				
			||||||
			Pass::call(design, "ice40_opt -full");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (check_label(active, run_from, run_to, "map_luts"))
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			if (abc2) {
 | 
					 | 
				
			||||||
				Pass::call(design, "abc");
 | 
					 | 
				
			||||||
				Pass::call(design, "ice40_opt");
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			Pass::call(design, "abc -lut 4");
 | 
					 | 
				
			||||||
			Pass::call(design, "clean");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (check_label(active, run_from, run_to, "map_cells"))
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Pass::call(design, "techmap -map +/ice40/cells_map.v");
 | 
					 | 
				
			||||||
			Pass::call(design, "clean");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (check_label(active, run_from, run_to, "check"))
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Pass::call(design, "hierarchy -check");
 | 
					 | 
				
			||||||
			Pass::call(design, "stat");
 | 
					 | 
				
			||||||
			Pass::call(design, "check -noinit");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (check_label(active, run_from, run_to, "blif"))
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			if (!blif_file.empty())
 | 
					 | 
				
			||||||
				Pass::call(design, stringf("write_blif -gates -attr -param %s", blif_file.c_str()));
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (check_label(active, run_from, run_to, "edif"))
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			if (!edif_file.empty())
 | 
					 | 
				
			||||||
				Pass::call(design, stringf("write_edif %s", edif_file.c_str()));
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		log_pop();
 | 
							log_pop();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						virtual void script() YS_OVERRIDE
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (check_label("begin"))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								run("read_verilog -lib +/ice40/cells_sim.v");
 | 
				
			||||||
 | 
								run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (flatten && check_label("flatten", "(unless -noflatten)"))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								run("proc");
 | 
				
			||||||
 | 
								run("flatten");
 | 
				
			||||||
 | 
								run("tribuf -logic");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (check_label("coarse"))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								run("synth -run coarse");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!nobram && check_label("bram", "(skip if -nobram)"))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								run("memory_bram -rules +/ice40/brams.txt");
 | 
				
			||||||
 | 
								run("techmap -map +/ice40/brams_map.v");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (check_label("fine"))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								run("opt -fast -mux_undef -undriven -fine");
 | 
				
			||||||
 | 
								run("memory_map");
 | 
				
			||||||
 | 
								run("opt -undriven -fine");
 | 
				
			||||||
 | 
								if (nocarry)
 | 
				
			||||||
 | 
									run("techmap");
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									run("techmap -map +/techmap.v -map +/ice40/arith_map.v");
 | 
				
			||||||
 | 
								if (retime || help_mode)
 | 
				
			||||||
 | 
									run("abc -dff", "(only if -retime)");
 | 
				
			||||||
 | 
								run("ice40_opt");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (check_label("map_ffs"))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								run("dffsr2dff");
 | 
				
			||||||
 | 
								run("dff2dffe -direct-match $_DFF_*");
 | 
				
			||||||
 | 
								run("techmap -map +/ice40/cells_map.v");
 | 
				
			||||||
 | 
								run("opt_expr -mux_undef");
 | 
				
			||||||
 | 
								run("simplemap");
 | 
				
			||||||
 | 
								run("ice40_ffinit");
 | 
				
			||||||
 | 
								run("ice40_ffssr");
 | 
				
			||||||
 | 
								run("ice40_opt -full");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (check_label("map_luts"))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (abc2 || help_mode) {
 | 
				
			||||||
 | 
									run("abc", "      (only if -abc2)");
 | 
				
			||||||
 | 
									run("ice40_opt", "(only if -abc2)");
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								run("abc -lut 4");
 | 
				
			||||||
 | 
								run("clean");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (check_label("map_cells"))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								run("techmap -map +/ice40/cells_map.v");
 | 
				
			||||||
 | 
								run("clean");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (check_label("check"))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								run("hierarchy -check");
 | 
				
			||||||
 | 
								run("stat");
 | 
				
			||||||
 | 
								run("check -noinit");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (check_label("blif"))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (!blif_file.empty() || help_mode)
 | 
				
			||||||
 | 
									run(stringf("write_blif -gates -attr -param %s", help_mode ? "<file-name>" : blif_file.c_str()));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (check_label("edif"))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (!edif_file.empty() || help_mode)
 | 
				
			||||||
 | 
									run(stringf("write_edif %s", help_mode ? "<file-name>" : edif_file.c_str()));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
} SynthIce40Pass;
 | 
					} SynthIce40Pass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PRIVATE_NAMESPACE_END
 | 
					PRIVATE_NAMESPACE_END
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue