Added library support to celltypes class and show pass
authorClifford Wolf <clifford@clifford.at>
Sun, 3 Mar 2013 09:36:23 +0000 (10:36 +0100)
committerClifford Wolf <clifford@clifford.at>
Sun, 3 Mar 2013 09:36:23 +0000 (10:36 +0100)
kernel/celltypes.h
kernel/show.cc
passes/extract/extract.cc

index a13cbf32c0a3fe8f58dfb62e6c812cefef88018d..1e56a4dd8005affbe68608e08f945a4a1f0d59c5 100644 (file)
@@ -27,6 +27,7 @@
 struct CellTypes
 {
        std::set<std::string> cell_types;
+       std::vector<const RTLIL::Design*> designs;
 
        void setup_internals()
        {
@@ -99,20 +100,39 @@ struct CellTypes
                cell_types.insert("$_DFF_PP1_");
        }
 
+       void setup_design(const RTLIL::Design *design)
+       {
+               designs.push_back(design);
+       }
+
        void clear()
        {
                cell_types.clear();
+               designs.clear();
        }
 
        bool cell_known(std::string type)
        {
-               return cell_types.count(type) > 0;
+               if (cell_types.count(type) > 0)
+                       return true;
+               for (auto design : designs)
+                       if (design->modules.count(type) > 0)
+                               return true;
+               return false;
        }
 
        bool cell_output(std::string type, std::string port)
        {
-               if (!cell_known(type))
+               if (cell_types.count(type) == 0) {
+                       for (auto design : designs)
+                               if (design->modules.count(type) > 0) {
+                                       if (design->modules.at(type)->wires.count(port))
+                                               return design->modules.at(type)->wires.at(port)->port_output;
+                                       return false;
+                               }
                        return false;
+               }
+
                if (port == "\\Y" || port == "\\Q" || port == "\\RD_DATA")
                        return true;
                if (type == "$memrd" && port == "\\DATA")
@@ -124,9 +144,20 @@ struct CellTypes
 
        bool cell_input(std::string type, std::string port)
        {
-               if (!cell_known(type))
+               if (cell_types.count(type) == 0) {
+                       for (auto design : designs)
+                               if (design->modules.count(type) > 0) {
+                                       if (design->modules.at(type)->wires.count(port))
+                                               return design->modules.at(type)->wires.at(port)->port_input;
+                                       return false;
+                               }
                        return false;
-               return !cell_output(type, port);
+               }
+
+               if (cell_types.count(type) > 0)
+                       return !cell_output(type, port);
+
+               return false;
        }
 
        static RTLIL::Const eval(std::string type, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
index b587a8568982d6e3dfc089eb4be83706beb88965..7c3f418b260e12903233e7420571b91296332085 100644 (file)
@@ -156,6 +156,7 @@ struct ShowWorker
                net_conn_map.clear();
 
                fprintf(f, "digraph \"%s\" {\n", escape(module->name));
+               fprintf(f, "label=\"%s\";\n", escape(module->name));
                fprintf(f, "rankdir=\"LR\";\n");
                fprintf(f, "remincross=true;\n");
 
@@ -274,12 +275,16 @@ struct ShowWorker
                fprintf(f, "};\n");
        }
 
-       ShowWorker(FILE *f, RTLIL::Design *design) : f(f), design(design)
+       ShowWorker(FILE *f, RTLIL::Design *design, std::vector<RTLIL::Design*> &libs) : f(f), design(design)
        {
                ct.setup_internals();
                ct.setup_internals_mem();
                ct.setup_stdcells();
                ct.setup_stdcells_mem();
+               ct.setup_design(design);
+
+               for (auto lib : libs)
+                       ct.setup_design(lib);
 
                design->optimize();
                page_counter = 0;
@@ -303,7 +308,7 @@ struct ShowPass : public Pass {
        {
                //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
                log("\n");
-               log("    show [-viewer <command>] [selection]\n");
+               log("    show [options] [selection]\n");
                log("\n");
                log("Create a graphviz DOT file for the selected part of the design and compile it\n");
                log("to a postscript file.\n");
@@ -311,14 +316,22 @@ struct ShowPass : public Pass {
                log("    -viewer <command>\n");
                log("         Also run the specified command with the postscript file as parameter.\n");
                log("\n");
+               log("    -lib <verilog_or_ilang_file>\n");
+               log("         Use the specified library file for determining whether cell ports are.\n");
+               log("         inputs or outputs. This option can be used multiple times to specify\n");
+               log("         more than one library.\n");
+               log("\n");
                log("The generated output files are `yosys-show.dot' and `yosys-show.ps'.\n");
                log("\n");
        }
        virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
        {
                log_header("Generating Graphviz representation of design.\n");
+               log_push();
 
                std::string viewer_exe;
+               std::vector<std::string> libfiles;
+               std::vector<RTLIL::Design*> libs;
 
                size_t argidx;
                for (argidx = 1; argidx < args.size(); argidx++)
@@ -328,15 +341,32 @@ struct ShowPass : public Pass {
                                viewer_exe = args[++argidx];
                                continue;
                        }
+                       if (arg == "-lib" && argidx+1 < args.size()) {
+                               libfiles.push_back(args[++argidx]);
+                               continue;
+                       }
                        break;
                }
                extra_args(args, argidx, design);
 
+               for (auto filename : libfiles) {
+                       FILE *f = fopen(filename.c_str(), "rt");
+                       if (f == NULL)
+                               log_error("Can't open lib file `%s'.\n", filename.c_str());
+                       RTLIL::Design *lib = new RTLIL::Design;
+                       Frontend::frontend_call(lib, f, filename, (filename.size() > 3 && filename.substr(filename.size()-3) == ".il") ? "ilang" : "verilog");
+                       libs.push_back(lib);
+                       fclose(f);
+               }
+
+               if (libs.size() > 0)
+                       log_header("Continuing show pass.\n");
+
                log("Writing dot description to `yosys-show.dot'.\n");
                FILE *f = fopen("yosys-show.dot", "w");
                if (f == NULL)
                        log_cmd_error("Can't open dot file `yosys-show.dot' for writing.\n");
-               ShowWorker worker(f, design);
+               ShowWorker worker(f, design, libs);
                fclose(f);
 
                if (worker.page_counter == 0)
@@ -353,6 +383,11 @@ struct ShowPass : public Pass {
                        if (system(cmd.c_str()) != 0)
                                log_cmd_error("Shell command failed!\n");
                }
+
+               for (auto lib : libs)
+                       delete lib;
+
+               log_pop();
        }
 } ShowPass;
  
index 94e62b9e8ed1da2b218763aa98738171a762cea4..3e5e4afb2811cff200b29c5614a965e97f144ae0 100644 (file)
@@ -525,7 +525,7 @@ struct ExtractPass : public Pass {
 
                        FILE *f = fopen(filename.c_str(), "wt");
                        if (f == NULL)
-                               log_cmd_error("Can't open output file `%s'.\n", filename.c_str());
+                               log_error("Can't open output file `%s'.\n", filename.c_str());
                        Backend::backend_call(map, f, filename, "ilang");
                        fclose(f);
                }