aboutsummaryrefslogtreecommitdiffstats
path: root/backends/cxxrtl/cxxrtl.cc
diff options
context:
space:
mode:
authorwhitequark <whitequark@whitequark.org>2020-06-05 13:52:30 +0000
committerwhitequark <whitequark@whitequark.org>2020-06-06 21:12:55 +0000
commitc399359ed6ea8f1d380a88779664f95f9c2e58a9 (patch)
tree4f0ef7d83ea87a27968226b32b4e269001022dbb /backends/cxxrtl/cxxrtl.cc
parentf6e16e7f4c65440783047d3f2b03563f36f6dae8 (diff)
downloadyosys-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.cc39
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("");
}