From cca3cb5fbbe5ba127b620be5435697fb0ee66736 Mon Sep 17 00:00:00 2001 From: Andrew Zonenberg Date: Fri, 11 Aug 2017 13:40:37 -0700 Subject: Added opt_rmports pass (remove unconnected ports from top-level modules) --- passes/opt/Makefile.inc | 1 + passes/opt/opt_rmports.cc | 132 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 passes/opt/opt_rmports.cc (limited to 'passes') diff --git a/passes/opt/Makefile.inc b/passes/opt/Makefile.inc index a8b1537bb..7d54adf0f 100644 --- a/passes/opt/Makefile.inc +++ b/passes/opt/Makefile.inc @@ -6,6 +6,7 @@ OBJS += passes/opt/opt_reduce.o OBJS += passes/opt/opt_rmdff.o OBJS += passes/opt/opt_clean.o OBJS += passes/opt/opt_expr.o +OBJS += passes/opt/opt_rmports.o ifneq ($(SMALL),1) OBJS += passes/opt/share.o diff --git a/passes/opt/opt_rmports.cc b/passes/opt/opt_rmports.cc new file mode 100644 index 000000000..2fd73fff2 --- /dev/null +++ b/passes/opt/opt_rmports.cc @@ -0,0 +1,132 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/register.h" +#include "kernel/sigtools.h" +#include "kernel/log.h" +#include +#include + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct OptRmportsPass : public Pass { + OptRmportsPass() : Pass("opt_rmports", "remove top-level ports with no connections") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" opt_rmports\n"); + log("\n"); + log("This pass identifies ports in the top-level design which are not used or driven\n"); + log("and removes them\n"); + log("\n"); + } + + virtual void execute(std::vector /*args*/, RTLIL::Design *design) + { + log_header(design, "Executing OPT_RMPORTS pass (remove top level ports with no connections).\n"); + + //vector mods = design->modules(); + //for(auto mod : mods) + // ProcessModule(mod); + ProcessModule(design->top_module()); + } + + virtual void ProcessModule(RTLIL::Module* module) + { + log("Finding unconnected ports in module %s\n", module->name.c_str()); + + std::set used_ports; + + //See what wires are used. + //Start by checking connections between named wires + auto& conns = module->connections(); + for(auto sigsig : conns) + { + auto s1 = sigsig.first.as_wire(); + auto s2 = sigsig.second.as_wire(); + + if( (s1->port_input || s1->port_output) && (used_ports.find(s1->name) == used_ports.end()) ) + used_ports.emplace(s1->name); + + if( (s2->port_input || s2->port_output) && (used_ports.find(s2->name) == used_ports.end()) ) + used_ports.emplace(s2->name); + } + + //Then check connections to cells + auto cells = module->cells(); + for(auto cell : cells) + { + auto& cconns = cell->connections(); + for(auto conn : cconns) + { + if(!conn.second.is_wire()) + continue; + auto sig = conn.second.as_wire(); + + if( (sig->port_input || sig->port_output) && (used_ports.find(sig->name) == used_ports.end()) ) + used_ports.emplace(sig->name); + } + } + + //Now that we know what IS used, get rid of anything that isn't in that list + std::set unused_ports; + for(auto port : module->ports) + { + if(used_ports.find(port) != used_ports.end()) + continue; + unused_ports.emplace(port); + } + + //Print the ports out as we go through them + for(auto port : unused_ports) + { + log(" removing unused top-level port %s\n", port.c_str()); + + //Remove from ports list + for(size_t i=0; iports.size(); i++) + { + if(module->ports[i] == port) + { + module->ports.erase(module->ports.begin() + i); + break; + } + } + + //Mark the wire as no longer a port + auto wire = module->wire(port); + wire->port_input = false; + wire->port_output = false; + wire->port_id = 0; + } + log("Removed %zu unused top-level ports.\n", unused_ports.size()); + + //Re-number all of the wires that DO have ports still on them + for(size_t i=0; iports.size(); i++) + { + auto port = module->ports[i]; + auto wire = module->wire(port); + wire->port_id = i+1; + } + } + +} OptRmportsPass; + +PRIVATE_NAMESPACE_END -- cgit v1.2.3 From 66aac06eeef177318f3a4ade150e20a21be7e7c7 Mon Sep 17 00:00:00 2001 From: Andrew Zonenberg Date: Fri, 11 Aug 2017 13:46:01 -0700 Subject: Removed commented out debug code --- passes/opt/opt_rmports.cc | 4 ---- 1 file changed, 4 deletions(-) (limited to 'passes') diff --git a/passes/opt/opt_rmports.cc b/passes/opt/opt_rmports.cc index 2fd73fff2..6c80e2b7c 100644 --- a/passes/opt/opt_rmports.cc +++ b/passes/opt/opt_rmports.cc @@ -42,10 +42,6 @@ struct OptRmportsPass : public Pass { virtual void execute(std::vector /*args*/, RTLIL::Design *design) { log_header(design, "Executing OPT_RMPORTS pass (remove top level ports with no connections).\n"); - - //vector mods = design->modules(); - //for(auto mod : mods) - // ProcessModule(mod); ProcessModule(design->top_module()); } -- cgit v1.2.3 From 3dd7f42e2b07c84178c648a0c3979c61fe25f68f Mon Sep 17 00:00:00 2001 From: Andrew Zonenberg Date: Fri, 11 Aug 2017 15:07:27 -0700 Subject: opt_rmports: Fixed incorrect handling of multi-bit nets --- passes/opt/opt_rmports.cc | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) (limited to 'passes') diff --git a/passes/opt/opt_rmports.cc b/passes/opt/opt_rmports.cc index 6c80e2b7c..afbbecf84 100644 --- a/passes/opt/opt_rmports.cc +++ b/passes/opt/opt_rmports.cc @@ -56,14 +56,28 @@ struct OptRmportsPass : public Pass { auto& conns = module->connections(); for(auto sigsig : conns) { - auto s1 = sigsig.first.as_wire(); - auto s2 = sigsig.second.as_wire(); + auto s1 = sigsig.first; + auto s2 = sigsig.second; - if( (s1->port_input || s1->port_output) && (used_ports.find(s1->name) == used_ports.end()) ) - used_ports.emplace(s1->name); + int len1 = s1.size(); + int len2 = s2.size(); + int len = len1; + if(len2 < len1) + len = len2; - if( (s2->port_input || s2->port_output) && (used_ports.find(s2->name) == used_ports.end()) ) - used_ports.emplace(s2->name); + for(int i=0; iname.c_str(), w2->name.c_str()); + + if( (w1->port_input || w1->port_output) && (used_ports.find(w1->name) == used_ports.end()) ) + used_ports.emplace(w1->name); + + if( (w2->port_input || w2->port_output) && (used_ports.find(w2->name) == used_ports.end()) ) + used_ports.emplace(w2->name); + } } //Then check connections to cells @@ -73,12 +87,13 @@ struct OptRmportsPass : public Pass { auto& cconns = cell->connections(); for(auto conn : cconns) { - if(!conn.second.is_wire()) - continue; - auto sig = conn.second.as_wire(); - - if( (sig->port_input || sig->port_output) && (used_ports.find(sig->name) == used_ports.end()) ) - used_ports.emplace(sig->name); + for(int i=0; iname.c_str()); + if( (sig->port_input || sig->port_output) && (used_ports.find(sig->name) == used_ports.end()) ) + used_ports.emplace(sig->name); + } } } -- cgit v1.2.3 From 2877d5e50449dd08ebcb183218d015008c9fffcb Mon Sep 17 00:00:00 2001 From: Andrew Zonenberg Date: Fri, 11 Aug 2017 16:16:25 -0700 Subject: Fixed handling of cell ports that aren't wires --- passes/opt/opt_rmports.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'passes') diff --git a/passes/opt/opt_rmports.cc b/passes/opt/opt_rmports.cc index afbbecf84..5522dfa8e 100644 --- a/passes/opt/opt_rmports.cc +++ b/passes/opt/opt_rmports.cc @@ -90,6 +90,9 @@ struct OptRmportsPass : public Pass { for(int i=0; iname.c_str()); if( (sig->port_input || sig->port_output) && (used_ports.find(sig->name) == used_ports.end()) ) used_ports.emplace(sig->name); -- cgit v1.2.3 From 1bb150c2318a16e8007b4cf76aa2a199f49f0f7e Mon Sep 17 00:00:00 2001 From: Andrew Zonenberg Date: Fri, 11 Aug 2017 16:47:07 -0700 Subject: Improved handling of constant connections in opt_rmports --- passes/opt/opt_rmports.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'passes') diff --git a/passes/opt/opt_rmports.cc b/passes/opt/opt_rmports.cc index 5522dfa8e..a7a2df866 100644 --- a/passes/opt/opt_rmports.cc +++ b/passes/opt/opt_rmports.cc @@ -69,6 +69,8 @@ struct OptRmportsPass : public Pass { { auto w1 = s1[i].wire; auto w2 = s2[i].wire; + if( (w1 == NULL) || (w2 == NULL) ) + continue; //log(" conn %s, %s\n", w1->name.c_str(), w2->name.c_str()); -- cgit v1.2.3 From 1a6a23f91a93414e0e43f0666d3b2af6295345a8 Mon Sep 17 00:00:00 2001 From: Andrew Zonenberg Date: Mon, 14 Aug 2017 11:00:18 -0700 Subject: Renamed opt_rmports pass to rmports --- passes/opt/opt_rmports.cc | 148 ---------------------------------------------- passes/opt/rmports.cc | 148 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+), 148 deletions(-) delete mode 100644 passes/opt/opt_rmports.cc create mode 100644 passes/opt/rmports.cc (limited to 'passes') diff --git a/passes/opt/opt_rmports.cc b/passes/opt/opt_rmports.cc deleted file mode 100644 index a7a2df866..000000000 --- a/passes/opt/opt_rmports.cc +++ /dev/null @@ -1,148 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Clifford Wolf - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#include "kernel/register.h" -#include "kernel/sigtools.h" -#include "kernel/log.h" -#include -#include - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -struct OptRmportsPass : public Pass { - OptRmportsPass() : Pass("opt_rmports", "remove top-level ports with no connections") { } - virtual void help() - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" opt_rmports\n"); - log("\n"); - log("This pass identifies ports in the top-level design which are not used or driven\n"); - log("and removes them\n"); - log("\n"); - } - - virtual void execute(std::vector /*args*/, RTLIL::Design *design) - { - log_header(design, "Executing OPT_RMPORTS pass (remove top level ports with no connections).\n"); - ProcessModule(design->top_module()); - } - - virtual void ProcessModule(RTLIL::Module* module) - { - log("Finding unconnected ports in module %s\n", module->name.c_str()); - - std::set used_ports; - - //See what wires are used. - //Start by checking connections between named wires - auto& conns = module->connections(); - for(auto sigsig : conns) - { - auto s1 = sigsig.first; - auto s2 = sigsig.second; - - int len1 = s1.size(); - int len2 = s2.size(); - int len = len1; - if(len2 < len1) - len = len2; - - for(int i=0; iname.c_str(), w2->name.c_str()); - - if( (w1->port_input || w1->port_output) && (used_ports.find(w1->name) == used_ports.end()) ) - used_ports.emplace(w1->name); - - if( (w2->port_input || w2->port_output) && (used_ports.find(w2->name) == used_ports.end()) ) - used_ports.emplace(w2->name); - } - } - - //Then check connections to cells - auto cells = module->cells(); - for(auto cell : cells) - { - auto& cconns = cell->connections(); - for(auto conn : cconns) - { - for(int i=0; iname.c_str()); - if( (sig->port_input || sig->port_output) && (used_ports.find(sig->name) == used_ports.end()) ) - used_ports.emplace(sig->name); - } - } - } - - //Now that we know what IS used, get rid of anything that isn't in that list - std::set unused_ports; - for(auto port : module->ports) - { - if(used_ports.find(port) != used_ports.end()) - continue; - unused_ports.emplace(port); - } - - //Print the ports out as we go through them - for(auto port : unused_ports) - { - log(" removing unused top-level port %s\n", port.c_str()); - - //Remove from ports list - for(size_t i=0; iports.size(); i++) - { - if(module->ports[i] == port) - { - module->ports.erase(module->ports.begin() + i); - break; - } - } - - //Mark the wire as no longer a port - auto wire = module->wire(port); - wire->port_input = false; - wire->port_output = false; - wire->port_id = 0; - } - log("Removed %zu unused top-level ports.\n", unused_ports.size()); - - //Re-number all of the wires that DO have ports still on them - for(size_t i=0; iports.size(); i++) - { - auto port = module->ports[i]; - auto wire = module->wire(port); - wire->port_id = i+1; - } - } - -} OptRmportsPass; - -PRIVATE_NAMESPACE_END diff --git a/passes/opt/rmports.cc b/passes/opt/rmports.cc new file mode 100644 index 000000000..30cf149ce --- /dev/null +++ b/passes/opt/rmports.cc @@ -0,0 +1,148 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/register.h" +#include "kernel/sigtools.h" +#include "kernel/log.h" +#include +#include + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct RmportsPassPass : public Pass { + RmportsPassPass() : Pass("rmports", "remove top-level ports with no connections") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" rmports\n"); + log("\n"); + log("This pass identifies ports in the top-level design which are not used or driven\n"); + log("and removes them\n"); + log("\n"); + } + + virtual void execute(std::vector /*args*/, RTLIL::Design *design) + { + log_header(design, "Executing RMPORTS pass (remove top level ports with no connections).\n"); + ProcessModule(design->top_module()); + } + + virtual void ProcessModule(RTLIL::Module* module) + { + log("Finding unconnected ports in module %s\n", module->name.c_str()); + + std::set used_ports; + + //See what wires are used. + //Start by checking connections between named wires + auto& conns = module->connections(); + for(auto sigsig : conns) + { + auto s1 = sigsig.first; + auto s2 = sigsig.second; + + int len1 = s1.size(); + int len2 = s2.size(); + int len = len1; + if(len2 < len1) + len = len2; + + for(int i=0; iname.c_str(), w2->name.c_str()); + + if( (w1->port_input || w1->port_output) && (used_ports.find(w1->name) == used_ports.end()) ) + used_ports.emplace(w1->name); + + if( (w2->port_input || w2->port_output) && (used_ports.find(w2->name) == used_ports.end()) ) + used_ports.emplace(w2->name); + } + } + + //Then check connections to cells + auto cells = module->cells(); + for(auto cell : cells) + { + auto& cconns = cell->connections(); + for(auto conn : cconns) + { + for(int i=0; iname.c_str()); + if( (sig->port_input || sig->port_output) && (used_ports.find(sig->name) == used_ports.end()) ) + used_ports.emplace(sig->name); + } + } + } + + //Now that we know what IS used, get rid of anything that isn't in that list + std::set unused_ports; + for(auto port : module->ports) + { + if(used_ports.find(port) != used_ports.end()) + continue; + unused_ports.emplace(port); + } + + //Print the ports out as we go through them + for(auto port : unused_ports) + { + log(" removing unused top-level port %s\n", port.c_str()); + + //Remove from ports list + for(size_t i=0; iports.size(); i++) + { + if(module->ports[i] == port) + { + module->ports.erase(module->ports.begin() + i); + break; + } + } + + //Mark the wire as no longer a port + auto wire = module->wire(port); + wire->port_input = false; + wire->port_output = false; + wire->port_id = 0; + } + log("Removed %zu unused top-level ports.\n", unused_ports.size()); + + //Re-number all of the wires that DO have ports still on them + for(size_t i=0; iports.size(); i++) + { + auto port = module->ports[i]; + auto wire = module->wire(port); + wire->port_id = i+1; + } + } + +} RmportsPassPass; + +PRIVATE_NAMESPACE_END -- cgit v1.2.3 From d5e5bbad861975761c87a77388ce7add7bd1bdea Mon Sep 17 00:00:00 2001 From: Andrew Zonenberg Date: Mon, 14 Aug 2017 11:04:56 -0700 Subject: Updated Makefile to reflect opt_rmports being renamed to rmports --- passes/opt/Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'passes') diff --git a/passes/opt/Makefile.inc b/passes/opt/Makefile.inc index 7d54adf0f..a145cf946 100644 --- a/passes/opt/Makefile.inc +++ b/passes/opt/Makefile.inc @@ -6,7 +6,7 @@ OBJS += passes/opt/opt_reduce.o OBJS += passes/opt/opt_rmdff.o OBJS += passes/opt/opt_clean.o OBJS += passes/opt/opt_expr.o -OBJS += passes/opt/opt_rmports.o +OBJS += passes/opt/rmports.o ifneq ($(SMALL),1) OBJS += passes/opt/share.o -- cgit v1.2.3 From bd2ac68769ebddf8c239eeaf26d43d30453db583 Mon Sep 17 00:00:00 2001 From: Andrew Zonenberg Date: Mon, 14 Aug 2017 11:16:44 -0700 Subject: rmports now works on all modules in the design, not just the top. --- passes/opt/rmports.cc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'passes') diff --git a/passes/opt/rmports.cc b/passes/opt/rmports.cc index 30cf149ce..f08d7b126 100644 --- a/passes/opt/rmports.cc +++ b/passes/opt/rmports.cc @@ -27,7 +27,7 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN struct RmportsPassPass : public Pass { - RmportsPassPass() : Pass("rmports", "remove top-level ports with no connections") { } + RmportsPassPass() : Pass("rmports", "remove module ports with no connections") { } virtual void help() { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| @@ -42,7 +42,10 @@ struct RmportsPassPass : public Pass { virtual void execute(std::vector /*args*/, RTLIL::Design *design) { log_header(design, "Executing RMPORTS pass (remove top level ports with no connections).\n"); - ProcessModule(design->top_module()); + + auto modules = design->selected_modules(); + for(auto mod : modules) + ProcessModule(mod); } virtual void ProcessModule(RTLIL::Module* module) @@ -114,7 +117,7 @@ struct RmportsPassPass : public Pass { //Print the ports out as we go through them for(auto port : unused_ports) { - log(" removing unused top-level port %s\n", port.c_str()); + log(" removing unused port %s\n", port.c_str()); //Remove from ports list for(size_t i=0; iports.size(); i++) @@ -132,7 +135,7 @@ struct RmportsPassPass : public Pass { wire->port_output = false; wire->port_id = 0; } - log("Removed %zu unused top-level ports.\n", unused_ports.size()); + log("Removed %zu unused ports.\n", unused_ports.size()); //Re-number all of the wires that DO have ports still on them for(size_t i=0; iports.size(); i++) -- cgit v1.2.3 From 0ee27d0226dcafad798eefdd26480dde1c186e98 Mon Sep 17 00:00:00 2001 From: Andrew Zonenberg Date: Mon, 14 Aug 2017 11:18:09 -0700 Subject: ProcessModule is no longer virtual (why was it in the first place?) --- passes/opt/rmports.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'passes') diff --git a/passes/opt/rmports.cc b/passes/opt/rmports.cc index f08d7b126..39cef12e6 100644 --- a/passes/opt/rmports.cc +++ b/passes/opt/rmports.cc @@ -48,7 +48,7 @@ struct RmportsPassPass : public Pass { ProcessModule(mod); } - virtual void ProcessModule(RTLIL::Module* module) + void ProcessModule(RTLIL::Module* module) { log("Finding unconnected ports in module %s\n", module->name.c_str()); -- cgit v1.2.3 From 15e41d6363b9f3a71a2fe564c793296f8c1fba6d Mon Sep 17 00:00:00 2001 From: Andrew Zonenberg Date: Mon, 14 Aug 2017 11:44:05 -0700 Subject: rmports: Now remove ports from cell instances if we optimized them out of that cell --- passes/opt/rmports.cc | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) (limited to 'passes') diff --git a/passes/opt/rmports.cc b/passes/opt/rmports.cc index 39cef12e6..3aaa05c99 100644 --- a/passes/opt/rmports.cc +++ b/passes/opt/rmports.cc @@ -43,12 +43,44 @@ struct RmportsPassPass : public Pass { { log_header(design, "Executing RMPORTS pass (remove top level ports with no connections).\n"); + //The set of ports we removed + std::map< RTLIL::IdString, std::set > removed_ports; + + //Find all of the unused ports, and remove them from that module auto modules = design->selected_modules(); for(auto mod : modules) - ProcessModule(mod); + ScanModule(mod, removed_ports); + + //Remove the unused ports from all instances of those modules + for(auto mod : modules) + CleanupModule(mod, removed_ports); + } + + void CleanupModule(RTLIL::Module* module, std::map< RTLIL::IdString, std::set >& removed_ports) + { + log("Removing now-unused cell ports in module %s\n", module->name.c_str()); + + auto cells = module->cells(); + for(auto cell : cells) + { + if(removed_ports.find(cell->type) == removed_ports.end()) + { + //log(" Not touching instance \"%s\" because we didn't remove any ports from module \"%s\"\n", + // cell->name.c_str(), cell->type.c_str()); + continue; + } + + auto ports_to_remove = removed_ports[cell->type]; + for(auto p : ports_to_remove) + { + log(" Removing port \"%s\" from instance \"%s\"\n", + p.c_str(), cell->type.c_str()); + cell->unsetPort(p); + } + } } - void ProcessModule(RTLIL::Module* module) + void ScanModule(RTLIL::Module* module, std::map< RTLIL::IdString, std::set >& removed_ports) { log("Finding unconnected ports in module %s\n", module->name.c_str()); @@ -118,6 +150,7 @@ struct RmportsPassPass : public Pass { for(auto port : unused_ports) { log(" removing unused port %s\n", port.c_str()); + removed_ports[module->name].emplace(port); //Remove from ports list for(size_t i=0; iports.size(); i++) -- cgit v1.2.3