如何使用 Yosys RTLIL API 获取未连接单元端口的列表?
How do I get a list of unconnected cell ports using the Yosys RTLIL API?
对于较大的项目,我需要使用 Yosys RTLIL API 创建未连接的单元端口列表。这样做的最佳策略是什么?
普通 RTLIL API 不提供任何索引。您可以确定连接到端口的网络,但不能确定连接到网络的端口。 Yosys 中提供了强大的索引器,可以在此处为您提供帮助,例如 ModIndex
来自 kernel/modtools.h
,但在大多数情况下,最简单的方法是根据您的需要创建自定义索引。
在这种情况下,我们只需要一个 dict<> 来计算连接到网络位的单元数。我们对所有单元格端口进行两次传递。在第一遍中,我们计算每个信号位的连接数,在第二遍中,我们确定单元端口是否是连接到该位的唯一端口:
void find_unconn_cellports(Module *module)
{
SigMap sigmap(module);
dict<SigBit, int> sigbit_conncounts;
for (auto wire : module->wires()) {
if (wire->port_input)
for (auto bit : sigmap(wire))
sigbit_conncounts[bit]++;
if (wire->port_output)
for (auto bit : sigmap(wire))
sigbit_conncounts[bit]++;
}
for (auto cell : module->cells())
for (auto conn : cell->connections())
for (auto bit : conn.second)
sigbit_conncounts[sigmap(bit)]++;
for (auto cell : module->cells())
for (auto conn : cell->connections())
for (int i = 0; i < GetSize(conn.second); i++)
if (sigbit_conncounts.at(sigmap(conn.second[i])) == 1)
log("Unconnected cell port bit: %s.%s.%s[%d]\n",
log_id(module), log_id(cell), log_id(conn.first), i);
}
使用类似的方法,我们可以找到所有 undriven 单元端口:
void find_undriven_cellports(Module *module)
{
SigMap sigmap(module);
pool<SigBit> driven_sigbit;
for (auto wire : module->wires()) {
if (wire->port_input)
for (auto bit : sigmap(wire))
driven_sigbit.insert(bit);
}
for (auto cell : module->cells())
for (auto conn : cell->connections())
if (cell->output(conn.first))
for (auto bit : sigmap(conn.second))
driven_sigbit.insert(bit);
for (auto cell : module->cells())
for (auto conn : cell->connections())
if (cell->input(conn.first))
for (int i = 0; i < GetSize(conn.second); i++) {
auto bit = sigmap(conn.second[i]);
if (bit.wire && !driven_sigbit.count(bit))
log("Undriven cell port bit: %s.%s.%s[%d]\n",
log_id(module), log_id(cell), log_id(conn.first), i);
}
}
或所有未使用 单元格端口:
void find_unused_cellports(Module *module)
{
SigMap sigmap(module);
pool<SigBit> used_sigbit;
for (auto wire : module->wires()) {
if (wire->port_output)
for (auto bit : sigmap(wire))
used_sigbit.insert(bit);
}
for (auto cell : module->cells())
for (auto conn : cell->connections())
if (cell->input(conn.first))
for (auto bit : sigmap(conn.second))
used_sigbit.insert(bit);
for (auto cell : module->cells())
for (auto conn : cell->connections())
if (cell->output(conn.first))
for (int i = 0; i < GetSize(conn.second); i++)
if (used_sigbit.count(sigmap(conn.second[i])) == 0)
log("Unused cell port bit: %s.%s.%s[%d]\n",
log_id(module), log_id(cell), log_id(conn.first), i);
}
对于较大的项目,我需要使用 Yosys RTLIL API 创建未连接的单元端口列表。这样做的最佳策略是什么?
普通 RTLIL API 不提供任何索引。您可以确定连接到端口的网络,但不能确定连接到网络的端口。 Yosys 中提供了强大的索引器,可以在此处为您提供帮助,例如 ModIndex
来自 kernel/modtools.h
,但在大多数情况下,最简单的方法是根据您的需要创建自定义索引。
在这种情况下,我们只需要一个 dict<> 来计算连接到网络位的单元数。我们对所有单元格端口进行两次传递。在第一遍中,我们计算每个信号位的连接数,在第二遍中,我们确定单元端口是否是连接到该位的唯一端口:
void find_unconn_cellports(Module *module)
{
SigMap sigmap(module);
dict<SigBit, int> sigbit_conncounts;
for (auto wire : module->wires()) {
if (wire->port_input)
for (auto bit : sigmap(wire))
sigbit_conncounts[bit]++;
if (wire->port_output)
for (auto bit : sigmap(wire))
sigbit_conncounts[bit]++;
}
for (auto cell : module->cells())
for (auto conn : cell->connections())
for (auto bit : conn.second)
sigbit_conncounts[sigmap(bit)]++;
for (auto cell : module->cells())
for (auto conn : cell->connections())
for (int i = 0; i < GetSize(conn.second); i++)
if (sigbit_conncounts.at(sigmap(conn.second[i])) == 1)
log("Unconnected cell port bit: %s.%s.%s[%d]\n",
log_id(module), log_id(cell), log_id(conn.first), i);
}
使用类似的方法,我们可以找到所有 undriven 单元端口:
void find_undriven_cellports(Module *module)
{
SigMap sigmap(module);
pool<SigBit> driven_sigbit;
for (auto wire : module->wires()) {
if (wire->port_input)
for (auto bit : sigmap(wire))
driven_sigbit.insert(bit);
}
for (auto cell : module->cells())
for (auto conn : cell->connections())
if (cell->output(conn.first))
for (auto bit : sigmap(conn.second))
driven_sigbit.insert(bit);
for (auto cell : module->cells())
for (auto conn : cell->connections())
if (cell->input(conn.first))
for (int i = 0; i < GetSize(conn.second); i++) {
auto bit = sigmap(conn.second[i]);
if (bit.wire && !driven_sigbit.count(bit))
log("Undriven cell port bit: %s.%s.%s[%d]\n",
log_id(module), log_id(cell), log_id(conn.first), i);
}
}
或所有未使用 单元格端口:
void find_unused_cellports(Module *module)
{
SigMap sigmap(module);
pool<SigBit> used_sigbit;
for (auto wire : module->wires()) {
if (wire->port_output)
for (auto bit : sigmap(wire))
used_sigbit.insert(bit);
}
for (auto cell : module->cells())
for (auto conn : cell->connections())
if (cell->input(conn.first))
for (auto bit : sigmap(conn.second))
used_sigbit.insert(bit);
for (auto cell : module->cells())
for (auto conn : cell->connections())
if (cell->output(conn.first))
for (int i = 0; i < GetSize(conn.second); i++)
if (used_sigbit.count(sigmap(conn.second[i])) == 0)
log("Unused cell port bit: %s.%s.%s[%d]\n",
log_id(module), log_id(cell), log_id(conn.first), i);
}