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;
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
}
}
+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());
}
}
+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++)
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();
}
}
+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++)
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;
+}
+
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 {
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 {
~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 {
~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 {
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 {
~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>
+OBJS += passes/cmds/design.o
OBJS += passes/cmds/select.o
OBJS += passes/cmds/show.o
OBJS += passes/cmds/rename.o
--- /dev/null
+/*
+ * 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;
+