summaryrefslogtreecommitdiff
path: root/passes/hierarchy
diff options
context:
space:
mode:
Diffstat (limited to 'passes/hierarchy')
-rw-r--r--passes/hierarchy/hierarchy.cc34
1 files changed, 34 insertions, 0 deletions
diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc
index 526d1729..6890cb9e 100644
--- a/passes/hierarchy/hierarchy.cc
+++ b/passes/hierarchy/hierarchy.cc
@@ -137,12 +137,23 @@ static void generate(RTLIL::Design *design, const std::vector<std::string> &cell
static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check, std::vector<std::string> &libdirs)
{
bool did_something = false;
+ std::map<RTLIL::Cell*, std::pair<int, int>> array_cells;
std::string filename;
for (auto &cell_it : module->cells)
{
RTLIL::Cell *cell = cell_it.second;
+ if (cell->type.substr(0, 7) == "$array:") {
+ int pos_idx = cell->type.find_first_of(':');
+ int pos_num = cell->type.find_first_of(':', pos_idx + 1);
+ int pos_type = cell->type.find_first_of(':', pos_num + 1);
+ int idx = atoi(cell->type.substr(pos_idx + 1, pos_num).c_str());
+ int num = atoi(cell->type.substr(pos_num + 1, pos_type).c_str());
+ array_cells[cell] = std::pair<int, int>(idx, num);
+ cell->type = cell->type.substr(pos_type + 1);
+ }
+
if (design->modules.count(cell->type) == 0)
{
if (design->modules.count("$abstract" + cell->type))
@@ -198,6 +209,29 @@ static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool fla
did_something = true;
}
+ for (auto &it : array_cells)
+ {
+ RTLIL::Cell *cell = it.first;
+ int idx = it.second.first, num = it.second.second;
+
+ if (design->modules.count(cell->type) == 0)
+ log_error("Array cell `%s.%s' of unkown type `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));
+
+ RTLIL::Module *mod = design->modules[cell->type];
+
+ for (auto &conn : cell->connections) {
+ int conn_size = conn.second.width;
+ if (mod->wires.count(conn.first) == 0)
+ log_error("Array cell `%s.%s' connects to unkown port `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(conn.first));
+ int port_size = mod->wires.at(conn.first)->width;
+ if (conn_size == port_size)
+ continue;
+ if (conn_size != port_size*num)
+ log_error("Array cell `%s.%s' has invalid port vs. signal size for port `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(conn.first));
+ conn.second = conn.second.extract(port_size*idx, port_size);
+ }
+ }
+
return did_something;
}