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 DeminoutPass
: public Pass
{
27 DeminoutPass() : Pass("deminout", "demote inout ports to input or output") { }
31 log(" deminout [options] [selection]\n");
33 log("\"Demote\" inout ports to input or output ports, if possible.\n");
36 virtual void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
)
38 log_header(design
, "Executing DEMINOUT pass (demote inout ports to input or output).\n");
41 for (argidx
= 1; argidx
< args
.size(); argidx
++)
43 // if (args[argidx] == "-bits") {
49 extra_args(args
, argidx
, design
);
51 bool keep_running
= true;
57 for (auto module
: design
->selected_modules())
59 SigMap
sigmap(module
);
60 pool
<SigBit
> bits_written
, bits_used
, bits_inout
;
61 dict
<SigBit
, int> bits_numports
;
63 for (auto wire
: module
->wires())
65 for (auto bit
: sigmap(wire
))
68 for (auto cell
: module
->cells())
69 for (auto &conn
: cell
->connections())
71 bool cellport_out
= cell
->output(conn
.first
) || !cell
->known();
72 bool cellport_in
= cell
->input(conn
.first
) || !cell
->known();
74 if (cellport_out
&& cellport_in
)
75 for (auto bit
: sigmap(conn
.second
))
76 bits_inout
.insert(bit
);
79 for (auto bit
: sigmap(conn
.second
))
80 bits_written
.insert(bit
);
83 for (auto bit
: sigmap(conn
.second
))
84 bits_used
.insert(bit
);
87 for (auto wire
: module
->selected_wires())
88 if (wire
->port_input
&& wire
->port_output
)
90 bool new_input
= false;
91 bool new_output
= false;
93 for (auto bit
: sigmap(wire
))
95 if (bits_numports
[bit
] > 1 || bits_inout
.count(bit
))
96 new_input
= true, new_output
= true;
98 if (bits_written
.count(bit
))
100 else if (bits_used
.count(bit
))
104 if (new_input
!= new_output
) {
105 log("Demoting inout port %s.%s to %s.\n", log_id(module
), log_id(wire
), new_input
? "input" : "output");
106 wire
->port_input
= new_input
;
107 wire
->port_output
= new_output
;
116 PRIVATE_NAMESPACE_END