diff options
author | Clifford Wolf <clifford@clifford.at> | 2014-06-07 11:48:50 +0200 |
---|---|---|
committer | Clifford Wolf <clifford@clifford.at> | 2014-06-07 11:48:50 +0200 |
commit | e275e8eef9ae47670075bd73a671f3acd3c0ca52 (patch) | |
tree | 415c0b5d2de494ac0d72a92745d3a1c0cc703275 /passes | |
parent | 0b1ce63a19025f73fe4d2a54253134ea9a4de625 (diff) | |
download | yosys-e275e8eef9ae47670075bd73a671f3acd3c0ca52.tar.gz yosys-e275e8eef9ae47670075bd73a671f3acd3c0ca52.tar.bz2 yosys-e275e8eef9ae47670075bd73a671f3acd3c0ca52.zip |
Add support for cell arrays
Diffstat (limited to 'passes')
-rw-r--r-- | passes/hierarchy/hierarchy.cc | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 526d17294..6890cb9ea 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; } |