diff options
Diffstat (limited to 'passes/techmap/deminout.cc')
-rw-r--r-- | passes/techmap/deminout.cc | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/passes/techmap/deminout.cc b/passes/techmap/deminout.cc index ed4e45762..b976b401b 100644 --- a/passes/techmap/deminout.cc +++ b/passes/techmap/deminout.cc @@ -25,7 +25,7 @@ PRIVATE_NAMESPACE_BEGIN struct DeminoutPass : public Pass { DeminoutPass() : Pass("deminout", "demote inout ports to input or output") { } - virtual void help() + void help() YS_OVERRIDE { log("\n"); log(" deminout [options] [selection]\n"); @@ -33,7 +33,7 @@ struct DeminoutPass : public Pass { log("\"Demote\" inout ports to input or output ports, if possible.\n"); log("\n"); } - virtual void execute(std::vector<std::string> args, RTLIL::Design *design) + void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE { log_header(design, "Executing DEMINOUT pass (demote inout ports to input or output).\n"); @@ -57,7 +57,7 @@ struct DeminoutPass : public Pass { for (auto module : design->selected_modules()) { SigMap sigmap(module); - pool<SigBit> bits_written, bits_used, bits_inout; + pool<SigBit> bits_written, bits_used, bits_inout, bits_tribuf; dict<SigBit, int> bits_numports; for (auto wire : module->wires()) @@ -82,6 +82,25 @@ struct DeminoutPass : public Pass { if (cellport_in) for (auto bit : sigmap(conn.second)) bits_used.insert(bit); + + if (conn.first == ID::Y && cell->type.in(ID($mux), ID($pmux), ID($_MUX_), ID($_TBUF_), ID($tribuf))) + { + bool tribuf = cell->type.in(ID($_TBUF_), ID($tribuf)); + + if (!tribuf) { + for (auto &c : cell->connections()) { + if (!c.first.in(ID::A, ID::B)) + continue; + for (auto b : sigmap(c.second)) + if (b == State::Sz) + tribuf = true; + } + } + + if (tribuf) + for (auto bit : sigmap(conn.second)) + bits_tribuf.insert(bit); + } } for (auto wire : module->selected_wires()) @@ -94,11 +113,17 @@ struct DeminoutPass : public Pass { { if (bits_numports[bit] > 1 || bits_inout.count(bit)) new_input = true, new_output = true; - - if (bits_written.count(bit)) + if (bit == State::S0 || bit == State::S1) + new_output = true; + if (bits_written.count(bit)) { new_output = true; - else if (bits_used.count(bit)) - new_input = true; + if (bits_tribuf.count(bit)) + goto tribuf_bit; + } else { + tribuf_bit: + if (bits_used.count(bit)) + new_input = true; + } } if (new_input != new_output) { |