vpi のテスト

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 もしっているのか、、、