iverilog で vpi をつかってみた。基本的には wiki にある通りにやっていけばよい。
http://iverilog.wikia.com/wiki/Main_Page
http://iverilog.wikia.com/wiki/Using_VPI
VPI の資料が少ないが、、、こんな感じで改造した。
static int hello_calltf(char *user_data) { vpiHandle systfref, argsiter, argh; struct t_vpi_value wrkval; systfref = vpi_handle(vpiSysTfCall, NULL); argsiter = vpi_iterate(vpiArgument, systfref); argh = vpi_scan(argsiter); wrkval.format = vpiIntVal; vpi_get_value(argh, &wrkval); vpi_printf("Hello, World! %s %d\n", user_data, wrkval.value.integer); argh = vpi_scan(argsiter); wrkval.format = vpiIntVal; vpi_get_value(argh, &wrkval); vpi_printf("Hello, World! %s %d\n", user_data, wrkval.value.integer); return 0; }
しかし、このハテナの記述は美しくないな、、、>>|c} と ||<< なんて覚えられん。あれちがっているのか?>> でなくて > だ一個多い。こういう風にどんどん言語を拡張しなくてはならないところが汚い。wiki もそう。wiki は便利だけど。
上のソースで2回vpi_scanをしているのはご愛嬌。コピー&ペーストしている悪いプログラムの例です。
呼び出し元は次のようにする。
module main; reg [31:0] R_INA; reg [31:0] R_INA2; reg [31:0] x; //integer x; initial $hello(1209, 1103); initial begin x = 111333; $hello(x, R_INA2); R_INA = $random; R_INA2 = R_INA + 1; $hello(x, R_INA2); R_INA2 = $random(x); $hello(R_INA, R_INA2); //x = 333; $hello(x, R_INA2); end endmodule
$randam は組み込みの関数。でついでに makefile
.SUFFIXES: .vvp run:hello.vvp hello_vpi.vpi vvp -M. -mhello_vpi hello.vvp hello_vpi.o:hello_vpi.c gcc -I/usr/local/include/iverilog -c -fpic hello_vpi.c hello_vpi.vpi:hello_vpi.o gcc -shared -ohello_vpi.vpi hello_vpi.o -lvpi hello.vvp:hello.v iverilog -ohello.vvp hello.v
make もしっているのか、、、