opt_dff: Fix NOT gates wired in reverse.
[yosys.git] / passes / cmds / plugin.cc
index aa6d5b6ccec04b7c0f6431989009808d1612e7ba..a94769bcd299e0b36b1ac06a425ee94d8dd5fb6e 100644 (file)
 #  include <dlfcn.h>
 #endif
 
+#ifdef WITH_PYTHON
+#  include <boost/algorithm/string/predicate.hpp>
+#  include <Python.h>
+#  include <boost/filesystem.hpp>
+#endif
+
 YOSYS_NAMESPACE_BEGIN
 
 std::map<std::string, void*> loaded_plugins;
+#ifdef WITH_PYTHON
+std::map<std::string, void*> loaded_python_plugins;
+#endif
 std::map<std::string, std::string> loaded_plugin_aliases;
 
 #ifdef YOSYS_ENABLE_PLUGINS
@@ -36,7 +45,35 @@ void load_plugin(std::string filename, std::vector<std::string> aliases)
        if (filename.find('/') == std::string::npos)
                filename = "./" + filename;
 
+       #ifdef WITH_PYTHON
+       if (!loaded_plugins.count(filename) && !loaded_python_plugins.count(filename)) {
+       #else
        if (!loaded_plugins.count(filename)) {
+       #endif
+
+               #ifdef WITH_PYTHON
+
+               boost::filesystem::path full_path(filename);
+
+               if(strcmp(full_path.extension().c_str(), ".py") == 0)
+               {
+                       std::string path(full_path.parent_path().c_str());
+                       filename = full_path.filename().c_str();
+                       filename = filename.substr(0,filename.size()-3);
+                       PyRun_SimpleString(("sys.path.insert(0,\""+path+"\")").c_str());
+                       PyErr_Print();
+                       PyObject *module_p = PyImport_ImportModule(filename.c_str());
+                       if(module_p == NULL)
+                       {
+                               PyErr_Print();
+                               log_cmd_error("Can't load python module `%s'\n", full_path.filename().c_str());
+                               return;
+                       }
+                       loaded_python_plugins[orig_filename] = module_p;
+                       Pass::init_register();
+               } else {
+               #endif
+
                void *hdl = dlopen(filename.c_str(), RTLD_LAZY|RTLD_LOCAL);
                if (hdl == NULL && orig_filename.find('/') == std::string::npos)
                        hdl = dlopen((proc_share_dirname() + "plugins/" + orig_filename + ".so").c_str(), RTLD_LAZY|RTLD_LOCAL);
@@ -44,6 +81,10 @@ void load_plugin(std::string filename, std::vector<std::string> aliases)
                        log_cmd_error("Can't load module `%s': %s\n", filename.c_str(), dlerror());
                loaded_plugins[orig_filename] = hdl;
                Pass::init_register();
+
+               #ifdef WITH_PYTHON
+               }
+               #endif
        }
 
        for (auto &alias : aliases)
@@ -52,13 +93,17 @@ void load_plugin(std::string filename, std::vector<std::string> aliases)
 #else
 void load_plugin(std::string, std::vector<std::string>)
 {
-       log_error("This version of yosys is built without plugin support.\n");
+       log_error(
+               "\n  This version of Yosys cannot load plugins at runtime.\n"
+               "  Some plugins may have been included at build time.\n"
+               "  Use option `-H' to see the available built-in and plugin commands.\n"
+       );
 }
 #endif
 
 struct PluginPass : public Pass {
        PluginPass() : Pass("plugin", "load and list loaded plugins") { }
-       void help() YS_OVERRIDE
+       void help() override
        {
                //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
                log("\n");
@@ -76,7 +121,7 @@ struct PluginPass : public Pass {
                log("        List loaded plugins\n");
                log("\n");
        }
-       void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+       void execute(std::vector<std::string> args, RTLIL::Design *design) override
        {
                std::string plugin_filename;
                std::vector<std::string> plugin_aliases;
@@ -107,7 +152,11 @@ struct PluginPass : public Pass {
                if (list_mode)
                {
                        log("\n");
+#ifdef WITH_PYTHON
+                       if (loaded_plugins.empty() and loaded_python_plugins.empty())
+#else
                        if (loaded_plugins.empty())
+#endif
                                log("No plugins loaded.\n");
                        else
                                log("Loaded plugins:\n");
@@ -115,6 +164,11 @@ struct PluginPass : public Pass {
                        for (auto &it : loaded_plugins)
                                log("  %s\n", it.first.c_str());
 
+#ifdef WITH_PYTHON
+                       for (auto &it : loaded_python_plugins)
+                               log("  %s\n", it.first.c_str());
+#endif
+
                        if (!loaded_plugin_aliases.empty()) {
                                log("\n");
                                int max_alias_len = 1;