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/yosys.h"
21 #include "kernel/sigtools.h"
24 PRIVATE_NAMESPACE_BEGIN
26 struct AttrmvcpPass
: public Pass
{
27 AttrmvcpPass() : Pass("attrmvcp", "move or copy attributes from wires to driving cells") { }
31 log(" attrmvcp [options] [selection]\n");
33 log("Move or copy attributes on wires to the cells driving them.\n");
36 log(" By default, attributes are moved. This will only add\n");
37 log(" the attribute to the cell, without removing it from\n");
41 log(" If no selected cell consumes the attribute, then it is\n");
42 log(" left on the wire by default. This option will cause the\n");
43 log(" attribute to be removed from the wire, even if no selected\n");
44 log(" cell takes it.\n");
47 log(" By default, attriburtes are moved to the cell driving the\n");
48 log(" wire. With this option set it will be moved to the cell\n");
49 log(" driven by the wire instead.\n");
51 log(" -attr <attrname>\n");
52 log(" Move or copy this attribute. This option can be used\n");
53 log(" multiple times.\n");
56 virtual void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
)
58 log_header(design
, "Executing ATTRMVCP pass (move or copy attributes).\n");
60 bool copy_mode
= false;
61 bool driven_mode
= false;
62 bool purge_mode
= false;
63 pool
<IdString
> attrnames
;
66 for (argidx
= 1; argidx
< args
.size(); argidx
++)
68 std::string arg
= args
[argidx
];
73 if (arg
== "-driven") {
77 if (arg
== "-purge") {
81 if (arg
== "-attr" && argidx
+1 < args
.size()) {
82 attrnames
.insert(RTLIL::escape_id(args
[++argidx
]));
87 extra_args(args
, argidx
, design
);
89 for (auto module
: design
->selected_modules())
91 dict
<SigBit
, pool
<Cell
*>> net2cells
;
92 SigMap
sigmap(module
);
94 for (auto cell
: module
->selected_cells())
95 for (auto &conn
: cell
->connections())
97 if (cell
->input(conn
.first
))
98 for (auto bit
: sigmap(conn
.second
))
99 net2cells
[bit
].insert(cell
);
101 if (cell
->output(conn
.first
))
102 for (auto bit
: sigmap(conn
.second
))
103 net2cells
[bit
].insert(cell
);
106 for (auto wire
: module
->selected_wires())
108 dict
<IdString
, Const
> new_attributes
;
110 for (auto attr
: wire
->attributes
)
112 bool did_something
= false;
114 if (!attrnames
.count(attr
.first
)) {
115 new_attributes
[attr
.first
] = attr
.second
;
119 for (auto bit
: sigmap(wire
))
120 if (net2cells
.count(bit
))
121 for (auto cell
: net2cells
.at(bit
)) {
122 log("Moving attribute %s=%s from %s.%s to %s.%s.\n", log_id(attr
.first
), log_const(attr
.second
),
123 log_id(module
), log_id(wire
), log_id(module
), log_id(cell
));
124 cell
->attributes
[attr
.first
] = attr
.second
;
125 did_something
= true;
128 if (!purge_mode
&& !did_something
)
129 new_attributes
[attr
.first
] = attr
.second
;
133 wire
->attributes
.swap(new_attributes
);
139 PRIVATE_NAMESPACE_END