summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--passes/cmds/Makefile.inc1
-rw-r--r--passes/cmds/setattr.cc180
2 files changed, 181 insertions, 0 deletions
diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc
index 52c53e03..8020adff 100644
--- a/passes/cmds/Makefile.inc
+++ b/passes/cmds/Makefile.inc
@@ -10,4 +10,5 @@ OBJS += passes/cmds/scatter.o
OBJS += passes/cmds/setundef.o
OBJS += passes/cmds/splitnets.o
OBJS += passes/cmds/stat.o
+OBJS += passes/cmds/setattr.o
diff --git a/passes/cmds/setattr.cc b/passes/cmds/setattr.cc
new file mode 100644
index 00000000..8d98df71
--- /dev/null
+++ b/passes/cmds/setattr.cc
@@ -0,0 +1,180 @@
+/*
+ * 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/rtlil.h"
+#include "kernel/log.h"
+
+struct setunset_t
+{
+ RTLIL::IdString name;
+ RTLIL::Const value;
+ bool unset;
+
+ setunset_t(std::string unset_name) : name(RTLIL::escape_id(unset_name)), value(), unset(true) { }
+
+ setunset_t(std::string set_name, std::vector<std::string> args, size_t &argidx) : name(RTLIL::escape_id(set_name)), value(), unset(false)
+ {
+ if (!args[argidx].empty() && args[argidx][0] == '"') {
+ std::string str = args[argidx++].substr(1);
+ while (str.size() != 0 && str[str.size()-1] != '"' && argidx < args.size())
+ str += args[argidx++];
+ if (str.size() != 0 && str[str.size()-1] == '"')
+ str = str.substr(0, str.size()-1);
+ value = RTLIL::Const(str);
+ } else {
+ RTLIL::SigSpec sig_value;
+ if (!RTLIL::SigSpec::parse(sig_value, NULL, args[argidx++]))
+ log_cmd_error("Can't decode value '%s'!\n", args[argidx-1].c_str());
+ value = sig_value.as_const();
+ }
+ }
+};
+
+static void do_setunset(std::map<RTLIL::IdString, RTLIL::Const> &attrs, std::vector<setunset_t> &list)
+{
+ for (auto &item : list)
+ if (item.unset)
+ attrs.erase(item.name);
+ else
+ attrs[item.name] = item.value;
+}
+
+struct SetattrPass : public Pass {
+ SetattrPass() : Pass("setattr", "set/unset attributes on objects") { }
+ virtual void help()
+ {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+ log("\n");
+ log(" setattr [ -mod ] [ -set name value | -unset name ]... [selection]\n");
+ log("\n");
+ log("Set/unset the given attributes on the selected objects. String values must be\n");
+ log("passed in double quotes (\").\n");
+ log("\n");
+ log("When called with -mod, this command will set and unset attributes on modules\n");
+ log("instead of objects within modules.\n");
+ log("\n");
+ }
+ virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+ {
+ std::vector<setunset_t> setunset_list;
+ bool flag_mod = false;
+
+ size_t argidx;
+ for (argidx = 1; argidx < args.size(); argidx++)
+ {
+ std::string arg = args[argidx];
+ if (arg == "-set" && argidx+2 < args.size()) {
+ argidx += 2;
+ setunset_list.push_back(setunset_t(args[argidx-1], args, argidx));
+ argidx--;
+ continue;
+ }
+ if (arg == "-unset" && argidx+1 < args.size()) {
+ setunset_list.push_back(setunset_t(args[++argidx]));
+ continue;
+ }
+ if (arg == "-mod") {
+ flag_mod = true;
+ continue;
+ }
+ break;
+ }
+ extra_args(args, argidx, design);
+
+ for (auto &mod : design->modules)
+ {
+ RTLIL::Module *module = mod.second;
+
+ if (flag_mod) {
+ if (design->selected_whole_module(module->name))
+ do_setunset(module->attributes, setunset_list);
+ continue;
+ }
+
+ if (!design->selected(module))
+ continue;
+
+ for (auto &it : module->wires)
+ if (design->selected(module, it.second))
+ do_setunset(it.second->attributes, setunset_list);
+
+ for (auto &it : module->memories)
+ if (design->selected(module, it.second))
+ do_setunset(it.second->attributes, setunset_list);
+
+ for (auto &it : module->cells)
+ if (design->selected(module, it.second))
+ do_setunset(it.second->attributes, setunset_list);
+
+ for (auto &it : module->processes)
+ if (design->selected(module, it.second))
+ do_setunset(it.second->attributes, setunset_list);
+ }
+ }
+} SetattrPass;
+
+struct SetparamPass : public Pass {
+ SetparamPass() : Pass("setparam", "set/unset parameters on objects") { }
+ virtual void help()
+ {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+ log("\n");
+ log(" setparam [ -set name value | -unset name ]... [selection]\n");
+ log("\n");
+ log("Set/unset the given parameters on the selected cells. String values must be\n");
+ log("passed in double quotes (\").\n");
+ log("\n");
+ }
+ virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+ {
+ std::vector<setunset_t> setunset_list;
+
+ size_t argidx;
+ for (argidx = 1; argidx < args.size(); argidx++)
+ {
+ std::string arg = args[argidx];
+ if (arg == "-set" && argidx+2 < args.size()) {
+ argidx += 2;
+ setunset_list.push_back(setunset_t(args[argidx-1], args, argidx));
+ argidx--;
+ continue;
+ }
+ if (arg == "-unset" && argidx+1 < args.size()) {
+ setunset_list.push_back(setunset_t(args[++argidx]));
+ continue;
+ }
+ break;
+ }
+ extra_args(args, argidx, design);
+
+ for (auto &mod : design->modules)
+ {
+ RTLIL::Module *module = mod.second;
+
+ if (!design->selected(module))
+ continue;
+
+ for (auto &it : module->cells)
+ if (design->selected(module, it.second))
+ do_setunset(it.second->parameters, setunset_list);
+ }
+ }
+} SetparamPass;
+