/* * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2012 Claire Xenia Wolf * * 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 // #include #include #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 pyosys { 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 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 &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 ); } }; 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_(m, "Globals"); // Trampoline Classes py::class_>(m, "Pass") .def(py::init([](std::string name, std::string short_help) { auto created = new pyosys::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(&Pass::call)) .def("call", py::overload_cast>(&Pass::call)) ; py::class_(m, "Monitor") .def(py::init([]() { return new pyosys::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::Monitor::notify_connect) ) .def("notify_blackout", &RTLIL::Monitor::notify_blackout) ; // Bind Opaque Containers bind_autogenerated_opaque_containers(m); // py::implicitly_convertible(); py::implicitly_convertible(); }; }; #endif // YOSYS_ENABLE_PYTHON