Vengineerの戯言

人生は短いけど、長いです。人生を楽しみましょう!

PythonベースのVerilog HDL/VHDLのテストベンチ環境の cocotb と Verilator

@Vengineerの戯言 : Twitter SystemVerilogの世界へようこそすべては、SystemC v0.9公開から始まった 

はじめに

巷では結構使われているという、cocotb を調べてみたら、Verilator が Verilog HDL Simulator として使えるようになっていた。 Verilatorの中を調べるシリーズにて、いろいろと調べたので、どのようにテストベンチ側がなっているのかをみてみたので、記録しておきます。

cocotb

サイトは、こちら。

github.com

Verilator の対応のコードは、こちら。

github.com

while (!Verilated::gotFinish()) ループのところは、ここ。top->eval() と top->final() はあるけど、それ以外は、なになに Callback 関連。これ、何かというと、Verilog HDLの VPI (Verilog Procedural Interface)を使った Callback の仕組みなんですよ。Verilog HDLには、VPIの他に、PLI ( Programming. Language Interface ) というのもありますが、cocotb では VPI を使っています。cocotb は VHDL もサポートしているので、VHPI というのもサポートしています。ModelSim (旧Mentor)のVHDLは VHPIではなくFLIになっています。

    while (!Verilated::gotFinish()) {
        // Call registered timed callbacks (e.g. clock timer)
        // These are called at the beginning of the time step
        // before the iterative regions (IEEE 1800-2012 4.4.1)
        VerilatedVpi::callTimedCbs();

        // Call Value Change callbacks triggered by Timer callbacks
        // These can modify signal values
        settle_value_callbacks();

        // We must evaluate whole design until we process all 'events'
        bool again = true;
        while (again) {
            // Evaluate design
            top->eval();

            // Call Value Change callbacks triggered by eval()
            // These can modify signal values
            again = settle_value_callbacks();

            // Call registered ReadWrite callbacks
            again |= VerilatedVpi::callCbs(cbReadWriteSynch);

            // Call Value Change callbacks triggered by ReadWrite callbacks
            // These can modify signal values
            again |= settle_value_callbacks();
        }

        // Call ReadOnly callbacks
        VerilatedVpi::callCbs(cbReadOnlySynch);

#if VM_TRACE
        tfp->dump(main_time);
#endif
        // cocotb controls the clock inputs using cbAfterDelay so
        // skip ahead to the next registered callback
        vluint64_t next_time = VerilatedVpi::cbNextDeadline();

        // If there are no more cbAfterDelay callbacks,
        // the next deadline is max value, so end the simulation now
        if (next_time == static_cast<vluint64_t>(~0ULL)) {
            vl_finish(__FILE__, __LINE__, "");
            break;
        } else {
            main_time = next_time;
        }

        // Call registered NextSimTime
        // It should be called in simulation cycle before everything else
        // but not on first cycle
        VerilatedVpi::callCbs(cbNextSimTime);

        // Call Value Change callbacks triggered by NextTimeStep callbacks
        // These can modify signal values
        settle_value_callbacks();
    }

    VerilatedVpi::callCbs(cbEndOfSimulation);

    top->final();

SystemVerilogでDPI-Cにて、export task が利用できるようになって、PLIやVPIを使わなくなりましたが、昔は、PLI/VPI/VHPI/FLI を使ってモデルを開発したですよ。 Verilog HDL の PLI/VPI については、下記の書籍を読みましょう!。めっちゃ、分厚いですが。

www.springer.com

おわりに

cocotb と Verilator がどのようになっているかを、さくって見てみました。 懐かしい Verilog HDL の VPI を使って、Python <=> C++/C <=> Verilator って感じで繋がっているということがわかりましたー。