diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc index 89df0366f..a90b0b87a 100644 --- a/backends/firrtl/firrtl.cc +++ b/backends/firrtl/firrtl.cc @@ -392,7 +392,34 @@ 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); + + 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()); @@ -1078,6 +1105,18 @@ 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(); } };