aboutsummaryrefslogtreecommitdiffstats
path: root/passes/hierarchy/hierarchy.cc
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2017-01-01 22:52:52 +0100
committerClifford Wolf <clifford@clifford.at>2017-01-01 23:03:44 +0100
commitf0df7dd7961128824baa785a6f76462f36877e4d (patch)
tree4af8f5933e89d7f86c655085a1f662433bfe23d1 /passes/hierarchy/hierarchy.cc
parenta7fb64efe6013e41c2892bea649d96c98e434c8a (diff)
downloadyosys-f0df7dd7961128824baa785a6f76462f36877e4d.tar.gz
yosys-f0df7dd7961128824baa785a6f76462f36877e4d.tar.bz2
yosys-f0df7dd7961128824baa785a6f76462f36877e4d.zip
Added cell port resizing to hierarchy pass
Diffstat (limited to 'passes/hierarchy/hierarchy.cc')
-rw-r--r--passes/hierarchy/hierarchy.cc56
1 files changed, 56 insertions, 0 deletions
diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc
index 376df5698..337af7fd7 100644
--- a/passes/hierarchy/hierarchy.cc
+++ b/passes/hierarchy/hierarchy.cc
@@ -367,6 +367,11 @@ struct HierarchyPass : public Pass {
log(" per default this pass also converts positional arguments in cells\n");
log(" to arguments using port names. this option disables this behavior.\n");
log("\n");
+ log(" -keep_portwidths\n");
+ log(" per default this pass adjusts the port width on cells that are\n");
+ log(" module instances when the width does not match the module port. this\n");
+ log(" option disables this behavior.\n");
+ log("\n");
log(" -nokeep_asserts\n");
log(" per default this pass sets the \"keep\" attribute on all modules\n");
log(" that directly or indirectly contain one or more $assert cells. this\n");
@@ -412,6 +417,7 @@ struct HierarchyPass : public Pass {
bool auto_top_mode = false;
bool generate_mode = false;
bool keep_positionals = false;
+ bool keep_portwidths = false;
bool nokeep_asserts = false;
std::vector<std::string> generate_cells;
std::vector<generate_port_decl_t> generate_ports;
@@ -470,6 +476,10 @@ struct HierarchyPass : public Pass {
keep_positionals = true;
continue;
}
+ if (args[argidx] == "-keep_portwidths") {
+ keep_portwidths = true;
+ continue;
+ }
if (args[argidx] == "-nokeep_asserts") {
nokeep_asserts = true;
continue;
@@ -614,6 +624,52 @@ struct HierarchyPass : public Pass {
}
}
+ if (!keep_portwidths)
+ {
+ for (auto module : design->modules())
+ for (auto cell : module->cells())
+ {
+ Module *m = design->module(cell->type);
+
+ if (m == nullptr)
+ continue;
+
+ for (auto &conn : cell->connections())
+ {
+ Wire *w = m->wire(conn.first);
+
+ if (w == nullptr || w->port_id == 0)
+ continue;
+
+ if (GetSize(w) == GetSize(conn.second))
+ continue;
+
+ SigSpec sig = conn.second;
+
+ if (GetSize(w) < GetSize(conn.second))
+ {
+ int n = GetSize(conn.second) - GetSize(w);
+ if (!w->port_input && w->port_output)
+ module->connect(sig.extract(GetSize(w), n), Const(0, n));
+ sig.remove(GetSize(w), n);
+ }
+ else
+ {
+ int n = GetSize(w) - GetSize(conn.second);
+ if (w->port_input && !w->port_output)
+ sig.append(Const(0, n));
+ else
+ sig.append(module->addWire(NEW_ID, n));
+ }
+
+ if (!conn.second.is_fully_const() || !w->port_input || w->port_output)
+ log_warning("Resizing cell port %s.%s.%s from %d bits to %d bits.\n", log_id(module), log_id(cell),
+ log_id(conn.first), GetSize(conn.second), GetSize(sig));
+ cell->setPort(conn.first, sig);
+ }
+ }
+ }
+
log_pop();
}
} HierarchyPass;