【DPI-C】C言語関数をSystemVerilogで生成したクロック同期で動かす

前回DPI-Cにて、SystemVerilog側のtaskをC言語の関数から呼び出すことができました。今回はこれを利用して、C言語関数をSystemVerilog側で生成したクロック同期で動作させます。

前回記事:【DPI-C】ModelSim AEでDPI-Cの実行テスト

今回確認すること

C言語側のforループをSystemVerilogのクロック立ち上がり同期で動作させられること。

クロックは10ns。標準出力へは以下の順番で出力されることが期待されます。

    SV側 5 ns
    C側 10ns
    C側 20ns
    SV側 25ns
    C側 30ns

ソースコード

svファイル

`timescale 1ns / 1ps
        
    module sv_test_top;
    
        // export
        // クロックの立ち上がりまで待つ
        export "DPI-C" task wait_clock;
        // import
        // 1clock待ってからprintfを3ループするC関数
        import "DPI-C" context task c_for_wait_clock();
    
        // クロック生成
        logic clk_i = 0;
        always #5ns clk_i <= ~clk_i; 
    
        // 1 clock wait
        task wait_clock();
            @(posedge clk_i);
        endtask
    
        // 指定ns遅延後、標準出力
        task automatic wait_ns (time t);
            #t;
            $display("sv task: t=%t", t);
        endtask
    
        // C で書かれた関数を呼び出す
        initial begin
            fork
                c_for_wait_clock();
                wait_ns(5);
                wait_ns(25);
            join
        end
    
    endmodule

cファイル

#include "svdpi.h"      // DPI-C用ヘッダ
#include "dpiheader.h"  // SystemVerilogで定義されたタスクが定義される
#include <stdio.h>

// SystemVerilog側でクロックの立ち上がりを検出したらprintf
int c_for_wait_clock()
{
    int i = 0;

    for (i = 0; i < 3; i++) {
        wait_clock();
        printf("c function: i=%d, %dns\n", i, (i+1)*10);
    }

    return 0;
}

doファイル

前回から実行時間だけ変更しています。

vlib work
vlog -dpiheader dpiheader.h test.sv
vlog test.sv test.c
vsim -batch work.sv_test_top -do "run 1us"

シミュレーション結果

想定される順番で処理が実行されました。

dpi-c modelsim import

今回はクロック同期で動かしてみましたが、要するにSystemVerilog側の信号変化に応じてC言語関数を動かすことができるということなので、出来ることがかなり広がりそうですね。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする