diff options
author | whitequark <whitequark@whitequark.org> | 2020-06-05 13:52:30 +0000 |
---|---|---|
committer | whitequark <whitequark@whitequark.org> | 2020-06-06 21:12:55 +0000 |
commit | c399359ed6ea8f1d380a88779664f95f9c2e58a9 (patch) | |
tree | 4f0ef7d83ea87a27968226b32b4e269001022dbb /backends/cxxrtl/cxxrtl.cc | |
parent | f6e16e7f4c65440783047d3f2b03563f36f6dae8 (diff) | |
download | yosys-c399359ed6ea8f1d380a88779664f95f9c2e58a9.tar.gz yosys-c399359ed6ea8f1d380a88779664f95f9c2e58a9.tar.bz2 yosys-c399359ed6ea8f1d380a88779664f95f9c2e58a9.zip |
cxxrtl: add a C API for driving and introspecting designs.
Compared to the C++ API, the C API currently has two limitations:
1. Memories cannot be updated in a race-free way.
2. Black boxes cannot be implemented in C.
Diffstat (limited to 'backends/cxxrtl/cxxrtl.cc')
-rw-r--r-- | backends/cxxrtl/cxxrtl.cc | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/backends/cxxrtl/cxxrtl.cc b/backends/cxxrtl/cxxrtl.cc index edd606c1a..4dc534513 100644 --- a/backends/cxxrtl/cxxrtl.cc +++ b/backends/cxxrtl/cxxrtl.cc @@ -1778,6 +1778,7 @@ struct CxxrtlWorker { void dump_design(RTLIL::Design *design) { + RTLIL::Module *top_module = nullptr; std::vector<RTLIL::Module*> modules; TopoSort<RTLIL::Module*> topo_design; for (auto module : design->modules()) { @@ -1787,6 +1788,8 @@ struct CxxrtlWorker { modules.push_back(module); // cxxrtl blackboxes first if (module->get_blackbox_attribute() || module->get_bool_attribute(ID(cxxrtl_blackbox))) continue; + if (module->get_bool_attribute(ID::top)) + top_module = module; topo_design.node(module); for (auto cell : module->cells()) { @@ -1808,6 +1811,25 @@ struct CxxrtlWorker { f << "#ifndef " << include_guard << "\n"; f << "#define " << include_guard << "\n"; f << "\n"; + if (top_module != nullptr && debug_info) { + f << "#include <backends/cxxrtl/cxxrtl_capi.h>\n"; + f << "\n"; + f << "#ifdef __cplusplus\n"; + f << "extern \"C\" {\n"; + f << "#endif\n"; + f << "\n"; + f << "cxxrtl_toplevel " << design_ns << "_create();\n"; + f << "\n"; + f << "#ifdef __cplusplus\n"; + f << "}\n"; + f << "#endif\n"; + f << "\n"; + } else { + f << "// The CXXRTL C API is not available because the design is built without debug information.\n"; + f << "\n"; + } + f << "#ifdef __cplusplus\n"; + f << "\n"; f << "#include <backends/cxxrtl/cxxrtl.h>\n"; f << "\n"; f << "using namespace cxxrtl;\n"; @@ -1818,6 +1840,8 @@ struct CxxrtlWorker { dump_module_intf(module); f << "} // namespace " << design_ns << "\n"; f << "\n"; + f << "#endif // __cplusplus\n"; + f << "\n"; f << "#endif\n"; *intf_f << f.str(); f.str(""); } @@ -1827,6 +1851,10 @@ struct CxxrtlWorker { else f << "#include <backends/cxxrtl/cxxrtl.h>\n"; f << "\n"; + f << "#ifdef CXXRTL_INCLUDE_CAPI_IMPL\n"; + f << "#include <backends/cxxrtl/cxxrtl_capi.cc>\n"; + f << "#endif\n"; + f << "\n"; f << "using namespace cxxrtl_yosys;\n"; f << "\n"; f << "namespace " << design_ns << " {\n"; @@ -1837,6 +1865,17 @@ struct CxxrtlWorker { dump_module_impl(module); } f << "} // namespace " << design_ns << "\n"; + f << "\n"; + if (top_module != nullptr && debug_info) { + f << "cxxrtl_toplevel " << design_ns << "_create() {\n"; + inc_indent(); + f << indent << "return new _cxxrtl_toplevel { "; + f << "std::make_unique<" << design_ns << "::" << mangle(top_module) << ">()"; + f << " };\n"; + dec_indent(); + f << "}\n"; + } + *impl_f << f.str(); f.str(""); } |