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>
33 std::map
<std::string
, void*> loaded_plugins
;
35 std::map
<std::string
, void*> loaded_python_plugins
;
37 std::map
<std::string
, std::string
> loaded_plugin_aliases
;
39 #ifdef YOSYS_ENABLE_PLUGINS
40 void load_plugin(std::string filename
, std::vector
<std::string
> aliases
)
42 std::string orig_filename
= filename
;
44 if (filename
.find('/') == std::string::npos
)
45 filename
= "./" + filename
;
48 if (!loaded_plugins
.count(filename
) && !loaded_python_plugins
.count(filename
)) {
50 if (!loaded_plugins
.count(filename
)) {
54 if(boost::algorithm::ends_with(filename
, ".py"))
56 int last_slash
= filename
.find_last_of('/');
57 std::string path
= filename
.substr(0, last_slash
);
58 filename
= filename
.substr(last_slash
+1, filename
.size());
59 filename
= filename
.substr(0,filename
.size()-3);
60 PyRun_SimpleString(("sys.path.insert(0,\""+path
+"\")").c_str());
61 PyObject
*filename_p
= PyUnicode_FromString(filename
.c_str());
62 if(filename_p
== NULL
)
65 log_cmd_error("Issues converting `%s' to Python\n", filename
.c_str());
68 PyObject
*module_p
= PyImport_Import(filename_p
);
72 log_cmd_error("Can't load python module `%s'\n", filename
.c_str());
75 loaded_python_plugins
[orig_filename
] = module_p
;
76 Pass::init_register();
80 void *hdl
= dlopen(filename
.c_str(), RTLD_LAZY
|RTLD_LOCAL
);
81 if (hdl
== NULL
&& orig_filename
.find('/') == std::string::npos
)
82 hdl
= dlopen((proc_share_dirname() + "plugins/" + orig_filename
+ ".so").c_str(), RTLD_LAZY
|RTLD_LOCAL
);
84 log_cmd_error("Can't load module `%s': %s\n", filename
.c_str(), dlerror());
85 loaded_plugins
[orig_filename
] = hdl
;
86 Pass::init_register();
93 for (auto &alias
: aliases
)
94 loaded_plugin_aliases
[alias
] = orig_filename
;
97 void load_plugin(std::string
, std::vector
<std::string
>)
99 log_error("This version of yosys is built without plugin support.\n");
103 struct PluginPass
: public Pass
{
104 PluginPass() : Pass("plugin", "load and list loaded plugins") { }
105 void help() YS_OVERRIDE
107 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
109 log(" plugin [options]\n");
111 log("Load and list loaded plugins.\n");
113 log(" -i <plugin_filename>\n");
114 log(" Load (install) the specified plugin.\n");
116 log(" -a <alias_name>\n");
117 log(" Register the specified alias name for the loaded plugin\n");
120 log(" List loaded plugins\n");
123 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
125 std::string plugin_filename
;
126 std::vector
<std::string
> plugin_aliases
;
127 bool list_mode
= false;
130 for (argidx
= 1; argidx
< args
.size(); argidx
++)
132 if ((args
[argidx
] == "-i") && argidx
+1 < args
.size() && plugin_filename
.empty()) {
133 plugin_filename
= args
[++argidx
];
136 if ((args
[argidx
] == "-a") && argidx
+1 < args
.size()) {
137 plugin_aliases
.push_back(args
[++argidx
]);
140 if (args
[argidx
] == "-l") {
146 extra_args(args
, argidx
, design
, false);
148 if (!plugin_filename
.empty())
149 load_plugin(plugin_filename
, plugin_aliases
);
155 if (loaded_plugins
.empty() and loaded_python_plugins
.empty())
157 if (loaded_plugins
.empty())
159 log("No plugins loaded.\n");
161 log("Loaded plugins:\n");
163 for (auto &it
: loaded_plugins
)
164 log(" %s\n", it
.first
.c_str());
167 for (auto &it
: loaded_python_plugins
)
168 log(" %s\n", it
.first
.c_str());
171 if (!loaded_plugin_aliases
.empty()) {
173 int max_alias_len
= 1;
174 for (auto &it
: loaded_plugin_aliases
)
175 max_alias_len
= max(max_alias_len
, GetSize(it
.first
));
176 for (auto &it
: loaded_plugin_aliases
)
177 log("Alias: %-*s %s\n", max_alias_len
, it
.first
.c_str(), it
.second
.c_str());