VPIを使うと、自作のC関数をVerilog環境にtaskとして追加できます。Icarus VerilogにVPIでtaskを追加してシミュレーションを実行する手順は次の通りです。
- Cコードのコンパイル
- Verilogコードのコンパイル
- シミュレーション実行
1. Cコードのコンパイル
まず、自作のC関数を含んだCコードが必要です。この例では、$helloというtaskを記述したhello.cというCコードを作成しています。
#include <stdio.h> #include "vpi_user.h" PLI_INT32 hello(void) { vpi_printf("hello world!\n"); return(0); } void register_my_systfs(void) { p_vpi_systf_data systf_data_p; static s_vpi_systf_data systf_data_list[] = { { vpiSysTask, 0, "$hello", hello, NULL, NULL, NULL }, { 0, 0, NULL, NULL, NULL, NULL, NULL } }; systf_data_p = &(systf_data_list[0]); while (systf_data_p->type != 0) vpi_register_systf(systf_data_p++); } void (*vlog_startup_routines[]) () = { register_my_systfs, 0 };
Cコードはiverilog-vpiでコンパイルします。
$iverilog-vpi hello.c
hello.vpiというファイルが生成されます。
2. Verilogコードのコンパイル
$helloを呼び出すVerilogモジュールを作成します。この例では、hello.vというファイルにtopというモジュールを定義し、その中で$helloを呼び出しています。
module top; initial begin $hello; end endmodule
Verilogコードはiverilogでコンパイルします。
iverilog -o hello hello.v
helloというファイルが生成されます。
3. シミュレーション実行
vvpでシミュレーションを実行します。VPIを使う場合は、iverilogで生成されたhelloに追加して-mでVPIモジュールを指定します。
$ vvp -m ./hello.vpi hello hello world!
Icarus Verilogのインストール手順はこちら