電気回路/HDL/Verilator で DPI-C の履歴(No.1)
更新DPI-C とは†
SystemVerilog の機能で、SystemVerilog で書かれたテストベンチから C あるいは C++ で書かれたルーチンを呼び出したり、その呼び出された C あるいは C++ で書かれたルーチンから SystemVerilog の task や function を呼び出したりするための規格です。
ModelSim XE を使ってやってみた結果は 電気回路/HDL/ModelSim XE を使った SystemVerilog DPI-C テスト にあります。
今回はこれをフリーのツールである Verilator でやろうという話。
関連記事†
SystemVerilog のソース†
dpic-test.sv
LANG:verilog(linenumber)
`timescale 1ns / 1ps
// トップモジュール
module hello_top;
// verilog で書いた task
task verilog_task(input int i, output int o);
$display("Hello from verilog_task(%d)", i);
o = 2 * i;
endtask
// C から使うためにエクスポートする
export "<strong class="word0">DPI-C</strong>" task verilog_task;
// C で書かれた関数をインポートする
import "<strong class="word0">DPI-C</strong>" context task c_task(input int i, output int o);
// C で書かれた関数を呼び出す
int ret;
initial begin
c_task(1, ret); // c_task は verilog_task を呼び出す
$display("ret = %d", ret);
end
endmodule
C++ モードでやってみる†
LANG:console $ ls dpic-test.sv $ verilator dpic-test.sv $ ls dpic_test.sv obj_dir/ $ ls obj_dir/ Vdpic_test.cpp Vdpic_test__Dpi.cpp Vdpic_test__Syms.h Vdpic_test_classes.mk Vdpic_test.h Vdpic_test__Dpi.h Vdpic_test__ver.d Vdpic_test.mk Vdpic_test__Syms.cpp Vdpic_test__verFiles.dat $ less Vdpic_test.h
としてみた結果は以下の通り。
obj_dir/Vdpic_test.h
LANG:cpp(linenumber)
// Verilated -*- C++ -*-
// DESCRIPTION: Verilator output: Primary design header
//
// This header should be included by all source files instantiating the design.
// The class here is then constructed to instantiate the design.
// See the Verilator manual for examples.
#ifndef _Vdpic_test_H_
#define _Vdpic_test_H_
#include "verilated.h"
class Vdpic_test__Syms;
//----------
VL_MODULE(Vdpic_test) {
public:
// CELLS
// Public to allow access to /*verilator_public*/ items;
// otherwise the application code can consider these internals.
// PORTS
// The application code writes and reads these signals to
// propagate new values into/out from the Verilated model.
// LOCAL SIGNALS
// Internals; generally not touched by application code
VL_SIG(v__DOT__ret,31,0);
// LOCAL VARIABLES
// Internals; generally not touched by application code
// INTERNAL VARIABLES
// Internals; generally not touched by application code
Vdpic_test__Syms* __VlSymsp; // Symbol table
// PARAMETERS
// Parameters marked /*verilator public*/ for use by application code
// CONSTRUCTORS
private:
Vdpic_test& operator= (const Vdpic_test&); ///< Copying not allowed
Vdpic_test(const Vdpic_test&); ///< Copying not allowed
public:
/// Construct the model; called by application code
/// The special name may be used to make a wrapper with a
/// single model invisible WRT DPI scope names.
Vdpic_test(const char* name="TOP");
/// Destroy the model; called (often implicitly) by application code
~Vdpic_test();
// USER METHODS
// API METHODS
/// Evaluate the model. Application must call when inputs change.
void eval();
/// Simulation complete, run final blocks. Application must call on completion.
void final();
// INTERNAL METHODS
private:
static void _eval_initial_loop(Vdpic_test__Syms* __restrict vlSymsp);
public:
void __Vconfigure(Vdpic_test__Syms* symsp, bool first);
static void __Vdpiexp_v__DOT__verilog_task_TOP(Vdpic_test__Syms* __restrict vlSymsp, IData i, IData& o);
void __Vdpiimwrap_v__DOT__c_task_TOP(const VerilatedScope* __Vscopep, const char* __Vfilenamep, IData __Vlineno, IData i, IData& o);
private:
static IData _change_request(Vdpic_test__Syms* __restrict vlSymsp);
public:
static void _eval(Vdpic_test__Syms* __restrict vlSymsp);
static void _eval_initial(Vdpic_test__Syms* __restrict vlSymsp);
static void _eval_settle(Vdpic_test__Syms* __restrict vlSymsp);
static void _initial__TOP(Vdpic_test__Syms* __restrict vlSymsp);
static void verilog_task(int i, int* o);
} VL_ATTR_ALIGNED(64);
#endif /*guard*/
Counter: 18740 (from 2010/06/03),
today: 2,
yesterday: 5