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:
parent
f42923d896
commit
1b9b594f52
1 changed files with 23 additions and 8 deletions
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue