如何使用Yosys RTLIL API获取未连接的单元端口列表?

时间:2016-03-30 07:27:56

标签: yosys

对于更大的项目,我需要使用Yosys RTLIL API创建一个未连接的单元端口列表。这样做的最佳策略是什么?

1 个答案:

答案 0 :(得分:0)

普通的RTLIL API不提供任何索引。您可以确定连接到端口的网络,但不能确定连接到网络的端口。 Yosys中有强大的索引器可以帮助您,例如来自ModIndex的{​​{1}},但在大多数情况下,最简单的方法是为您需要的任何内容创建自定义索引。

在这种情况下,我们只需要一个字典<>计算连接到净位的单元数。我们在所有单元端口上进行两次传递。在第一遍中,我们计算每个信号位的连接数,在第二遍中,我们确定单元端口是否是连接到该位的唯一端口:

kernel/modtools.h

使用类似的方法,我们可以找到所有未驱动的单元端口:

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);
}

或所有未使用的单元端口:

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);
                                }
}