@Vengineerの戯言 : Twitter SystemVerilogの世界へようこそ、すべては、SystemC v0.9公開から始まった
はじめに
巷では結構使われているという、cocotb を調べてみたら、Verilator が Verilog HDL Simulator として使えるようになっていた。 Verilatorの中を調べるシリーズにて、いろいろと調べたので、どのようにテストベンチ側がなっているのかをみてみたので、記録しておきます。
cocotb
サイトは、こちら。
Verilator の対応のコードは、こちら。
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 については、下記の書籍を読みましょう!。めっちゃ、分厚いですが。
おわりに
cocotb と Verilator がどのようになっているかを、さくって見てみました。 懐かしい Verilog HDL の VPI を使って、Python <=> C++/C <=> Verilator って感じで繋がっているということがわかりましたー。