mirror of
https://github.com/YosysHQ/yosys
synced 2025-10-09 09:21:58 +00:00
261 lines
6.8 KiB
C++
261 lines
6.8 KiB
C++
/*
|
|
* yosys -- Yosys Open SYnthesis Suite
|
|
*
|
|
* Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#ifdef YOSYS_ENABLE_PYTHON
|
|
|
|
// <!-- generated includes -->
|
|
#include <pybind11/pybind11.h>
|
|
#include <pybind11/native_enum.h>
|
|
|
|
#include "pyosys/hashlib.h"
|
|
|
|
namespace py = pybind11;
|
|
|
|
USING_YOSYS_NAMESPACE
|
|
|
|
using std::set;
|
|
using std::regex;
|
|
using std::ostream;
|
|
using namespace RTLIL;
|
|
|
|
#include "wrappers.inc.cc"
|
|
|
|
namespace YOSYS_PYTHON {
|
|
struct Globals {};
|
|
|
|
// Trampolines for Classes with Python-Overridable Virtual Methods
|
|
// https://pybind11.readthedocs.io/en/stable/advanced/classes.html#overriding-virtual-functions-in-python
|
|
class PassTrampoline : public Pass {
|
|
public:
|
|
using Pass::Pass;
|
|
|
|
void help() override {
|
|
PYBIND11_OVERRIDE(void, Pass, help);
|
|
}
|
|
|
|
bool formatted_help() override {
|
|
PYBIND11_OVERRIDE(bool, Pass, formatted_help);
|
|
}
|
|
|
|
void clear_flags() override {
|
|
PYBIND11_OVERRIDE(void, Pass, clear_flags);
|
|
}
|
|
|
|
void execute(std::vector<std::string> args, RTLIL::Design *design) override {
|
|
PYBIND11_OVERRIDE_PURE(
|
|
void,
|
|
Pass,
|
|
execute,
|
|
args,
|
|
design
|
|
);
|
|
}
|
|
|
|
void on_register() override {
|
|
PYBIND11_OVERRIDE(void, Pass, on_register);
|
|
}
|
|
|
|
void on_shutdown() override {
|
|
PYBIND11_OVERRIDE(void, Pass, on_shutdown);
|
|
}
|
|
|
|
bool replace_existing_pass() const override {
|
|
PYBIND11_OVERRIDE(
|
|
bool,
|
|
Pass,
|
|
replace_existing_pass
|
|
);
|
|
}
|
|
};
|
|
|
|
class MonitorTrampoline : public RTLIL::Monitor {
|
|
public:
|
|
using RTLIL::Monitor::Monitor;
|
|
|
|
void notify_module_add(RTLIL::Module *module) override {
|
|
PYBIND11_OVERRIDE(
|
|
void,
|
|
RTLIL::Monitor,
|
|
notify_module_add,
|
|
module
|
|
);
|
|
}
|
|
|
|
void notify_module_del(RTLIL::Module *module) override {
|
|
PYBIND11_OVERRIDE(
|
|
void,
|
|
RTLIL::Monitor,
|
|
notify_module_del,
|
|
module
|
|
);
|
|
}
|
|
|
|
void notify_connect(
|
|
RTLIL::Cell *cell,
|
|
const RTLIL::IdString &port,
|
|
const RTLIL::SigSpec &old_sig,
|
|
const RTLIL::SigSpec &sig
|
|
) override {
|
|
PYBIND11_OVERRIDE(
|
|
void,
|
|
RTLIL::Monitor,
|
|
notify_connect,
|
|
cell,
|
|
port,
|
|
old_sig,
|
|
sig
|
|
);
|
|
}
|
|
|
|
void notify_connect(
|
|
RTLIL::Module *module,
|
|
const RTLIL::SigSig &sigsig
|
|
) override {
|
|
PYBIND11_OVERRIDE(
|
|
void,
|
|
RTLIL::Monitor,
|
|
notify_connect,
|
|
module,
|
|
sigsig
|
|
);
|
|
}
|
|
|
|
void notify_connect(
|
|
RTLIL::Module *module,
|
|
const std::vector<RTLIL::SigSig> &sigsig_vec
|
|
) override {
|
|
PYBIND11_OVERRIDE(
|
|
void,
|
|
RTLIL::Monitor,
|
|
notify_connect,
|
|
module,
|
|
sigsig_vec
|
|
);
|
|
}
|
|
|
|
void notify_blackout(
|
|
RTLIL::Module *module
|
|
) override {
|
|
PYBIND11_OVERRIDE(
|
|
void,
|
|
RTLIL::Monitor,
|
|
notify_blackout,
|
|
module
|
|
);
|
|
}
|
|
};
|
|
|
|
/// @brief Use an auxiliary function to adapt the legacy function.
|
|
void log_to_stream(py::object object)
|
|
{
|
|
// TODO
|
|
};
|
|
|
|
PYBIND11_MODULE(libyosys, m) {
|
|
// this code is run on import
|
|
m.doc() = "python access to libyosys";
|
|
|
|
if (!yosys_already_setup()) {
|
|
log_streams.push_back(&std::cout);
|
|
log_error_stderr = true;
|
|
yosys_setup();
|
|
|
|
// Cleanup
|
|
m.add_object("_cleanup_handle", py::capsule([](){
|
|
yosys_shutdown();
|
|
}));
|
|
}
|
|
|
|
// Logging Methods
|
|
m.def("log_header", [](Design *d, std::string s) { log_formatted_header(d, "%s", s); });
|
|
m.def("log", [](std::string s) { log_formatted_string("%s", s); });
|
|
m.def("log_file_info", [](std::string_view file, int line, std::string s) { log_formatted_file_info(file, line, s); });
|
|
m.def("log_warning", [](std::string s) { log_formatted_warning("Warning: ", s); });
|
|
m.def("log_warning_noprefix", [](std::string s) { log_formatted_warning("", s); });
|
|
m.def("log_file_warning", [](std::string_view file, int line, std::string s) { log_formatted_file_warning(file, line, s); });
|
|
m.def("log_error", [](std::string s) { log_formatted_error(s); });
|
|
m.def("log_file_error", [](std::string_view file, int line, std::string s) { log_formatted_file_error(file, line, s); });
|
|
|
|
// Namespace to host global objects
|
|
auto global_variables = py::class_<Globals>(m, "Globals");
|
|
|
|
// Trampoline Classes
|
|
py::class_<Pass, YOSYS_PYTHON::PassTrampoline, std::unique_ptr<Pass, py::nodelete>>(m, "Pass")
|
|
.def(py::init([](std::string name, std::string short_help) {
|
|
auto created = new YOSYS_PYTHON::PassTrampoline(name, short_help);
|
|
Pass::init_register();
|
|
return created;
|
|
}), py::arg("name"), py::arg("short_help"))
|
|
.def("help", &Pass::help)
|
|
.def("formatted_help", &Pass::formatted_help)
|
|
.def("execute", &Pass::execute)
|
|
.def("clear_flags", &Pass::clear_flags)
|
|
.def("on_register", &Pass::on_register)
|
|
.def("on_shutdown", &Pass::on_shutdown)
|
|
.def("replace_existing_pass", &Pass::replace_existing_pass)
|
|
.def("experimental", &Pass::experimental)
|
|
.def("internal", &Pass::internal)
|
|
.def("pre_execute", &Pass::pre_execute)
|
|
.def("post_execute", &Pass::post_execute)
|
|
.def("cmd_log_args", &Pass::cmd_log_args)
|
|
.def("cmd_error", &Pass::cmd_error)
|
|
.def("extra_args", &Pass::extra_args)
|
|
.def("call", py::overload_cast<RTLIL::Design *,std::string>(&Pass::call))
|
|
.def("call", py::overload_cast<RTLIL::Design *,std::vector<std::string>>(&Pass::call))
|
|
;
|
|
|
|
py::class_<RTLIL::Monitor, YOSYS_PYTHON::MonitorTrampoline>(m, "Monitor")
|
|
.def(py::init([]() {
|
|
return new YOSYS_PYTHON::MonitorTrampoline();
|
|
}))
|
|
.def("notify_module_add", &RTLIL::Monitor::notify_module_add)
|
|
.def("notify_module_del", &RTLIL::Monitor::notify_module_del)
|
|
.def(
|
|
"notify_connect",
|
|
py::overload_cast<
|
|
RTLIL::Cell *,
|
|
const RTLIL::IdString &,
|
|
const RTLIL::SigSpec &,
|
|
const RTLIL::SigSpec &
|
|
>(&RTLIL::Monitor::notify_connect)
|
|
)
|
|
.def(
|
|
"notify_connect",
|
|
py::overload_cast<
|
|
RTLIL::Module *,
|
|
const RTLIL::SigSig &
|
|
>(&RTLIL::Monitor::notify_connect)
|
|
)
|
|
.def(
|
|
"notify_connect",
|
|
py::overload_cast<
|
|
RTLIL::Module *,
|
|
const std::vector<RTLIL::SigSig> &
|
|
>(&RTLIL::Monitor::notify_connect)
|
|
)
|
|
.def("notify_blackout", &RTLIL::Monitor::notify_blackout)
|
|
;
|
|
|
|
// Bind Opaque Containers
|
|
bind_autogenerated_opaque_containers(m);
|
|
|
|
// <!-- generated pymod-level code -->
|
|
};
|
|
};
|
|
|
|
#endif // YOSYS_ENABLE_PYTHON
|