From 73914d1a414ad2277beca87fe1c52a564a796481 Mon Sep 17 00:00:00 2001
From: Clifford Wolf <clifford@clifford.at>
Date: Tue, 3 Sep 2013 19:10:11 +0200
Subject: [PATCH] Added -selected option to various backends

---
 backends/ilang/ilang_backend.cc     | 23 ++++++++++++++++++++---
 backends/intersynth/intersynth.cc   | 17 +++++++++++++++++
 backends/verilog/verilog_backend.cc | 27 +++++++++++++++++++++------
 3 files changed, 58 insertions(+), 9 deletions(-)

diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc
index 503164d43..5d70457e8 100644
--- a/backends/ilang/ilang_backend.cc
+++ b/backends/ilang/ilang_backend.cc
@@ -342,12 +342,29 @@ struct IlangBackend : public Backend {
 		log("Write the current design to an 'ilang' file. (ilang is a text representation\n");
 		log("of a design in yosys's internal format.)\n");
 		log("\n");
+		log("    -selected\n");
+		log("        only write selected parts of the design.\n");
+		log("\n");
 	}
-	virtual void execute(FILE *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) {
+	virtual void execute(FILE *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
+	{
+		bool selected = false;
+
 		log_header("Executing ILANG backend.\n");
-		extra_args(f, filename, args, 1);
+
+		size_t argidx;
+		for (argidx = 1; argidx < args.size(); argidx++) {
+			std::string arg = args[argidx];
+			if (arg == "-selected") {
+				selected = true;
+				continue;
+			}
+			break;
+		}
+		extra_args(f, filename, args, argidx);
+
 		log("Output filename: %s\n", filename.c_str());
-		ILANG_BACKEND::dump_design(f, design, false);
+		ILANG_BACKEND::dump_design(f, design, selected);
 	}
 } IlangBackend;
 
diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc
index e0092ef18..513c17531 100644
--- a/backends/intersynth/intersynth.cc
+++ b/backends/intersynth/intersynth.cc
@@ -69,6 +69,10 @@ struct IntersynthBackend : public Backend {
 		log("        inputs or outputs. This option can be used multiple times to specify\n");
 		log("        more than one library.\n");
 		log("\n");
+		log("    -selected\n");
+		log("        only write selected modules. modules must be selected entirely or\n");
+		log("        not at all.\n");
+		log("\n");
 		log("http://www.clifford.at/intersynth/\n");
 		log("\n");
 	}
@@ -80,6 +84,7 @@ struct IntersynthBackend : public Backend {
 		std::vector<std::string> libfiles;
 		std::vector<RTLIL::Design*> libs;
 		bool flag_notypes = false;
+		bool selected = false;
 
 		size_t argidx;
 		for (argidx = 1; argidx < args.size(); argidx++)
@@ -92,6 +97,10 @@ struct IntersynthBackend : public Backend {
 				libfiles.push_back(args[++argidx]);
 				continue;
 			}
+			if (args[argidx] == "-selected") {
+				selected = true;
+				continue;
+			}
 			break;
 		}
 		extra_args(f, filename, args, argidx);
@@ -123,9 +132,17 @@ struct IntersynthBackend : public Backend {
 			RTLIL::Module *module = module_it.second;
 			SigMap sigmap(module);
 
+			if (module->attributes.count("\\placeholder") > 0)
+				continue;
 			if (module->memories.size() == 0 && module->processes.size() == 0 && module->cells.size() == 0)
 				continue;
 
+			if (selected && !design->selected_whole_module(module->name)) {
+				if (design->selected_module(module->name))
+					log_cmd_error("Can't handle partially selected module %s!\n", RTLIL::id2cstr(module->name));
+				continue;
+			}
+
 			log("Generating netlist %s.\n", RTLIL::id2cstr(module->name));
 
 			if (module->memories.size() != 0 || module->processes.size() != 0)
diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc
index da1a7433f..5b7b601dd 100644
--- a/backends/verilog/verilog_backend.cc
+++ b/backends/verilog/verilog_backend.cc
@@ -928,6 +928,10 @@ struct VerilogBackend : public Backend {
 		log("        this option set only the modules with the 'placeholder' attribute\n");
 		log("        are written to the output file.\n");
 		log("\n");
+		log("    -selected\n");
+		log("        only write selected modules. modules must be selected entirely or\n");
+		log("        not at all.\n");
+		log("\n");
 	}
 	virtual void execute(FILE *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
 	{
@@ -939,6 +943,7 @@ struct VerilogBackend : public Backend {
 		noexpr = false;
 
 		bool placeholders = false;
+		bool selected = false;
 
 		reg_ct.clear();
 		reg_ct.setup_stdcells_mem();
@@ -969,17 +974,27 @@ struct VerilogBackend : public Backend {
 				placeholders = true;
 				continue;
 			}
+			if (arg == "-selected") {
+				selected = true;
+				continue;
+			}
 			break;
 		}
 		extra_args(f, filename, args, argidx);
 
-		for (auto it = design->modules.begin(); it != design->modules.end(); it++)
-			if ((it->second->attributes.count("\\placeholder") > 0) == placeholders) {
-				if (it != design->modules.begin())
-					fprintf(f, "\n");
-				log("Dumping module `%s'.\n", it->first.c_str());
-				dump_module(f, "", it->second);
+		for (auto it = design->modules.begin(); it != design->modules.end(); it++) {
+			if ((it->second->attributes.count("\\placeholder") > 0) != placeholders)
+				continue;
+			if (selected && !design->selected_whole_module(it->first)) {
+				if (design->selected_module(it->first))
+					log_cmd_error("Can't handle partially selected module %s!\n", RTLIL::id2cstr(it->first));
+				continue;
 			}
+			if (it != design->modules.begin())
+				fprintf(f, "\n");
+			log("Dumping module `%s'.\n", it->first.c_str());
+			dump_module(f, "", it->second);
+		}
 
 		reg_ct.clear();
 	}