Refactor to directly call ILANG_BACKEND::dump_const() + directly lookup src attribute
authorSahand Kashani <sahand.kashani@gmail.com>
Tue, 24 Mar 2020 09:36:14 +0000 (10:36 +0100)
committerSahand Kashani <sahand.kashani@gmail.com>
Tue, 24 Mar 2020 09:55:21 +0000 (10:55 +0100)
backends/firrtl/firrtl.cc

index de7d2275b63bcd99aceb367d6b990eeb05b201ea..48a4d04656cffdfb6b3a89f7411c31245b42b8e9 100644 (file)
@@ -23,6 +23,7 @@
 #include "kernel/celltypes.h"
 #include "kernel/cellaigs.h"
 #include "kernel/log.h"
+#include "backends/ilang/ilang_backend.h"
 #include <algorithm>
 #include <string>
 #include <vector>
@@ -42,72 +43,18 @@ static const FDirection FD_OUT = 0x2;
 static const FDirection FD_INOUT = 0x3;
 static const int FIRRTL_MAX_DSH_WIDTH_ERROR = 20; // For historic reasons, this is actually one greater than the maximum allowed shift width
 
-// Shamelessly copied from ilang_backend.cc. Something better is surely possible here.
-void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int offset = 0, bool autoint = true)
+std::string getFileinfo(const RTLIL::AttrObject *design_entity)
 {
-       if (width < 0)
-               width = data.bits.size() - offset;
-       if ((data.flags & RTLIL::CONST_FLAG_STRING) == 0 || width != (int)data.bits.size()) {
-               if (width == 32 && autoint) {
-                       int32_t val = 0;
-                       for (int i = 0; i < width; i++) {
-                               log_assert(offset+i < (int)data.bits.size());
-                               switch (data.bits[offset+i]) {
-                               case RTLIL::S0: break;
-                               case RTLIL::S1: val |= 1 << i; break;
-                               default: val = -1; break;
-                               }
-                       }
-                       if (val >= 0) {
-                               f << stringf("%d", val);
-                               return;
-                       }
-               }
-               f << stringf("%d'", width);
-               for (int i = offset+width-1; i >= offset; i--) {
-                       log_assert(i < (int)data.bits.size());
-                       switch (data.bits[i]) {
-                       case RTLIL::S0: f << stringf("0"); break;
-                       case RTLIL::S1: f << stringf("1"); break;
-                       case RTLIL::Sx: f << stringf("x"); break;
-                       case RTLIL::Sz: f << stringf("z"); break;
-                       case RTLIL::Sa: f << stringf("-"); break;
-                       case RTLIL::Sm: f << stringf("m"); break;
-                       }
-               }
-       } else {
-               f << stringf("\"");
-               std::string str = data.decode_string();
-               for (size_t i = 0; i < str.size(); i++) {
-                       if (str[i] == '\n')
-                               f << stringf("\\n");
-                       else if (str[i] == '\t')
-                               f << stringf("\\t");
-                       else if (str[i] < 32)
-                               f << stringf("\\%03o", str[i]);
-                       else if (str[i] == '"')
-                               f << stringf("\\\"");
-                       else if (str[i] == '\\')
-                               f << stringf("\\\\");
-                       else
-                               f << str[i];
-               }
-               f << stringf("\"");
-       }
-}
+       std::string src(design_entity->get_src_attribute());
 
-std::string getFileinfo(const dict<RTLIL::IdString, RTLIL::Const> &attributes)
-{
        std::ostringstream fileinfo;
-       for (auto &it : attributes) {
-               if (it.first == "\\src") {
-                       fileinfo << "@[";
-                       dump_const(fileinfo, it.second);
-                       fileinfo << "]";
-               }
+       if (!src.empty()) {
+               fileinfo << "@[" << src << "]";
        }
 
-       std::string fileinfo_str = fileinfo.str();
+       // Remove quotes from src attribute as firrtl automatically escapes and
+       // double-quotes them.
+       std::string fileinfo_str(fileinfo.str());
        fileinfo_str.erase(std::remove(fileinfo_str.begin(), fileinfo_str.end(), '\"'), fileinfo_str.end());
 
        return fileinfo_str;
@@ -401,7 +348,7 @@ struct FirrtlWorker
                        log_warning("No instance for %s.%s\n", cell_type.c_str(), cell_name.c_str());
                        return;
                }
-               auto cellFileinfo = getFileinfo(cell->attributes);
+               auto cellFileinfo = getFileinfo(cell);
                wire_exprs.push_back(stringf("%s" "inst %s%s of %s %s", indent.c_str(), cell_name.c_str(), cell_name_comment.c_str(), instanceOf.c_str(), cellFileinfo.c_str()));
 
                for (auto it = cell->connections().begin(); it != cell->connections().end(); ++it) {
@@ -467,14 +414,14 @@ struct FirrtlWorker
 
        void run()
        {
-               auto moduleFileinfo = getFileinfo(module->attributes);
+               auto moduleFileinfo = getFileinfo(module);
                f << stringf("  module %s: %s\n", make_id(module->name), moduleFileinfo.c_str());
                vector<string> port_decls, wire_decls, cell_exprs, wire_exprs;
 
                for (auto wire : module->wires())
                {
                        const auto wireName = make_id(wire->name);
-                       auto wireFileinfo = getFileinfo(wire->attributes);
+                       auto wireFileinfo = getFileinfo(wire);
 
                        // If a wire has initial data, issue a warning since FIRRTL doesn't currently support it.
                        if (wire->attributes.count("\\init")) {
@@ -517,7 +464,7 @@ struct FirrtlWorker
                        string primop;
                        bool always_uint = false;
                        string y_id = make_id(cell->name);
-                       std::string cellFileinfo = getFileinfo(cell->attributes);
+                       std::string cellFileinfo = getFileinfo(cell);
 
                        if (cell->type.in("$not", "$logic_not", "$neg", "$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_bool", "$reduce_xnor"))
                        {
@@ -573,7 +520,7 @@ struct FirrtlWorker
                        {
                                string a_expr = make_expr(cell->getPort("\\A"));
                                string b_expr = make_expr(cell->getPort("\\B"));
-                               std::string cellFileinfo = getFileinfo(cell->attributes);
+                               std::string cellFileinfo = getFileinfo(cell);
                                wire_decls.push_back(stringf("    wire %s: UInt<%d> %s\n", y_id.c_str(), y_width, cellFileinfo.c_str()));
 
                                if (a_signed) {
@@ -1037,7 +984,7 @@ struct FirrtlWorker
                for (auto wire : module->wires())
                {
                        string expr;
-                       std::string wireFileinfo = getFileinfo(wire->attributes);
+                       std::string wireFileinfo = getFileinfo(wire);
 
                        if (wire->port_input)
                                continue;
@@ -1208,7 +1155,7 @@ struct FirrtlBackend : public Backend {
                if (top == nullptr)
                        top = last;
 
-               auto circuitFileinfo = getFileinfo(top->attributes);
+               auto circuitFileinfo = getFileinfo(top);
                *f << stringf("circuit %s: %s\n", make_id(top->name), circuitFileinfo.c_str());
 
                for (auto module : design->modules())