From 0f38008ed34e36e798f521b4b6d4fea89ae31a3b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 27 Jul 2013 14:27:51 +0200 Subject: [PATCH] Added "design" command (-reset, -save, -load) --- frontends/ast/ast.cc | 15 +++++ frontends/ast/ast.h | 1 + kernel/rtlil.cc | 89 +++++++++++++++++++++++++++ kernel/rtlil.h | 24 ++++---- passes/cmds/Makefile.inc | 1 + passes/cmds/design.cc | 128 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 246 insertions(+), 12 deletions(-) create mode 100644 passes/cmds/design.cc diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 3e9ea50ac..e7aa472ef 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -896,6 +896,21 @@ void AstModule::update_auto_wires(std::map 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; diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 99760e09c..f6bb7a40f 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -205,6 +205,7 @@ namespace AST virtual ~AstModule(); virtual RTLIL::IdString derive(RTLIL::Design *design, std::map parameters); virtual void update_auto_wires(std::map auto_sizes); + virtual RTLIL::Module *clone() const; }; // this must be set by the language frontend before parsing the sources diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index a10912868..6271aeef8 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -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; +} + diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 6dde475d1..f5e8ae477 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -239,8 +239,9 @@ struct RTLIL::Module { void add(RTLIL::Cell *cell); void fixup_ports(); - template - void rewrite_sigspecs(T functor); + template 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 parameters; void optimize(); - template - void rewrite_sigspecs(T functor); + template void rewrite_sigspecs(T functor); }; struct RTLIL::SigChunk { @@ -337,8 +337,8 @@ struct RTLIL::CaseRule { ~CaseRule(); void optimize(); - template - void rewrite_sigspecs(T functor); + template void rewrite_sigspecs(T functor); + RTLIL::CaseRule *clone() const; }; struct RTLIL::SwitchRule { @@ -348,8 +348,8 @@ struct RTLIL::SwitchRule { ~SwitchRule(); void optimize(); - template - void rewrite_sigspecs(T functor); + template void rewrite_sigspecs(T functor); + RTLIL::SwitchRule *clone() const; }; struct RTLIL::SyncRule { @@ -358,8 +358,8 @@ struct RTLIL::SyncRule { std::vector actions; void optimize(); - template - void rewrite_sigspecs(T functor); + template void rewrite_sigspecs(T functor); + RTLIL::SyncRule *clone() const; }; struct RTLIL::Process { @@ -370,8 +370,8 @@ struct RTLIL::Process { ~Process(); void optimize(); - template - void rewrite_sigspecs(T functor); + template void rewrite_sigspecs(T functor); + RTLIL::Process *clone() const; }; template diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index 75bfa5b8b..9dc85b1ef 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -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 index 000000000..2f599adb0 --- /dev/null +++ b/passes/cmds/design.cc @@ -0,0 +1,128 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * 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 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 \n"); + log("\n"); + log("Save the current design under the given name.\n"); + log("\n"); + log("\n"); + log(" design -load \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 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; +