Add extmodule support to firrtl backend
authorSahand Kashani <sahand.kashani@gmail.com>
Tue, 5 May 2020 23:01:14 +0000 (01:01 +0200)
committerSahand Kashani <sahand.kashani@gmail.com>
Tue, 5 May 2020 23:01:14 +0000 (01:01 +0200)
The current firrtl backend emits blackboxes as standard modules
with an empty body, but this causes the firrtl compiler to
optimize out entire circuits due to the absence of any drivers.

Yosys already tags blackboxes with a (*blackbox*) attribute, so this
commit just propagates this change to firrtl's syntax for blackboxes.

backends/firrtl/firrtl.cc

index 40d05a03654639f66f7c43fe192ab40b93e5e661..ff1329532f6142285292d33739d7cfdc21c0fe4e 100644 (file)
@@ -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<string> 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();
+               }
        }
 };