はじめに
VPIで2入力、1出力の乗算器を作成します。
環境はIcarus Verilogです。
作り方
乗算するCコードを作成します。
my_mult.cpp
#include "vpi_user.h"
// Task
int my_mult(char *userdata) {
vpiHandle systf_h, args_iter, arg_h; # VPIハンドル
s_vpi_value value; # Verilog側とデータのやり取りを行う変数
// おまじない
systf_h = vpi_handle(vpiSysTfCall, NULL);
args_iter = vpi_iterate(vpiArgument, systf_h);
// 第1引数を取得
arg_h = vpi_scan(args_iter);
value.format = vpiIntVal;
vpi_get_value(arg_h, &value);
int a = value.value.integer;
// 第2引数を取得
arg_h = vpi_scan(args_iter);
value.format = vpiIntVal;
vpi_get_value(arg_h, &value);
int b = value.value.integer;
// 第3引数に乗算結果を格納
arg_h = vpi_scan(args_iter);
value.value.integer = a * b;
value.format = vpiIntVal;
vpi_put_value(arg_h, &value, NULL, vpiNoDelay);
// メモリを解放する
vpi_free_object(args_iter);
vpi_free_object(arg_h);
return 0;
}
// SystemTaskを作成
void get_sum_register() {
s_vpi_systf_data task_data = {vpiSysTask, 0, "$my_mult", my_mult, 0, 0, 0};
vpi_register_systf(&task_data);
}
// 作成したSystemTaskをVerilogで使えるように登録
void (*vlog_startup_routines[])() = {
get_sum_register,
0
};
作成したC関数をVerilog側で使用します。
sample.sv
module sample;
reg [3:0] a, b, c;
initial begin
a = 3;
b = 4;
$my_mult(a, b, c);
$display("%d x %d = %d", a, b, c);
end
endmodule
コンパイルして実行してみます。
iverilog-vpi my_mult.cpp
iverilog -g2005-sv sample.sv
vvp -M. -mmy_mult a.out
# 出力
# 3 x 4 = 12
まとめ
vpiで乗算器を作成しました。
コメント