VPIで乗算器を作成する Verilog

はじめに

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で乗算器を作成しました。

コメント

タイトルとURLをコピーしました