From e275e8eef9ae47670075bd73a671f3acd3c0ca52 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 7 Jun 2014 11:48:50 +0200 Subject: Add support for cell arrays --- passes/hierarchy/hierarchy.cc | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'passes') 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 &cell static bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check, std::vector &libdirs) { bool did_something = false; + std::map> 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(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; } -- cgit v1.2.3