FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

Verilatorの使い方(4. DPI-Cを使ったC/C++との連携)

Verilog-HDLを使った検証では、C/C++のモデルとVerilogのモデルを接続した協調検証が頻繁に行われる。Verilatorでも同様の機能が搭載されており、DPI-Cを使ったC/C++Verilogとの通信が実現可能だ。

f:id:msyksphinz:20200504211549p:plain

ここでは前回作成したcounter_4bit.svに対してDPI-Cを経由してCコードを接続してみる。例えば、カウンタがカウントアップするとC言語の関数を呼び出す。

  1. まず、接続するC言語の関数をimportで宣言する。ここではdpi_c_func()を宣言する。
// Function from C-code
import "DPI-C" context task dpi_c_func(input int in, output int out);

dpi_c_funcは関数名、input intC言語実装側にとってのinputで、output intC言語実装側にとってのoutput(つまりポインタ)となる。

int                   return_value;

always_ff @(posedge clk, negedge reset_n) begin
  if (!reset_n) begin
    cnt <= 4'h0;
  end else begin
    if (en) begin
      cnt <= cnt + 4'h1;
      /* verilator lint_off WIDTH */
      dpi_c_func (cnt, return_value);
      $display("return_value = %d", return_value);
    end
  end
end
endmodule // counter_4bit

上記のように、Verilogの関数のように呼び出すことができる。

  1. C++の実装側。ここではdpi_counter_4bit.cppを用意する。
#include <verilated.h>
#include "Vcounter_4bit.h"
#include "stdio.h"

extern "C" {
  int dpi_c_func (int i, int* o);
}

int dpi_c_func (int i, int* o)
{
  printf("Hello from dpi_c_func(%d)\n", i);

  *o = 100 + i;

  return(0);
}

実装についても特に言及すべきところは無いと思う。extern "C"によってC++のデマングルを禁止している。入力側を値渡しの引数として、出力側はポインタ渡しで記述する。

ビルド時にdpi_counter.cppを追加すればよい。

$ verilator --cc --exe  --trace-fst --trace-params --trace-structs --trace-underscore counter_4bit.v -exe tb_counter_4bit.cpp dpi_counter.cpp
$ make -C obj_dir -f Vcounter_4bit.mk

実行してみよう。

$ ./obj_dir/Vcounter_4bit
Hello from c_task(0)
return_value =         100
Hello from c_task(1)
return_value =         101
Hello from c_task(2)
return_value =         102
Hello from c_task(3)
return_value =         103
Hello from c_task(4)
return_value =         104
Hello from c_task(5)
return_value =         105
Hello from c_task(6)
return_value =         106
Hello from c_task(7)
return_value =         107
Final Counter Value = 8

正しく動作していることが確認できた。