mirror of https://github.com/YosysHQ/yosys.git
hierarchy: Resolve SV wildcard port connections
Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
parent
50f86c11b2
commit
5df591c023
|
@ -1582,7 +1582,7 @@ cell_port:
|
|||
free_attr($1);
|
||||
} |
|
||||
attr TOK_AUTOCONNECT_ALL {
|
||||
astbuf2->attributes[ID(autoconnect)] = AstNode::mkconst_int(1, false);
|
||||
astbuf2->attributes[ID(implicit_port_conns)] = AstNode::mkconst_int(1, false);
|
||||
};
|
||||
|
||||
always_comb_or_latch:
|
||||
|
|
|
@ -548,6 +548,19 @@ RTLIL::Module *check_if_top_has_changed(Design *design, Module *top_mod)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// Find a matching wire for an implicit port connection; traversing generate block scope
|
||||
RTLIL::Wire *find_implicit_port_wire(Module *module, Cell *cell, const std::string& port)
|
||||
{
|
||||
const std::string &cellname = cell->name.str();
|
||||
size_t idx = cellname.size();
|
||||
while ((idx = cellname.find_last_of('.', idx-1)) != std::string::npos) {
|
||||
Wire *found = module->wire(cellname.substr(0, idx+1) + port.substr(1));
|
||||
if (found != nullptr)
|
||||
return found;
|
||||
}
|
||||
return module->wire(port);
|
||||
}
|
||||
|
||||
struct HierarchyPass : public Pass {
|
||||
HierarchyPass() : Pass("hierarchy", "check, expand and clean up design hierarchy") { }
|
||||
void help() YS_OVERRIDE
|
||||
|
@ -970,6 +983,55 @@ struct HierarchyPass : public Pass {
|
|||
}
|
||||
}
|
||||
|
||||
// Process SV implicit port connections
|
||||
std::set<Module*> blackbox_derivatives;
|
||||
std::vector<Module*> design_modules = design->modules();
|
||||
|
||||
for (auto module : design_modules)
|
||||
{
|
||||
for (auto cell : module->cells())
|
||||
{
|
||||
if (!cell->get_bool_attribute(ID(implicit_port_conns)))
|
||||
continue;
|
||||
Module *m = design->module(cell->type);
|
||||
|
||||
if (m == nullptr)
|
||||
log_error("Cell %s.%s (%s) has implicit port connections but the module it instantiates is unknown.\n",
|
||||
RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));
|
||||
|
||||
// Need accurate port widths for error checking; so must derive blackboxes with dynamic port widths
|
||||
if (m->get_blackbox_attribute() && !cell->parameters.empty() && m->get_bool_attribute("\\dynports")) {
|
||||
IdString new_m_name = m->derive(design, cell->parameters, true);
|
||||
if (new_m_name.empty())
|
||||
continue;
|
||||
if (new_m_name != m->name) {
|
||||
m = design->module(new_m_name);
|
||||
blackbox_derivatives.insert(m);
|
||||
}
|
||||
}
|
||||
|
||||
auto old_connections = cell->connections();
|
||||
for (auto wire : m->wires()) {
|
||||
// Find ports of the module that aren't explicitly connected
|
||||
if (!wire->port_input && !wire->port_output)
|
||||
continue;
|
||||
if (old_connections.count(wire->name))
|
||||
continue;
|
||||
// Make sure a wire of correct name exists in the parent
|
||||
Wire* parent_wire = find_implicit_port_wire(module, cell, wire->name.str());
|
||||
if (parent_wire == nullptr)
|
||||
log_error("No matching wire for implicit port connection `%s' of cell %s.%s (%s).\n",
|
||||
RTLIL::id2cstr(wire->name), RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));
|
||||
if (parent_wire->width != wire->width)
|
||||
log_error("Width mismatch between wire (%d bits) and port (%d bits) for implicit port connection `%s' of cell %s.%s (%s).\n",
|
||||
parent_wire->width, wire->width,
|
||||
RTLIL::id2cstr(wire->name), RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));
|
||||
cell->setPort(wire->name, parent_wire);
|
||||
}
|
||||
cell->attributes.erase(ID(implicit_port_conns));
|
||||
}
|
||||
}
|
||||
|
||||
if (!nodefaults)
|
||||
{
|
||||
dict<IdString, dict<IdString, Const>> defaults_db;
|
||||
|
@ -1000,9 +1062,6 @@ struct HierarchyPass : public Pass {
|
|||
}
|
||||
}
|
||||
|
||||
std::set<Module*> blackbox_derivatives;
|
||||
std::vector<Module*> design_modules = design->modules();
|
||||
|
||||
for (auto module : design_modules)
|
||||
{
|
||||
pool<Wire*> wand_wor_index;
|
||||
|
|
Loading…
Reference in New Issue