2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include "kernel/register.h"
21 #include "kernel/rtlil.h"
22 #include "kernel/log.h"
25 PRIVATE_NAMESPACE_BEGIN
33 setunset_t(std::string unset_name
) : name(RTLIL::escape_id(unset_name
)), value(), unset(true) { }
35 setunset_t(std::string set_name
, std::string set_value
) : name(RTLIL::escape_id(set_name
)), value(), unset(false)
37 if (set_value
.substr(0, 1) == "\"" && set_value
.substr(GetSize(set_value
)-1) == "\"") {
38 value
= RTLIL::Const(set_value
.substr(1, GetSize(set_value
)-2));
40 RTLIL::SigSpec sig_value
;
41 if (!RTLIL::SigSpec::parse(sig_value
, NULL
, set_value
))
42 log_cmd_error("Can't decode value '%s'!\n", set_value
.c_str());
43 value
= sig_value
.as_const();
48 static void do_setunset(dict
<RTLIL::IdString
, RTLIL::Const
> &attrs
, const std::vector
<setunset_t
> &list
)
50 for (auto &item
: list
)
52 attrs
.erase(item
.name
);
54 attrs
[item
.name
] = item
.value
;
57 struct SetattrPass
: public Pass
{
58 SetattrPass() : Pass("setattr", "set/unset attributes on objects") { }
59 void help() YS_OVERRIDE
61 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
63 log(" setattr [ -mod ] [ -set name value | -unset name ]... [selection]\n");
65 log("Set/unset the given attributes on the selected objects. String values must be\n");
66 log("passed in double quotes (\").\n");
68 log("When called with -mod, this command will set and unset attributes on modules\n");
69 log("instead of objects within modules.\n");
72 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
74 std::vector
<setunset_t
> setunset_list
;
75 bool flag_mod
= false;
78 for (argidx
= 1; argidx
< args
.size(); argidx
++)
80 std::string arg
= args
[argidx
];
81 if (arg
== "-set" && argidx
+2 < args
.size()) {
82 string set_key
= args
[++argidx
];
83 string set_val
= args
[++argidx
];
84 setunset_list
.push_back(setunset_t(set_key
, set_val
));
87 if (arg
== "-unset" && argidx
+1 < args
.size()) {
88 setunset_list
.push_back(setunset_t(args
[++argidx
]));
97 extra_args(args
, argidx
, design
);
99 for (auto &mod
: design
->modules_
)
101 RTLIL::Module
*module
= mod
.second
;
104 if (design
->selected_whole_module(module
->name
))
105 do_setunset(module
->attributes
, setunset_list
);
109 if (!design
->selected(module
))
112 for (auto &it
: module
->wires_
)
113 if (design
->selected(module
, it
.second
))
114 do_setunset(it
.second
->attributes
, setunset_list
);
116 for (auto &it
: module
->memories
)
117 if (design
->selected(module
, it
.second
))
118 do_setunset(it
.second
->attributes
, setunset_list
);
120 for (auto &it
: module
->cells_
)
121 if (design
->selected(module
, it
.second
))
122 do_setunset(it
.second
->attributes
, setunset_list
);
124 for (auto &it
: module
->processes
)
125 if (design
->selected(module
, it
.second
))
126 do_setunset(it
.second
->attributes
, setunset_list
);
131 struct WbflipPass
: public Pass
{
132 WbflipPass() : Pass("wbflip", "flip the whitebox attribute") { }
133 void help() YS_OVERRIDE
135 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
137 log(" wbflip [selection]\n");
139 log("Flip the whitebox attribute on selected cells. I.e. if it's set, unset it, and\n");
140 log("vice-versa. Blackbox cells are not effected by this command.\n");
143 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
146 for (argidx
= 1; argidx
< args
.size(); argidx
++)
148 std::string arg
= args
[argidx
];
149 // if (arg == "-mod") {
155 extra_args(args
, argidx
, design
);
157 for (Module
*module
: design
->modules())
159 if (!design
->selected(module
))
162 if (module
->get_bool_attribute("\\blackbox"))
165 module
->set_bool_attribute("\\whitebox", !module
->get_bool_attribute("\\whitebox"));
170 struct SetparamPass
: public Pass
{
171 SetparamPass() : Pass("setparam", "set/unset parameters on objects") { }
172 void help() YS_OVERRIDE
174 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
176 log(" setparam [ -type cell_type ] [ -set name value | -unset name ]... [selection]\n");
178 log("Set/unset the given parameters on the selected cells. String values must be\n");
179 log("passed in double quotes (\").\n");
181 log("The -type option can be used to change the cell type of the selected cells.\n");
184 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
186 vector
<setunset_t
> setunset_list
;
187 string new_cell_type
;
190 for (argidx
= 1; argidx
< args
.size(); argidx
++)
192 std::string arg
= args
[argidx
];
193 if (arg
== "-set" && argidx
+2 < args
.size()) {
194 string set_key
= args
[++argidx
];
195 string set_val
= args
[++argidx
];
196 setunset_list
.push_back(setunset_t(set_key
, set_val
));
199 if (arg
== "-unset" && argidx
+1 < args
.size()) {
200 setunset_list
.push_back(setunset_t(args
[++argidx
]));
203 if (arg
== "-type" && argidx
+1 < args
.size()) {
204 new_cell_type
= RTLIL::escape_id(args
[++argidx
]);
209 extra_args(args
, argidx
, design
);
211 for (auto &mod
: design
->modules_
)
213 RTLIL::Module
*module
= mod
.second
;
215 if (!design
->selected(module
))
218 for (auto &it
: module
->cells_
)
219 if (design
->selected(module
, it
.second
)) {
220 if (!new_cell_type
.empty())
221 it
.second
->type
= new_cell_type
;
222 do_setunset(it
.second
->parameters
, setunset_list
);
228 struct ChparamPass
: public Pass
{
229 ChparamPass() : Pass("chparam", "re-evaluate modules with new parameters") { }
230 void help() YS_OVERRIDE
232 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
234 log(" chparam [ -set name value ]... [selection]\n");
236 log("Re-evaluate the selected modules with new parameters. String values must be\n");
237 log("passed in double quotes (\").\n");
240 log(" chparam -list [selection]\n");
242 log("List the available parameters of the selected modules.\n");
245 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
247 std::vector
<setunset_t
> setunset_list
;
248 dict
<RTLIL::IdString
, RTLIL::Const
> new_parameters
;
249 bool list_mode
= false;
252 for (argidx
= 1; argidx
< args
.size(); argidx
++)
254 std::string arg
= args
[argidx
];
255 if (arg
== "-set" && argidx
+2 < args
.size()) {
256 string set_key
= args
[++argidx
];
257 string set_val
= args
[++argidx
];
258 setunset_list
.push_back(setunset_t(set_key
, set_val
));
261 if (arg
== "-list") {
268 for (int i
= argidx
; i
< GetSize(args
); i
++)
269 if (design
->module("$abstract\\" + args
[i
]) != nullptr &&
270 design
->module(RTLIL::escape_id(args
[i
])) == nullptr)
271 args
[i
] = "$abstract\\" + args
[i
];
273 extra_args(args
, argidx
, design
);
275 do_setunset(new_parameters
, setunset_list
);
278 if (!new_parameters
.empty())
279 log_cmd_error("The options -set and -list cannot be used together.\n");
280 for (auto module
: design
->selected_modules()) {
281 log("%s:\n", log_id(module
));
282 for (auto param
: module
->avail_parameters
)
283 log(" %s\n", log_id(param
));
288 pool
<IdString
> modnames
, old_modnames
;
289 for (auto module
: design
->selected_whole_modules_warn()) {
290 modnames
.insert(module
->name
);
291 old_modnames
.insert(module
->name
);
295 for (auto modname
: modnames
) {
296 Module
*module
= design
->module(modname
);
297 Module
*new_module
= design
->module(module
->derive(design
, new_parameters
));
298 if (module
!= new_module
) {
299 Module
*m
= new_module
->clone();
300 m
->name
= module
->name
;
301 design
->remove(module
);
304 if (old_modnames
.count(new_module
->name
) == 0)
305 design
->remove(new_module
);
310 PRIVATE_NAMESPACE_END