How do I get a list of unconnected cell ports using the Yosys RTLIL API?

落爺英雄遲暮 提交于 2019-12-11 12:46:45

问题


For a larger project, I need to create a list of unconnected cell ports using the Yosys RTLIL API. What is the best strategy for doing so?


回答1:


The plain RTLIL API does not provide any indexes. You can determine the net connected to a port, but not the ports connected to a net. There are powerful indexers available in Yosys that can help you here, for example ModIndex from kernel/modtools.h, but in most cases it is simplest to create a custom index for whatever you need.

In this case we just need a dict<> that counts the number of cells connected to a net bit. We make two passes over all cell ports. In the first pass we count the number of connections for each signal bit, and in a second pass we determine if a cell port is the only port connected to that bit:

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

Using a similar approach we can find all undriven cell ports:

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

Or all unused cell ports:

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


来源:https://stackoverflow.com/questions/36302284/how-do-i-get-a-list-of-unconnected-cell-ports-using-the-yosys-rtlil-api

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!