Added "design" command (-reset, -save, -load)
authorClifford Wolf <clifford@clifford.at>
Sat, 27 Jul 2013 12:27:51 +0000 (14:27 +0200)
committerClifford Wolf <clifford@clifford.at>
Sat, 27 Jul 2013 12:27:51 +0000 (14:27 +0200)
frontends/ast/ast.cc
frontends/ast/ast.h
kernel/rtlil.cc
kernel/rtlil.h
passes/cmds/Makefile.inc
passes/cmds/design.cc [new file with mode: 0644]

index 3e9ea50acb55c0f42f4d8435fde7eb35f1ac23b1..e7aa472efa915a6ef401c51401e973ee3caa97fc 100644 (file)
@@ -896,6 +896,21 @@ void AstModule::update_auto_wires(std::map<RTLIL::IdString, int> auto_sizes)
        delete newmod;
 }
 
+RTLIL::Module *AstModule::clone() const
+{
+       AstModule *new_mod = new AstModule;
+       cloneInto(new_mod);
+
+       new_mod->ast = ast->clone();
+       new_mod->nolatches = nolatches;
+       new_mod->nomem2reg = nomem2reg;
+       new_mod->mem2reg = mem2reg;
+       new_mod->lib = lib;
+       new_mod->noopt = noopt;
+
+       return new_mod;
+}
+
 // internal dummy line number callbacks
 namespace {
        int internal_line_num;
index 99760e09c13c8f61a5c9a429f2a42512f3b7d365..f6bb7a40fb1feced744b517eb785b18e92d94621 100644 (file)
@@ -205,6 +205,7 @@ namespace AST
                virtual ~AstModule();
                virtual RTLIL::IdString derive(RTLIL::Design *design, std::map<RTLIL::IdString, RTLIL::Const> parameters);
                virtual void update_auto_wires(std::map<RTLIL::IdString, int> auto_sizes);
+               virtual RTLIL::Module *clone() const;
        };
 
        // this must be set by the language frontend before parsing the sources
index a109128683661c54ef4ea87040539d5fa9c8f4ed..6271aeef8313d21fe76b651a84bb6d438ebf66c9 100644 (file)
@@ -341,6 +341,47 @@ void RTLIL::Module::optimize()
        }
 }
 
+void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const
+{
+       new_mod->name = name;
+       new_mod->connections = connections;
+       new_mod->attributes = attributes;
+
+       for (auto &it : wires)
+               new_mod->wires[it.first] = new RTLIL::Wire(*it.second);
+
+       for (auto &it : memories)
+               new_mod->memories[it.first] = new RTLIL::Memory(*it.second);
+
+       for (auto &it : cells)
+               new_mod->cells[it.first] = new RTLIL::Cell(*it.second);
+
+       for (auto &it : processes)
+               new_mod->processes[it.first] = it.second->clone();
+
+       struct RewriteSigSpecWorker
+       {
+               RTLIL::Module *mod;
+               void operator()(RTLIL::SigSpec &sig)
+               {
+                       for (auto &c : sig.chunks)
+                               if (c.wire != NULL)
+                                       c.wire = mod->wires.at(c.wire->name);
+               }
+       };
+
+       RewriteSigSpecWorker rewriteSigSpecWorker;
+       rewriteSigSpecWorker.mod = new_mod;
+       new_mod->rewrite_sigspecs(rewriteSigSpecWorker);
+}
+
+RTLIL::Module *RTLIL::Module::clone() const
+{
+       RTLIL::Module *new_mod = new RTLIL::Module;
+       cloneInto(new_mod);
+       return new_mod;
+}
+
 void RTLIL::Module::add(RTLIL::Wire *wire)
 {
        assert(!wire->name.empty());
@@ -1165,6 +1206,16 @@ void RTLIL::CaseRule::optimize()
        }
 }
 
+RTLIL::CaseRule *RTLIL::CaseRule::clone() const
+{
+       RTLIL::CaseRule *new_caserule = new RTLIL::CaseRule;
+       new_caserule->compare = compare;
+       new_caserule->actions = actions;
+       for (auto &it : switches)
+               new_caserule->switches.push_back(it->clone());
+       return new_caserule;
+}
+
 RTLIL::SwitchRule::~SwitchRule()
 {
        for (auto it = cases.begin(); it != cases.end(); it++)
@@ -1178,6 +1229,17 @@ void RTLIL::SwitchRule::optimize()
                it->optimize();
 }
 
+RTLIL::SwitchRule *RTLIL::SwitchRule::clone() const
+{
+       RTLIL::SwitchRule *new_switchrule = new RTLIL::SwitchRule;
+       new_switchrule->signal = signal;
+       new_switchrule->attributes = attributes;
+       for (auto &it : cases)
+               new_switchrule->cases.push_back(it->clone());
+       return new_switchrule;
+       
+}
+
 void RTLIL::SyncRule::optimize()
 {
        signal.optimize();
@@ -1187,6 +1249,15 @@ void RTLIL::SyncRule::optimize()
        }
 }
 
+RTLIL::SyncRule *RTLIL::SyncRule::clone() const
+{
+       RTLIL::SyncRule *new_syncrule = new RTLIL::SyncRule;
+       new_syncrule->type = type;
+       new_syncrule->signal = signal;
+       new_syncrule->actions = actions;
+       return new_syncrule;
+}
+
 RTLIL::Process::~Process()
 {
        for (auto it = syncs.begin(); it != syncs.end(); it++)
@@ -1200,3 +1271,21 @@ void RTLIL::Process::optimize()
                it->optimize();
 }
 
+RTLIL::Process *RTLIL::Process::clone() const
+{
+       RTLIL::Process *new_proc = new RTLIL::Process;
+
+       new_proc->name = name;
+       new_proc->attributes = attributes;
+
+       RTLIL::CaseRule *rc_ptr = root_case.clone();
+       new_proc->root_case = *rc_ptr;
+       rc_ptr->switches.clear();
+       delete rc_ptr;
+
+       for (auto &it : syncs)
+               new_proc->syncs.push_back(it->clone());
+       
+       return new_proc;
+}
+
index 6dde475d191622b57408a41d943ed3fb8a1e6ac6..f5e8ae47798ccb3f2757fa8170a41ce1490b1d4e 100644 (file)
@@ -239,8 +239,9 @@ struct RTLIL::Module {
        void add(RTLIL::Cell *cell);
        void fixup_ports();
 
-       template<typename T>
-       void rewrite_sigspecs(T functor);
+       template<typename T> void rewrite_sigspecs(T functor);
+       void cloneInto(RTLIL::Module *new_mod) const;
+       virtual RTLIL::Module *clone() const;
 };
 
 struct RTLIL::Wire {
@@ -266,8 +267,7 @@ struct RTLIL::Cell {
        std::map<RTLIL::IdString, RTLIL::Const> parameters;
        void optimize();
 
-       template<typename T>
-       void rewrite_sigspecs(T functor);
+       template<typename T> void rewrite_sigspecs(T functor);
 };
 
 struct RTLIL::SigChunk {
@@ -337,8 +337,8 @@ struct RTLIL::CaseRule {
        ~CaseRule();
        void optimize();
 
-       template<typename T>
-       void rewrite_sigspecs(T functor);
+       template<typename T> void rewrite_sigspecs(T functor);
+       RTLIL::CaseRule *clone() const;
 };
 
 struct RTLIL::SwitchRule {
@@ -348,8 +348,8 @@ struct RTLIL::SwitchRule {
        ~SwitchRule();
        void optimize();
 
-       template<typename T>
-       void rewrite_sigspecs(T functor);
+       template<typename T> void rewrite_sigspecs(T functor);
+       RTLIL::SwitchRule *clone() const;
 };
 
 struct RTLIL::SyncRule {
@@ -358,8 +358,8 @@ struct RTLIL::SyncRule {
        std::vector<RTLIL::SigSig> actions;
        void optimize();
 
-       template<typename T>
-       void rewrite_sigspecs(T functor);
+       template<typename T> void rewrite_sigspecs(T functor);
+       RTLIL::SyncRule *clone() const;
 };
 
 struct RTLIL::Process {
@@ -370,8 +370,8 @@ struct RTLIL::Process {
        ~Process();
        void optimize();
 
-       template<typename T>
-       void rewrite_sigspecs(T functor);
+       template<typename T> void rewrite_sigspecs(T functor);
+       RTLIL::Process *clone() const;
 };
 
 template<typename T>
index 75bfa5b8bf1ce96c1d83235dd481c295046dd26f..9dc85b1ef76ce08714c64f6b059a42a60adfc2c0 100644 (file)
@@ -1,4 +1,5 @@
 
+OBJS += passes/cmds/design.o
 OBJS += passes/cmds/select.o
 OBJS += passes/cmds/show.o
 OBJS += passes/cmds/rename.o
diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc
new file mode 100644 (file)
index 0000000..2f599ad
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ *  yosys -- Yosys Open SYnthesis Suite
+ *
+ *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
+ *  
+ *  Permission to use, copy, modify, and/or distribute this software for any
+ *  purpose with or without fee is hereby granted, provided that the above
+ *  copyright notice and this permission notice appear in all copies.
+ *  
+ *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "kernel/register.h"
+#include "kernel/celltypes.h"
+#include "kernel/rtlil.h"
+#include "kernel/log.h"
+
+struct DesignPass : public Pass {
+       DesignPass() : Pass("design", "save, restore and reset current design") { }
+       std::map<std::string, RTLIL::Design*> saved_designs;
+       virtual ~DesignPass() {
+               for (auto &it : saved_designs)
+                       delete it.second;
+               saved_designs.clear();
+       }
+       virtual void help()
+       {
+               //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+               log("\n");
+               log("    design -reset\n");
+               log("\n");
+               log("Clear the current design.\n");
+               log("\n");
+               log("\n");
+               log("    design -save <name>\n");
+               log("\n");
+               log("Save the current design under the given name.\n");
+               log("\n");
+               log("\n");
+               log("    design -load <name>\n");
+               log("\n");
+               log("Reset the current design and load the design previously saved under the given\n");
+               log("name.\n");
+               log("\n");
+       }
+       virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+       {
+               bool got_mode = false;
+               bool reset_mode = false;
+               std::string save_name, load_name;
+
+               size_t argidx;
+               for (argidx = 1; argidx < args.size(); argidx++)
+               {
+                       std::string arg = args[argidx];
+                       if (!got_mode && arg == "-reset") {
+                               got_mode = true;
+                               reset_mode = true;
+                               continue;
+                       }
+                       if (arg == "-save" && argidx+1 < args.size()) {
+                               got_mode = true;
+                               save_name = args[++argidx];
+                               continue;
+                       }
+                       if (arg == "-load" && argidx+1 < args.size()) {
+                               got_mode = true;
+                               load_name = args[++argidx];
+                               if (saved_designs.count(load_name) == 0)
+                                       log_cmd_error("No saved design '%s' found!\n", load_name.c_str());
+                               continue;
+                       }
+               }
+               extra_args(args, argidx, design, false);
+
+               if (!got_mode)
+                       cmd_error(args, argidx, "Missing mode argument (-reset, -save, or -load).");
+
+               if (reset_mode || !load_name.empty())
+               {
+                       for (auto &it : design->modules)
+                               delete it.second;
+                       design->modules.clear();
+
+                       design->selection_stack.clear();
+                       design->selection_vars.clear();
+                       design->selected_active_module.clear();
+
+                       design->selection_stack.push_back(RTLIL::Selection());
+               }
+
+               if (!save_name.empty())
+               {
+                       RTLIL::Design *design_copy = new RTLIL::Design;
+
+                       for (auto &it : design->modules)
+                               design_copy->modules[it.first] = it.second->clone();
+
+                       design_copy->selection_stack = design->selection_stack;
+                       design_copy->selection_vars = design->selection_vars;
+                       design_copy->selected_active_module = design->selected_active_module;
+
+                       if (saved_designs.count(save_name))
+                               delete saved_designs.at(save_name);
+                       saved_designs[save_name] = design_copy;
+               }
+
+               if (!load_name.empty())
+               {
+                       RTLIL::Design *saved_design = saved_designs.at(load_name);
+
+                       for (auto &it : saved_design->modules)
+                               design->modules[it.first] = it.second->clone();
+
+                       design->selection_stack = saved_design->selection_stack;
+                       design->selection_vars = saved_design->selection_vars;
+                       design->selected_active_module = saved_design->selected_active_module;
+               }
+       }
+} DesignPass;