2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2014 Clifford Wolf <clifford@clifford.at>
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include "kernel/yosys.h"
22 #ifdef YOSYS_ENABLE_PLUGINS
27 # include <boost/algorithm/string/predicate.hpp>
29 # include <boost/filesystem.hpp>
34 std::map
<std::string
, void*> loaded_plugins
;
36 std::map
<std::string
, void*> loaded_python_plugins
;
38 std::map
<std::string
, std::string
> loaded_plugin_aliases
;
40 #ifdef YOSYS_ENABLE_PLUGINS
41 void load_plugin(std::string filename
, std::vector
<std::string
> aliases
)
43 std::string orig_filename
= filename
;
45 if (filename
.find('/') == std::string::npos
)
46 filename
= "./" + filename
;
49 if (!loaded_plugins
.count(filename
) && !loaded_python_plugins
.count(filename
)) {
51 if (!loaded_plugins
.count(filename
)) {
56 boost::filesystem::path
full_path(filename
);
58 if(strcmp(full_path
.extension().c_str(), ".py") == 0)
60 std::string
path(full_path
.parent_path().c_str());
61 filename
= full_path
.filename().c_str();
62 filename
= filename
.substr(0,filename
.size()-3);
63 PyRun_SimpleString(("sys.path.insert(0,\""+path
+"\")").c_str());
65 PyObject
*module_p
= PyImport_ImportModule(filename
.c_str());
69 log_cmd_error("Can't load python module `%s'\n", full_path
.filename().c_str());
72 loaded_python_plugins
[orig_filename
] = module_p
;
73 Pass::init_register();
77 void *hdl
= dlopen(filename
.c_str(), RTLD_LAZY
|RTLD_LOCAL
);
78 if (hdl
== NULL
&& orig_filename
.find('/') == std::string::npos
)
79 hdl
= dlopen((proc_share_dirname() + "plugins/" + orig_filename
+ ".so").c_str(), RTLD_LAZY
|RTLD_LOCAL
);
81 log_cmd_error("Can't load module `%s': %s\n", filename
.c_str(), dlerror());
82 loaded_plugins
[orig_filename
] = hdl
;
83 Pass::init_register();
90 for (auto &alias
: aliases
)
91 loaded_plugin_aliases
[alias
] = orig_filename
;
94 void load_plugin(std::string
, std::vector
<std::string
>)
97 "\n This version of Yosys cannot load plugins at runtime.\n"
98 " Some plugins may have been included at build time.\n"
99 " Use option `-H' to see the available built-in and plugin commands.\n"
104 struct PluginPass
: public Pass
{
105 PluginPass() : Pass("plugin", "load and list loaded plugins") { }
108 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
110 log(" plugin [options]\n");
112 log("Load and list loaded plugins.\n");
114 log(" -i <plugin_filename>\n");
115 log(" Load (install) the specified plugin.\n");
117 log(" -a <alias_name>\n");
118 log(" Register the specified alias name for the loaded plugin\n");
121 log(" List loaded plugins\n");
124 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) override
126 std::string plugin_filename
;
127 std::vector
<std::string
> plugin_aliases
;
128 bool list_mode
= false;
131 for (argidx
= 1; argidx
< args
.size(); argidx
++)
133 if ((args
[argidx
] == "-i") && argidx
+1 < args
.size() && plugin_filename
.empty()) {
134 plugin_filename
= args
[++argidx
];
137 if ((args
[argidx
] == "-a") && argidx
+1 < args
.size()) {
138 plugin_aliases
.push_back(args
[++argidx
]);
141 if (args
[argidx
] == "-l") {
147 extra_args(args
, argidx
, design
, false);
149 if (!plugin_filename
.empty())
150 load_plugin(plugin_filename
, plugin_aliases
);
156 if (loaded_plugins
.empty() and loaded_python_plugins
.empty())
158 if (loaded_plugins
.empty())
160 log("No plugins loaded.\n");
162 log("Loaded plugins:\n");
164 for (auto &it
: loaded_plugins
)
165 log(" %s\n", it
.first
.c_str());
168 for (auto &it
: loaded_python_plugins
)
169 log(" %s\n", it
.first
.c_str());
172 if (!loaded_plugin_aliases
.empty()) {
174 int max_alias_len
= 1;
175 for (auto &it
: loaded_plugin_aliases
)
176 max_alias_len
= max(max_alias_len
, GetSize(it
.first
));
177 for (auto &it
: loaded_plugin_aliases
)
178 log("Alias: %-*s %s\n", max_alias_len
, it
.first
.c_str(), it
.second
.c_str());