3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-08-14 01:46:40 +00:00

rtlil: resolve positional cell ports before giving up on a direction

Until `hierarchy` runs, a connection made by position is named `$<port_id>`
rather than after the port it reaches, so looking it up by name in the
instantiated module finds nothing and port_dir() reports PD_UNKNOWN. The
signorm index reads that as "not an input", which makes the cell claim a
driver on a net it only reads.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MQU5XCqDYY8MbivGkNRrDo
This commit is contained in:
Emil J. Tywoniak 2026-07-21 19:20:28 +02:00
parent f42923d896
commit 1b9b594f52

View file

@ -5213,13 +5213,32 @@ bool RTLIL::Cell::known() const
return false;
}
// Find the port a connection names in the module the cell instantiates. Until
// `hierarchy` runs, a connection made by position is named `$<port_id>` instead
// of after the port it reaches, and looking that up by name finds nothing --
// which would leave even a plain input port's direction unknown.
static RTLIL::Wire *find_port(RTLIL::Module *m, TwineRef portname)
{
if (m == nullptr)
return nullptr;
if (RTLIL::Wire *w = m->wire(portname))
return w;
std::string name = m->design->twines.str(portname);
if (name.size() < 2 || name[0] != '$' || name[1] < '0' || name[1] > '9')
return nullptr;
int port_id = atoi(name.c_str() + 1);
if (port_id < 1 || port_id > GetSize(m->ports))
return nullptr;
return m->wire(m->ports[port_id - 1]);
}
bool RTLIL::Cell::input(TwineRef portname) const
{
if (yosys_celltypes.cell_known(type_impl))
return yosys_celltypes.cell_input(type_impl, portname);
if (module && module->design) {
RTLIL::Module *m = module->design->module(type_impl);
RTLIL::Wire *w = m ? m->wire(portname) : nullptr;
RTLIL::Wire *w = find_port(module->design->module(type_impl), portname);
return w && w->port_input;
}
return false;
@ -5230,8 +5249,7 @@ bool RTLIL::Cell::output(TwineRef portname) const
if (yosys_celltypes.cell_known(type_impl))
return yosys_celltypes.cell_output(type_impl, portname);
if (module && module->design) {
RTLIL::Module *m = module->design->module(type_impl);
RTLIL::Wire *w = m ? m->wire(portname) : nullptr;
RTLIL::Wire *w = find_port(module->design->module(type_impl), portname);
return w && w->port_output;
}
return false;
@ -5242,10 +5260,7 @@ RTLIL::PortDir RTLIL::Cell::port_dir(TwineRef portname) const
if (yosys_celltypes.cell_known(type_impl))
return yosys_celltypes.cell_port_dir(type_impl, portname);
if (module && module->design) {
RTLIL::Module *m = module->design->module(type_impl);
if (m == nullptr)
return PortDir::PD_UNKNOWN;
RTLIL::Wire *w = m->wire(portname);
RTLIL::Wire *w = find_port(module->design->module(type_impl), portname);
if (w == nullptr)
return PortDir::PD_UNKNOWN;
return PortDir(w->port_input + w->port_output * 2);