diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc index 40d05a036..ff1329532 100644 --- a/backends/firrtl/firrtl.cc +++ b/backends/firrtl/firrtl.cc @@ -392,7 +392,37 @@ struct FirrtlWorker return result; } - void run() + void emit_extmodule() + { + std::string moduleFileinfo = getFileinfo(module); + f << stringf(" extmodule %s: %s\n", make_id(module->name), moduleFileinfo.c_str()); + vector port_decls; + + for (auto wire : module->wires()) + { + const auto wireName = make_id(wire->name); + std::string wireFileinfo = getFileinfo(wire); + + // Maybe not needed? + if (wire->port_id) + { + if (wire->port_input && wire->port_output) + { + log_error("Module port %s.%s is inout!\n", log_id(module), log_id(wire)); + } + port_decls.push_back(stringf(" %s %s: UInt<%d> %s\n", wire->port_input ? "input" : "output", + wireName, wire->width, wireFileinfo.c_str())); + } + } + + for (auto str : port_decls) { + f << str; + } + + f << stringf("\n"); + } + + void emit_module() { std::string moduleFileinfo = getFileinfo(module); f << stringf(" module %s: %s\n", make_id(module->name), moduleFileinfo.c_str()); @@ -1076,6 +1106,22 @@ struct FirrtlWorker for (auto str : wire_exprs) f << str; + + f << stringf("\n"); + } + + void run() + { + // Blackboxes should be emitted as `extmodule`s in firrtl. Only ports are + // emitted in such a case. + if (module->get_blackbox_attribute()) + { + emit_extmodule(); + } + else + { + emit_module(); + } } };