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
27 static void rename_in_module(RTLIL::Module
*module
, std::string from_name
, std::string to_name
, bool flag_output
)
29 from_name
= RTLIL::escape_id(from_name
);
30 to_name
= RTLIL::escape_id(to_name
);
32 if (module
->count_id(to_name
))
33 log_cmd_error("There is already an object `%s' in module `%s'.\n", to_name
.c_str(), module
->name
.c_str());
35 for (auto &it
: module
->wires_
)
36 if (it
.first
== from_name
) {
38 log("Renaming wire %s to %s in module %s.\n", log_id(w
), log_id(to_name
), log_id(module
));
39 module
->rename(w
, to_name
);
40 if (w
->port_id
|| flag_output
) {
42 w
->port_output
= true;
43 module
->fixup_ports();
48 for (auto &it
: module
->cells_
)
49 if (it
.first
== from_name
) {
51 log_cmd_error("Called with -output but the specified object is a cell.\n");
52 log("Renaming cell %s to %s in module %s.\n", log_id(it
.second
), log_id(to_name
), log_id(module
));
53 module
->rename(it
.second
, to_name
);
57 log_cmd_error("Object `%s' not found!\n", from_name
.c_str());
60 static std::string
derive_name_from_src(const std::string
&src
, int counter
)
62 std::string src_base
= src
.substr(0, src
.find('|'));
64 return stringf("$%d", counter
);
66 return stringf("\\%s$%d", src_base
.c_str(), counter
);
69 static IdString
derive_name_from_wire(const RTLIL::Cell
&cell
)
72 const SigSpec
*output
= nullptr;
74 for (auto &connection
: cell
.connections()) {
75 if (cell
.output(connection
.first
)) {
76 output
= &connection
.second
;
81 if (num_outputs
!= 1) // Skip cells thad drive multiple outputs
84 std::string name
= "";
85 for (auto &chunk
: output
->chunks()) {
86 // Skip cells that drive privately named wires
87 if (!chunk
.wire
|| chunk
.wire
->name
.str()[0] == '$')
93 name
+= chunk
.wire
->name
.str();
94 if (chunk
.wire
->width
!= chunk
.width
) {
97 name
+= std::to_string(chunk
.offset
+ chunk
.width
) + ":";
98 name
+= std::to_string(chunk
.offset
) + "]";
102 return name
+ cell
.type
.str();
105 struct RenamePass
: public Pass
{
106 RenamePass() : Pass("rename", "rename object in the design") { }
107 void help() YS_OVERRIDE
109 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
111 log(" rename old_name new_name\n");
113 log("Rename the specified object. Note that selection patterns are not supported\n");
114 log("by this command.\n");
118 log(" rename -output old_name new_name\n");
120 log("Like above, but also make the wire an output. This will fail if the object is\n");
121 log("not a wire.\n");
124 log(" rename -src [selection]\n");
126 log("Assign names auto-generated from the src attribute to all selected wires and\n");
127 log("cells with private names.\n");
130 log(" rename -wire [selection]\n");
132 log("Assign auto-generated names based on the wires they drive to all selected\n");
133 log("cells with private names. Ignores cells driving privatly named wires.\n");
136 log(" rename -enumerate [-pattern <pattern>] [selection]\n");
138 log("Assign short auto-generated names to all selected wires and cells with private\n");
139 log("names. The -pattern option can be used to set the pattern for the new names.\n");
140 log("The character %% in the pattern is replaced with a integer number. The default\n");
141 log("pattern is '_%%_'.\n");
144 log(" rename -hide [selection]\n");
146 log("Assign private names (the ones with $-prefix) to all selected wires and cells\n");
147 log("with public names. This ignores all selected ports.\n");
150 log(" rename -top new_name\n");
152 log("Rename top module.\n");
155 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
157 std::string pattern_prefix
= "_", pattern_suffix
= "_";
158 bool flag_src
= false;
159 bool flag_wire
= false;
160 bool flag_enumerate
= false;
161 bool flag_hide
= false;
162 bool flag_top
= false;
163 bool flag_output
= false;
164 bool got_mode
= false;
167 for (argidx
= 1; argidx
< args
.size(); argidx
++)
169 std::string arg
= args
[argidx
];
170 if (arg
== "-src" && !got_mode
) {
175 if (arg
== "-output" && !got_mode
) {
180 if (arg
== "-wire" && !got_mode
) {
185 if (arg
== "-enumerate" && !got_mode
) {
186 flag_enumerate
= true;
190 if (arg
== "-hide" && !got_mode
) {
195 if (arg
== "-top" && !got_mode
) {
200 if (arg
== "-pattern" && argidx
+1 < args
.size() && args
[argidx
+1].find('%') != std::string::npos
) {
201 int pos
= args
[++argidx
].find('%');
202 pattern_prefix
= args
[argidx
].substr(0, pos
);
203 pattern_suffix
= args
[argidx
].substr(pos
+1);
211 extra_args(args
, argidx
, design
);
213 for (auto &mod
: design
->modules_
)
217 RTLIL::Module
*module
= mod
.second
;
218 if (!design
->selected(module
))
221 dict
<RTLIL::IdString
, RTLIL::Wire
*> new_wires
;
222 for (auto &it
: module
->wires_
) {
223 if (it
.first
[0] == '$' && design
->selected(module
, it
.second
))
224 it
.second
->name
= derive_name_from_src(it
.second
->get_src_attribute(), counter
++);
225 new_wires
[it
.second
->name
] = it
.second
;
227 module
->wires_
.swap(new_wires
);
228 module
->fixup_ports();
230 dict
<RTLIL::IdString
, RTLIL::Cell
*> new_cells
;
231 for (auto &it
: module
->cells_
) {
232 if (it
.first
[0] == '$' && design
->selected(module
, it
.second
))
233 it
.second
->name
= derive_name_from_src(it
.second
->get_src_attribute(), counter
++);
234 new_cells
[it
.second
->name
] = it
.second
;
236 module
->cells_
.swap(new_cells
);
242 extra_args(args
, argidx
, design
);
244 for (auto &mod
: design
->modules_
)
246 RTLIL::Module
*module
= mod
.second
;
247 if (!design
->selected(module
))
250 dict
<RTLIL::IdString
, RTLIL::Cell
*> new_cells
;
251 for (auto &it
: module
->cells_
) {
252 if (it
.first
[0] == '$' && design
->selected(module
, it
.second
))
253 it
.second
->name
= derive_name_from_wire(*it
.second
);
254 new_cells
[it
.second
->name
] = it
.second
;
256 module
->cells_
.swap(new_cells
);
262 extra_args(args
, argidx
, design
);
264 for (auto &mod
: design
->modules_
)
268 RTLIL::Module
*module
= mod
.second
;
269 if (!design
->selected(module
))
272 dict
<RTLIL::IdString
, RTLIL::Wire
*> new_wires
;
273 for (auto &it
: module
->wires_
) {
274 if (it
.first
[0] == '$' && design
->selected(module
, it
.second
))
275 do it
.second
->name
= stringf("\\%s%d%s", pattern_prefix
.c_str(), counter
++, pattern_suffix
.c_str());
276 while (module
->count_id(it
.second
->name
) > 0);
277 new_wires
[it
.second
->name
] = it
.second
;
279 module
->wires_
.swap(new_wires
);
280 module
->fixup_ports();
282 dict
<RTLIL::IdString
, RTLIL::Cell
*> new_cells
;
283 for (auto &it
: module
->cells_
) {
284 if (it
.first
[0] == '$' && design
->selected(module
, it
.second
))
285 do it
.second
->name
= stringf("\\%s%d%s", pattern_prefix
.c_str(), counter
++, pattern_suffix
.c_str());
286 while (module
->count_id(it
.second
->name
) > 0);
287 new_cells
[it
.second
->name
] = it
.second
;
289 module
->cells_
.swap(new_cells
);
295 extra_args(args
, argidx
, design
);
297 for (auto &mod
: design
->modules_
)
299 RTLIL::Module
*module
= mod
.second
;
300 if (!design
->selected(module
))
303 dict
<RTLIL::IdString
, RTLIL::Wire
*> new_wires
;
304 for (auto &it
: module
->wires_
) {
305 if (design
->selected(module
, it
.second
))
306 if (it
.first
[0] == '\\' && it
.second
->port_id
== 0)
307 it
.second
->name
= NEW_ID
;
308 new_wires
[it
.second
->name
] = it
.second
;
310 module
->wires_
.swap(new_wires
);
311 module
->fixup_ports();
313 dict
<RTLIL::IdString
, RTLIL::Cell
*> new_cells
;
314 for (auto &it
: module
->cells_
) {
315 if (design
->selected(module
, it
.second
))
316 if (it
.first
[0] == '\\')
317 it
.second
->name
= NEW_ID
;
318 new_cells
[it
.second
->name
] = it
.second
;
320 module
->cells_
.swap(new_cells
);
326 if (argidx
+1 != args
.size())
327 log_cmd_error("Invalid number of arguments!\n");
329 IdString new_name
= RTLIL::escape_id(args
[argidx
]);
330 RTLIL::Module
*module
= design
->top_module();
333 log_cmd_error("No top module found!\n");
335 log("Renaming module %s to %s.\n", log_id(module
), log_id(new_name
));
336 design
->rename(module
, new_name
);
340 if (argidx
+2 != args
.size())
341 log_cmd_error("Invalid number of arguments!\n");
343 std::string from_name
= args
[argidx
++];
344 std::string to_name
= args
[argidx
++];
346 if (!design
->selected_active_module
.empty())
348 if (design
->modules_
.count(design
->selected_active_module
) > 0)
349 rename_in_module(design
->modules_
.at(design
->selected_active_module
), from_name
, to_name
, flag_output
);
354 log_cmd_error("Mode -output requires that there is an active module selected.\n");
355 for (auto &mod
: design
->modules_
) {
356 if (mod
.first
== from_name
|| RTLIL::unescape_id(mod
.first
) == from_name
) {
357 to_name
= RTLIL::escape_id(to_name
);
358 log("Renaming module %s to %s.\n", mod
.first
.c_str(), to_name
.c_str());
359 RTLIL::Module
*module
= mod
.second
;
360 design
->modules_
.erase(module
->name
);
361 module
->name
= to_name
;
362 design
->modules_
[module
->name
] = module
;
367 log_cmd_error("Object `%s' not found!\n", from_name
.c_str());
374 PRIVATE_NAMESPACE_END