aboutsummaryrefslogtreecommitdiffstats
path: root/passes/cmds/setattr.cc
diff options
context:
space:
mode:
Diffstat (limited to 'passes/cmds/setattr.cc')
-rw-r--r--passes/cmds/setattr.cc119
1 files changed, 98 insertions, 21 deletions
diff --git a/passes/cmds/setattr.cc b/passes/cmds/setattr.cc
index 9a6d8a038..9b05ae32f 100644
--- a/passes/cmds/setattr.cc
+++ b/passes/cmds/setattr.cc
@@ -2,11 +2,11 @@
* 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
@@ -32,25 +32,20 @@ struct setunset_t
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)
+ setunset_t(std::string set_name, std::string set_value) : 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);
+ if (set_value.substr(0, 1) == "\"" && set_value.substr(GetSize(set_value)-1) == "\"") {
+ value = RTLIL::Const(set_value.substr(1, GetSize(set_value)-2));
} 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());
+ if (!RTLIL::SigSpec::parse(sig_value, NULL, set_value))
+ log_cmd_error("Can't decode value '%s'!\n", set_value.c_str());
value = sig_value.as_const();
}
}
};
-static void do_setunset(dict<RTLIL::IdString, RTLIL::Const> &attrs, std::vector<setunset_t> &list)
+static void do_setunset(dict<RTLIL::IdString, RTLIL::Const> &attrs, const std::vector<setunset_t> &list)
{
for (auto &item : list)
if (item.unset)
@@ -84,9 +79,9 @@ struct SetattrPass : public Pass {
{
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--;
+ string set_key = args[++argidx];
+ string set_val = args[++argidx];
+ setunset_list.push_back(setunset_t(set_key, set_val));
continue;
}
if (arg == "-unset" && argidx+1 < args.size()) {
@@ -132,7 +127,7 @@ struct SetattrPass : public Pass {
}
}
} SetattrPass;
-
+
struct SetparamPass : public Pass {
SetparamPass() : Pass("setparam", "set/unset parameters on objects") { }
virtual void help()
@@ -154,9 +149,9 @@ struct SetparamPass : public Pass {
{
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--;
+ string set_key = args[++argidx];
+ string set_val = args[++argidx];
+ setunset_list.push_back(setunset_t(set_key, set_val));
continue;
}
if (arg == "-unset" && argidx+1 < args.size()) {
@@ -180,5 +175,87 @@ struct SetparamPass : public Pass {
}
}
} SetparamPass;
-
+
+struct ChparamPass : public Pass {
+ ChparamPass() : Pass("chparam", "re-evaluate modules with new parameters") { }
+ virtual void help()
+ {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+ log("\n");
+ log(" chparam [ -set name value ]... [selection]\n");
+ log("\n");
+ log("Re-evaluate the selected modules with new parameters. String values must be\n");
+ log("passed in double quotes (\").\n");
+ log("\n");
+ log("\n");
+ log(" chparam -list [selection]\n");
+ log("\n");
+ log("List the available parameters of the selected modules.\n");
+ log("\n");
+ }
+ virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+ {
+ std::vector<setunset_t> setunset_list;
+ dict<RTLIL::IdString, RTLIL::Const> new_parameters;
+ bool list_mode = false;
+
+ size_t argidx;
+ for (argidx = 1; argidx < args.size(); argidx++)
+ {
+ std::string arg = args[argidx];
+ if (arg == "-set" && argidx+2 < args.size()) {
+ string set_key = args[++argidx];
+ string set_val = args[++argidx];
+ setunset_list.push_back(setunset_t(set_key, set_val));
+ continue;
+ }
+ if (arg == "-list") {
+ list_mode = true;
+ continue;
+ }
+ break;
+ }
+
+ for (int i = argidx; i < GetSize(args); i++)
+ if (design->module("$abstract\\" + args[i]) != nullptr &&
+ design->module(RTLIL::escape_id(args[i])) == nullptr)
+ args[i] = "$abstract\\" + args[i];
+
+ extra_args(args, argidx, design);
+
+ do_setunset(new_parameters, setunset_list);
+
+ if (list_mode) {
+ if (!new_parameters.empty())
+ log_cmd_error("The options -set and -list cannot be used together.\n");
+ for (auto module : design->selected_modules()) {
+ log("%s:\n", log_id(module));
+ for (auto param : module->avail_parameters)
+ log(" %s\n", log_id(param));
+ }
+ return;
+ }
+
+ pool<IdString> modnames, old_modnames;
+ for (auto module : design->selected_whole_modules_warn()) {
+ modnames.insert(module->name);
+ old_modnames.insert(module->name);
+ }
+ modnames.sort();
+
+ for (auto modname : modnames) {
+ Module *module = design->module(modname);
+ Module *new_module = design->module(module->derive(design, new_parameters));
+ if (module != new_module) {
+ Module *m = new_module->clone();
+ m->name = module->name;
+ design->remove(module);
+ design->add(m);
+ }
+ if (old_modnames.count(new_module->name) == 0)
+ design->remove(new_module);
+ }
+ }
+} ChparamPass;
+
PRIVATE_NAMESPACE_END