0

Yosys で特定のモジュールのシーケンシャルな深さと複雑さを計算する新しいパスを実装しようとしています。そのために、scc pass に触発されています。これを実装するには、モジュールの入力ポートから始まる DFS を具体的に実行する必要があります。そのために、入力ポートに直接接続されているすべてのセルを見つけようとしています。モジュールのポートから始めて、関連するワイヤを見つけます。

SigPool inputPorts;
for (auto &it : module->ports) 
  if (module->wires_[it]->port_input)  
     inputPorts.add((sigmap(RTLIL::SigSpec(module->wires_[it]))));

しかし、私が抱えている問題は、そこから入力ポートに直接接続されているセルを見つけることができないことです (wires/sigspec/sigpool タイプには、その目的のための APR はありません)。

どんな助け/ヒントも大歓迎です。

4

2 に答える 2

1

次のコード例 (DFS ではありませんが) には、必要なすべての関連する慣用的な Yosys コード スニペットが含まれているはずです。

    // create canonical versions of all sigbits
    SigMap sigmap(module);

    // first layer of bits
    pool<SigBit> input_bits;

    for (auto wire : module->wires())
        if (wire->port_input)
            for (auto bit : sigmap(wire))
                input_bits.insert(bit);

    // index: from sigbit to driven cells
    dict<SigBit, pool<Cell*>> bit2cells;

    // index: from cell to driven sigbits
    dict<Cell*, pool<SigBit>> cell2bits;

    for (auto cell : module->cells())
    for (auto &conn : cell->connections()) {
        if (cell->input(conn.first)) {
            for (auto bit : sigmap(conn.second))
                bit2cells[bit].insert(cell);
        }
        if (cell->output(conn.first)) {
            for (auto bit : sigmap(conn.second))
                cell2bits[cell].insert(bit);
        }
    }

    pool<SigBit> queue = input_bits;
    pool<Cell*> visited_cells;

    while (!queue.empty())
    {
        log("------\n");

        pool<Cell*> this_iter_cells;

        for (auto bit : queue)
        for (auto cell : bit2cells[bit])
            if (!visited_cells.count(cell)) {
                log("  %s\n", log_id(cell));
                visited_cells.insert(cell);
                this_iter_cells.insert(cell);
            }

        queue.clear();
        for (auto cell : this_iter_cells)
        for (auto bit : cell2bits[cell])
            queue.insert(bit);
    }

それから取り除くべき最も重要なこと:

  • 信号ビットの正規表現を作成するために使用SigMapします (2 つのワイヤが互いに接続されていて、同じ実際のビットの単なる「エイリアス名」である場合)。

  • (1) 必要なインデックス構造を作成し、(2) 実際のアルゴリズムを実行します。

thisおよびthis questionへの回答も役立つ場合があります。

(私は急いでこの回答を書いています。不明な点がある場合は、以下のコメントでさらに質問してください。)

于 2016-05-21T11:51:05.527 に答える
1

その部分を次のように実装できましたが、それは機能しますが、それが最善の方法であるかどうかはわかりません。アドバイス/コメントをいただければ幸いです。

// for all input the cells of the module find its incoming signals (inputSignals in this code), and for each bit of them do the following:
for (auto &bit : inputSignals)
  if (bit.wire != NULL) {
    if (inputPortsSet.count(bit.wire->port_id)) {
      log ("found an input port\n");
      log ("%s :",cell->name.c_str());
      log(" %s ", bit.wire->name.c_str());
      log(" %d \n", bit.wire->port_id);       
      break;
    }
  }
于 2016-05-20T22:04:26.477 に答える