Added "dump" command (part ilang backend)
authorClifford Wolf <clifford@clifford.at>
Sun, 2 Jun 2013 15:53:30 +0000 (17:53 +0200)
committerClifford Wolf <clifford@clifford.at>
Sun, 2 Jun 2013 15:53:30 +0000 (17:53 +0200)
backends/ilang/ilang_backend.cc
backends/ilang/ilang_backend.h
kernel/rtlil.cc
kernel/rtlil.h

index 8dcdb12881e0c99484ccfb3fa2f9449dc3e35d81..9c74e61ca9da5025c1aa2c7086f58916dc040d22 100644 (file)
@@ -27,6 +27,8 @@
 #include "kernel/log.h"
 #include <string>
 #include <assert.h>
+#include <string.h>
+#include <errno.h>
 
 using namespace ILANG_BACKEND;
 
@@ -257,7 +259,7 @@ void ILANG_BACKEND::dump_conn(FILE *f, std::string indent, const RTLIL::SigSpec
        fprintf(f, "\n");
 }
 
-void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module *module)
+void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module *module, const RTLIL::Design *design, bool only_selected)
 {
        for (auto it = module->attributes.begin(); it != module->attributes.end(); it++) {
                fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str());
@@ -268,29 +270,63 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module
        fprintf(f, "%s" "module %s\n", indent.c_str(), module->name.c_str());
 
        for (auto it = module->wires.begin(); it != module->wires.end(); it++)
-               dump_wire(f, indent + "  ", it->second);
+               if (!only_selected || design->selected(module, it->second)) {
+                       if (only_selected)
+                               fprintf(f, "\n");
+                       dump_wire(f, indent + "  ", it->second);
+               }
 
        for (auto it = module->memories.begin(); it != module->memories.end(); it++)
-               dump_memory(f, indent + "  ", it->second);
+               if (!only_selected || design->selected(module, it->second)) {
+                       if (only_selected)
+                               fprintf(f, "\n");
+                       dump_memory(f, indent + "  ", it->second);
+               }
 
        for (auto it = module->cells.begin(); it != module->cells.end(); it++)
-               dump_cell(f, indent + "  ", it->second);
+               if (!only_selected || design->selected(module, it->second)) {
+                       if (only_selected)
+                               fprintf(f, "\n");
+                       dump_cell(f, indent + "  ", it->second);
+               }
 
        for (auto it = module->processes.begin(); it != module->processes.end(); it++)
-               dump_proc(f, indent + "  ", it->second);
+               if (!only_selected || design->selected(module, it->second)) {
+                       if (only_selected)
+                               fprintf(f, "\n");
+                       dump_proc(f, indent + "  ", it->second);
+               }
 
-       for (auto it = module->connections.begin(); it != module->connections.end(); it++)
-               dump_conn(f, indent + "  ", it->first, it->second);
+       bool first_conn_line = true;
+       for (auto it = module->connections.begin(); it != module->connections.end(); it++) {
+               bool show_conn = !only_selected;
+               if (only_selected) {
+                       RTLIL::SigSpec sigs = it->first;
+                       sigs.append(it->second);
+                       for (auto &c : sigs.chunks) {
+                               if (c.wire == NULL || !design->selected(module, c.wire))
+                                       continue;
+                               show_conn = true;
+                       }
+               }
+               if (show_conn) {
+                       if (only_selected && first_conn_line)
+                               fprintf(f, "\n");
+                       dump_conn(f, indent + "  ", it->first, it->second);
+                       first_conn_line = false;
+               }
+       }
 
        fprintf(f, "%s" "end\n", indent.c_str());
 }
 
-void ILANG_BACKEND::dump_design(FILE *f, const RTLIL::Design *design)
+void ILANG_BACKEND::dump_design(FILE *f, const RTLIL::Design *design, bool only_selected)
 {
        for (auto it = design->modules.begin(); it != design->modules.end(); it++) {
-               if (it != design->modules.begin())
+               if (it != design->modules.begin() || only_selected)
                        fprintf(f, "\n");
-               dump_module(f, "", it->second);
+               if (!only_selected || design->selected(it->second))
+                       dump_module(f, "", it->second, design, only_selected);
        }
 }
 
@@ -310,7 +346,61 @@ struct IlangBackend : public Backend {
                log_header("Executing ILANG backend.\n");
                extra_args(f, filename, args, 1);
                log("Output filename: %s\n", filename.c_str());
-               ILANG_BACKEND::dump_design(f, design);
+               ILANG_BACKEND::dump_design(f, design, false);
        }
 } IlangBackend;
 
+struct DumpPass : public Pass {
+       DumpPass() : Pass("dump", "print parts of the design in ilang format") { }
+       virtual void help()
+       {
+               //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+               log("\n");
+               log("    dump [options] [selection]\n");
+               log("\n");
+               log("Write the selected parts of the design to the console or specified file in\n");
+               log("ilang format.\n");
+               log("\n");
+               log("    -outfile <filename>\n");
+               log("        Write to the specified file.\n");
+               log("\n");
+       }
+       virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+       {
+               std::string filename;
+
+               size_t argidx;
+               for (argidx = 1; argidx < args.size(); argidx++)
+               {
+                       std::string arg = args[argidx];
+                       if (arg == "-outfile" && argidx+1 < args.size()) {
+                               filename = args[++argidx];
+                               continue;
+                       }
+                       break;
+               }
+               extra_args(args, argidx, design);
+
+               FILE *f = NULL;
+               char *buf_ptr;
+               size_t buf_size;
+
+               if (!filename.empty()) {
+                       f = fopen(filename.c_str(), "w");
+                       if (f == NULL)
+                               log_error("Can't open file `%s' for writing: %s\n", filename.c_str(), strerror(errno));
+               } else {
+                       f = open_memstream(&buf_ptr, &buf_size);
+               }
+
+               ILANG_BACKEND::dump_design(f, design, true);
+
+               fclose(f);
+
+               if (filename.empty()) {
+                       log("%s", buf_ptr);
+                       free(buf_ptr);
+               }
+       }
+} DumpPass;
index e34c4e6752715eab5638e7082b17b4e9bae3b8b8..b9700970fe576ec670390bfd5207e7014e8408cc 100644 (file)
@@ -40,8 +40,8 @@ namespace ILANG_BACKEND {
        void dump_proc_sync(FILE *f, std::string indent, const RTLIL::SyncRule *sy);
        void dump_proc(FILE *f, std::string indent, const RTLIL::Process *proc);
        void dump_conn(FILE *f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right);
-       void dump_module(FILE *f, std::string indent, const RTLIL::Module *module);
-       void dump_design(FILE *f, const RTLIL::Design *design);
+       void dump_module(FILE *f, std::string indent, const RTLIL::Module *module, const RTLIL::Design *design, bool only_selected);
+       void dump_design(FILE *f, const RTLIL::Design *design, bool only_selected);
 }
 
 #endif
index b0dcfe42892058360f4df57bc9f1d3aa22a40ce9..2c255285f09ac3d8f665c010c7e51d6ccde2dd8f 100644 (file)
@@ -101,7 +101,7 @@ std::string RTLIL::Const::as_string() const
        return ret;
 }
 
-bool RTLIL::Selection::selected_module(RTLIL::IdString mod_name)
+bool RTLIL::Selection::selected_module(RTLIL::IdString mod_name) const
 {
        if (full_selection)
                return true;
@@ -112,7 +112,7 @@ bool RTLIL::Selection::selected_module(RTLIL::IdString mod_name)
        return false;
 }
 
-bool RTLIL::Selection::selected_whole_module(RTLIL::IdString mod_name)
+bool RTLIL::Selection::selected_whole_module(RTLIL::IdString mod_name) const
 {
        if (full_selection)
                return true;
@@ -121,14 +121,14 @@ bool RTLIL::Selection::selected_whole_module(RTLIL::IdString mod_name)
        return false;
 }
 
-bool RTLIL::Selection::selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name)
+bool RTLIL::Selection::selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name) const
 {
        if (full_selection)
                return true;
        if (selected_modules.count(mod_name) > 0)
                return true;
        if (selected_members.count(mod_name) > 0)
-               if (selected_members[mod_name].count(memb_name) > 0)
+               if (selected_members.at(mod_name).count(memb_name) > 0)
                        return true;
        return false;
 }
@@ -217,7 +217,7 @@ void RTLIL::Design::optimize()
                it.second.optimize(this);
 }
 
-bool RTLIL::Design::selected_module(RTLIL::IdString mod_name)
+bool RTLIL::Design::selected_module(RTLIL::IdString mod_name) const
 {
        if (!selected_active_module.empty() && mod_name != selected_active_module)
                return false;
@@ -226,7 +226,7 @@ bool RTLIL::Design::selected_module(RTLIL::IdString mod_name)
        return selection_stack.back().selected_module(mod_name);
 }
 
-bool RTLIL::Design::selected_whole_module(RTLIL::IdString mod_name)
+bool RTLIL::Design::selected_whole_module(RTLIL::IdString mod_name) const
 {
        if (!selected_active_module.empty() && mod_name != selected_active_module)
                return false;
@@ -235,7 +235,7 @@ bool RTLIL::Design::selected_whole_module(RTLIL::IdString mod_name)
        return selection_stack.back().selected_whole_module(mod_name);
 }
 
-bool RTLIL::Design::selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name)
+bool RTLIL::Design::selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name) const
 {
        if (!selected_active_module.empty() && mod_name != selected_active_module)
                return false;
index fe88182fa86d3af31c6b5dad8a2926bd282f54fe..b150828891cf20af70a7998b5217a3c79e3bd22a 100644 (file)
@@ -189,9 +189,9 @@ struct RTLIL::Selection {
        std::set<RTLIL::IdString> selected_modules;
        std::map<RTLIL::IdString, std::set<RTLIL::IdString>> selected_members;
        Selection(bool full = true) : full_selection(full) { }
-       bool selected_module(RTLIL::IdString mod_name);
-       bool selected_whole_module(RTLIL::IdString mod_name);
-       bool selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name);
+       bool selected_module(RTLIL::IdString mod_name) const;
+       bool selected_whole_module(RTLIL::IdString mod_name) const;
+       bool selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name) const;
        void optimize(RTLIL::Design *design);
 };
 
@@ -203,20 +203,20 @@ struct RTLIL::Design {
        ~Design();
        void check();
        void optimize();
-       bool selected_module(RTLIL::IdString mod_name);
-       bool selected_whole_module(RTLIL::IdString mod_name);
-       bool selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name);
-       template<typename T1> bool selected(T1 *module) {
+       bool selected_module(RTLIL::IdString mod_name) const;
+       bool selected_whole_module(RTLIL::IdString mod_name) const;
+       bool selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name) const;
+       template<typename T1> bool selected(T1 *module) const {
                return selected_module(module->name);
        }
-       template<typename T1, typename T2> bool selected(T1 *module, T2 *member) {
+       template<typename T1, typename T2> bool selected(T1 *module, T2 *member) const {
                return selected_member(module->name, member->name);
        }
        template<typename T1, typename T2> void select(T1 *module, T2 *member) {
                if (selection_stack.size() > 0) {
                        RTLIL::Selection &sel = selection_stack.back();
                        if (!sel.full_selection && sel.selected_modules.count(module->name) == 0)
-                               sel.selected_members[module->name].insert(member->name);
+                               sel.selected_members.at(module->name).insert(member->name);
                }
        }
 };