Added "plugin" command
authorClifford Wolf <clifford@clifford.at>
Fri, 22 Aug 2014 11:58:36 +0000 (13:58 +0200)
committerClifford Wolf <clifford@clifford.at>
Fri, 22 Aug 2014 12:00:11 +0000 (14:00 +0200)
Makefile
kernel/driver.cc
kernel/yosys.cc
kernel/yosys.h
passes/cmds/Makefile.inc
passes/cmds/plugin.cc [new file with mode: 0644]

index a64c628ef0d9bb4788bb48aa492cbbef8ae61697..e7417539480ea31e8948c5863068225515055da9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -151,6 +151,7 @@ OBJS += passes/cmds/show.o
 OBJS += passes/cmds/stat.o
 OBJS += passes/cmds/cover.o
 OBJS += passes/cmds/design.o
+OBJS += passes/cmds/plugin.o
 
 include passes/proc/Makefile.inc
 include passes/opt/Makefile.inc
index d59e68a5031d52ed9e47161b87f6d16f596e404e..6bd60d7b56014a585a996a062526914325bd1274 100644 (file)
@@ -27,7 +27,6 @@
 #include <string.h>
 #include <unistd.h>
 #include <libgen.h>
-#include <dlfcn.h>
 #include <limits.h>
 #include <errno.h>
 
@@ -38,7 +37,7 @@ int main(int argc, char **argv)
        std::string frontend_command = "auto";
        std::string backend_command = "auto";
        std::vector<std::string> passes_commands;
-       std::vector<void*> loaded_modules;
+       std::vector<std::string> plugin_filenames;
        std::string output_filename = "";
        std::string scriptfile = "";
        bool scriptfile_tcl = false;
@@ -82,11 +81,7 @@ int main(int argc, char **argv)
                        passes_commands.push_back("opt");
                        break;
                case 'm':
-                       loaded_modules.push_back(dlopen(optarg, RTLD_LAZY|RTLD_GLOBAL));
-                       if (loaded_modules.back() == NULL) {
-                               fprintf(stderr, "Can't load module `%s': %s\n", optarg, dlerror());
-                               exit(1);
-                       }
+                       plugin_filenames.push_back(optarg);
                        break;
                case 'f':
                        frontend_command = optarg;
@@ -239,6 +234,9 @@ int main(int argc, char **argv)
 
        yosys_setup();
 
+       for (auto &fn : plugin_filenames)
+               load_plugin(fn, {});
+
        if (optind == argc && passes_commands.size() == 0 && scriptfile.empty()) {
                if (!got_output_filename)
                        backend_command = "";
@@ -346,9 +344,6 @@ int main(int argc, char **argv)
 
        yosys_shutdown();
 
-       for (auto mod : loaded_modules)
-               dlclose(mod);
-
        return 0;
 }
 
index 599c92d52894b071e45bd9894d3a8815ddd0c7b7..ce24873142135398e760fe7b31e6326a33242eff 100644 (file)
@@ -22,6 +22,7 @@
 #include <readline/readline.h>
 #include <readline/history.h>
 
+#include <dlfcn.h>
 #include <unistd.h>
 #include <limits.h>
 
@@ -98,6 +99,12 @@ void yosys_shutdown()
                yosys_tcl_interp = NULL;
        }
 #endif
+
+       for (auto &it : loaded_plugins)
+               dlclose(it.second);
+
+       loaded_plugins.clear();
+       loaded_plugin_aliases.clear();
 }
 
 RTLIL::IdString new_id(std::string file, int line, std::string func)
index 79c90628c929c6836f2d4837d5fc96a056b9eb67..c6cbcabc99a9611e587fff5feefba2241d7bbd84 100644 (file)
@@ -132,6 +132,11 @@ extern const char *yosys_version_str;
 extern std::map<std::string, RTLIL::Design*> saved_designs;
 extern std::vector<RTLIL::Design*> pushed_designs;
 
+// from passes/cmds/pluginc.cc
+extern std::map<std::string, void*> loaded_plugins;
+extern std::map<std::string, std::string> loaded_plugin_aliases;
+void load_plugin(std::string filename, std::vector<std::string> aliases);
+
 YOSYS_NAMESPACE_END
 
 #endif
index d6e45f2d1511601c19aa72f8f987eb5a587b2957..4cf61150e7c1b34e0b3e692661a277550248b689 100644 (file)
@@ -21,4 +21,5 @@ OBJS += passes/cmds/connwrappers.o
 OBJS += passes/cmds/cover.o
 OBJS += passes/cmds/trace.o
 OBJS += passes/cmds/wreduce.o
+OBJS += passes/cmds/plugin.o
 
diff --git a/passes/cmds/plugin.cc b/passes/cmds/plugin.cc
new file mode 100644 (file)
index 0000000..c73684f
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ *  yosys -- Yosys Open SYnthesis Suite
+ *
+ *  Copyright (C) 2014  Clifford Wolf <clifford@clifford.at>
+ *
+ *  Permission to use, copy, modify, and/or distribute this software for any
+ *  purpose with or without fee is hereby granted, provided that the above
+ *  copyright notice and this permission notice appear in all copies.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "kernel/yosys.h"
+#include <dlfcn.h>
+
+YOSYS_NAMESPACE_BEGIN
+
+std::map<std::string, void*> loaded_plugins;
+std::map<std::string, std::string> loaded_plugin_aliases;
+
+void load_plugin(std::string filename, std::vector<std::string> aliases)
+{
+       if (filename.find('/') == std::string::npos)
+               filename = "./" + filename;
+
+       if (!loaded_plugins.count(filename)) {
+               void *hdl = dlopen(filename.c_str(), RTLD_LAZY|RTLD_LOCAL);
+               if (hdl == NULL)
+                       log_cmd_error("Can't load module `%s': %s\n", filename.c_str(), dlerror());
+               loaded_plugins[filename] = hdl;
+               Pass::init_register();
+       }
+
+       for (auto &alias : aliases)
+               loaded_plugin_aliases[alias] = filename;
+}
+
+struct PluginPass : public Pass {
+       PluginPass() : Pass("plugin", "load and list loaded plugins") { }
+       virtual void help()
+       {
+               //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+               log("\n");
+               log("    plugin [options]\n");
+               log("\n");
+               log("Load and list loaded plugins.\n");
+               log("\n");
+               log("    -i <plugin_filename>\n");
+               log("        Load (install) the specified plugin.\n");
+               log("\n");
+               log("    -a <alias_name>\n");
+               log("        Register the specified alias name for the loaded plugin\n");
+               log("\n");
+               log("    -l\n");
+               log("        List loaded plugins\n");
+               log("\n");
+       }
+       virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+       {
+               std::string plugin_filename;
+               std::vector<std::string> plugin_aliases;
+               bool list_mode = false;
+
+               size_t argidx;
+               for (argidx = 1; argidx < args.size(); argidx++)
+               {
+                       if ((args[argidx] == "-i") && argidx+1 < args.size() && plugin_filename.empty()) {
+                               plugin_filename = args[++argidx];
+                               continue;
+                       }
+                       if ((args[argidx] == "-a") && argidx+1 < args.size()) {
+                               plugin_aliases.push_back(args[++argidx]);
+                               continue;
+                       }
+                       if (args[argidx] == "-l") {
+                               list_mode = true;
+                               continue;
+                       }
+                       break;
+               }
+               extra_args(args, argidx, design, false);
+
+               if (!plugin_filename.empty())
+                       load_plugin(plugin_filename, plugin_aliases);
+
+               if (list_mode)
+               {
+                       log("\n");
+                       if (loaded_plugins.empty())
+                               log("No plugins loaded.\n");
+                       else
+                               log("Loaded plugins:\n");
+
+                       for (auto &it : loaded_plugins)
+                               log("  %s\n", it.first.c_str());
+
+                       if (!loaded_plugin_aliases.empty()) {
+                               log("\n");
+                               int max_alias_len = 1;
+                               for (auto &it : loaded_plugin_aliases)
+                                       max_alias_len = std::max(max_alias_len, SIZE(it.first));
+                               for (auto &it : loaded_plugin_aliases)
+                                       log("Alias: %-*s %s\n", max_alias_len, it.first.c_str(), it.second.c_str());
+                       }
+               }
+       }
+} PluginPass;
+
+YOSYS_NAMESPACE_END
+