Rename cells based on the wires they drive.
authorScott Mansell <phiren@gmail.com>
Sun, 6 Jan 2019 01:40:10 +0000 (14:40 +1300)
committerScott Mansell <phiren@gmail.com>
Sun, 6 Jan 2019 06:00:16 +0000 (19:00 +1300)
passes/cmds/rename.cc

index 4b4af0a4016b3c535134c0f5b212cc41f235899c..698ce72352fd8f4f3b960424b4e1807a7c0e331c 100644 (file)
@@ -61,6 +61,42 @@ static std::string derive_name_from_src(const std::string &src, int counter)
                return stringf("\\%s$%d", src_base.c_str(), counter);
 }
 
+static IdString derive_name_from_wire(const RTLIL::Cell &cell)
+{
+       // Find output
+       const SigSpec *output = nullptr;
+       int num_outputs = 0;
+       for (auto &connection : cell.connections()) {
+               if (cell.output(connection.first)) {
+                       output = &connection.second;
+                       num_outputs++;
+               }
+       }
+
+       if (num_outputs != 1) // Skip cells thad drive multiple outputs
+               return cell.name;
+
+       std::string name = "";
+       for (auto &chunk : output->chunks()) {
+               // Skip cells that drive privately named wires
+               if (!chunk.wire || chunk.wire->name.str()[0] == '$')
+                       return cell.name;
+
+               if (name != "")
+                       name += "$";
+
+               name += chunk.wire->name.str();
+               if (chunk.wire->width != chunk.width) {
+                       name += "[";
+                       if (chunk.width != 1)
+                               name += std::to_string(chunk.offset + chunk.width) + ":";
+                       name += std::to_string(chunk.offset) + "]";
+               }
+       }
+
+       return name + cell.type.str();
+}
+
 struct RenamePass : public Pass {
        RenamePass() : Pass("rename", "rename object in the design") { }
        void help() YS_OVERRIDE
@@ -77,6 +113,10 @@ struct RenamePass : public Pass {
                log("Assign names auto-generated from the src attribute to all selected wires and\n");
                log("cells with private names.\n");
                log("\n");
+               log("    rename -wire [selection]\n");
+               log("Assign auto-generated names based on the wires they drive to all selected\n");
+               log("cells with private names. Ignores cells driving privatly named wires.\n");
+               log("\n");
                log("    rename -enumerate [-pattern <pattern>] [selection]\n");
                log("\n");
                log("Assign short auto-generated names to all selected wires and cells with private\n");
@@ -98,6 +138,7 @@ struct RenamePass : public Pass {
        {
                std::string pattern_prefix = "_", pattern_suffix = "_";
                bool flag_src = false;
+               bool flag_wire = false;
                bool flag_enumerate = false;
                bool flag_hide = false;
                bool flag_top = false;
@@ -112,6 +153,11 @@ struct RenamePass : public Pass {
                                got_mode = true;
                                continue;
                        }
+                       if (arg == "-wire" && !got_mode) {
+                               flag_wire = true;
+                               got_mode = true;
+                               continue;
+                       }
                        if (arg == "-enumerate" && !got_mode) {
                                flag_enumerate = true;
                                got_mode = true;
@@ -167,6 +213,26 @@ struct RenamePass : public Pass {
                        }
                }
                else
+               if (flag_wire)
+               {
+                       extra_args(args, argidx, design);
+
+                       for (auto &mod : design->modules_)
+                       {
+                               RTLIL::Module *module = mod.second;
+                               if (!design->selected(module))
+                                       continue;
+
+                               dict<RTLIL::IdString, RTLIL::Cell*> new_cells;
+                               for (auto &it : module->cells_) {
+                                       if (it.first[0] == '$' && design->selected(module, it.second))
+                                               it.second->name = derive_name_from_wire(*it.second);
+                                       new_cells[it.second->name] = it.second;
+                               }
+                               module->cells_.swap(new_cells);
+                       }
+               }
+               else
                if (flag_enumerate)
                {
                        extra_args(args, argidx, design);