FC2カウンター FPGAの部屋 Verilatorを試してみる9(DPI-C:SystemVerilogからCの関数を呼び出す)
FC2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

Verilatorを試してみる9(DPI-C:SystemVerilogからCの関数を呼び出す)

VerilatorでDPI-Cがうまくいかないとツイッターに書いたら、武内さんからVerilatorでDPI-Cが動いたよとツイッターで教えていただいた。ありがとうございます。いつもお世話になっております。
武内さんの”電気回路/HDL/Verilator で DPI-C”を参考にさせていただいて、やってみた。

私はVerilator ManualのDPI Sample記述をそのままにやっていた。下にそのDPI Sampleを引用する。
まずはVerilogサンプルから。

module test;
import "DPI-C" function integer add (input integer a, input integer b);

   initial begin
      $display("%x + %x = %x", 1, 2, add(1,2));
   end
endmodule


次にC++のサンプルを下に引用する。

    #include "svdpi.h"
    #include "Vour__Dpi.h"
    int add (int a, int b) { return a+b; }


これでコンパイルした。

verilator -cc our.v --exe sc_main.cpp


しかし、Inernal Errorになってしまった。
Verilator_26_110605.png

どうやら、$display("%x + %x = %x", 1, 2, add(1,2));で$displayの中にadd(1,2)を書くのがダメそうだ。そこで、int c;を定義して、$displayの前にadd()をコールしてみた。下に修正後のVerilogソースを示す。ついでに$finish;も追加した。

module test;
import "DPI-C" function integer add (input integer a, input integer b);

   int c;
   initial begin
      c = add(1, 2);
      $display("%x + %x = %x", 1, 2, c);
      $finish;
   end
endmodule


これでコンパイルしたら通った。次にobj_dirにcd して、makeを実行した。

make -j -f Vour.mk Vour


今度は ld がステータス1で終了してしまった。
Verilator_27_110605.png

電気回路/HDL/Verilator で DPI-C”をよく見ながら考えた。そうだC++にmain()が書いていない。。。おマヌケだった。。
他も修正した結果を下に示す。

#include <verilated.h> 
#include "Vour.h"
#include "svdpi.h"
#include "Vour__Dpi.h"

extern "C" int add (int a, int b) { return a+b; }

unsigned int main_time = 0;     // Current simulation time

double sc_time_stamp () {       // Called by $time in Verilog
    return main_time;
}

int main(int argc, char** argv) {
    Verilated::commandArgs(argc, argv);   // Remember args

    Vour *top = new Vour();   // Create instance

    while (!Verilated::gotFinish()) {

        top->eval();    // 評価

        main_time++;
    }

    top->final();        // シミュレーション終了
}


これで、コンパイル、makeして、実行ファイルができたので、実行した。
Verilator_28_110605.png

うまく行きました。良かった。。。

次に、Verilogでadd()をtask としてresultを出力として返すようにVerilogファイルを変更した。

module test;

import "DPI-C" task add (input int a, input int b, output int result);

   integer a, b, result;
   initial begin
      a = 1;
      b = 2;
      add(a, b, result);
      $display("%x + %x = %x", a, b, result);
      $finish;
   end
endmodule


C++の方も示す。

#include <verilated.h> 
#include "Vour2.h"
#include "Vour2__Dpi.h"

extern "C" int add (int a, int b, int *result) { 
    *result = a + b;
    return (0); 
}
    
unsigned int main_time = 0;     // Current simulation time

double sc_time_stamp () {       // Called by $time in Verilog
    return main_time;
}

int main(int argc, char** argv) {
    Verilated::commandArgs(argc, argv);   // Remember args

    Vour2 *top = new Vour2();   // Create instance

    while (!Verilated::gotFinish()) {

        top->eval();    // 評価

        main_time++;
    }

    top->final();        // シミュレーション終了
}


同様にコンパイル、make、実行したら、うまく行った。
Verilator_29_110605.png
  1. 2011年06月05日 07:59 |
  2. シミュレーション
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
https://marsee101.blog.fc2.com/tb.php/1819-781e08a9
この記事にトラックバックする(FC2ブログユーザー)