LoginSignup
2
2

More than 5 years have passed since last update.

Verilogシミュレーター「OSS CVC」のDPI機能を試す。

Last updated at Posted at 2015-02-15

はじめに

前回紹介したVerilogシミュレーター「OSS CVC」の機能を一つであるDPIを簡単に試してみたいと思います。

DPIって?

SystemVerilogの機能で、SystemVerilog側からC言語の関数をコールしたり(import)、またその逆も出来ます(export)。
例えば、importを使用してC言語のリファレンスモデルと比較したり、exportを使用して、ソフトウェアからハードウェアにアクセスするような開発が可能となります。
今回は、importのごく簡単な記述でOSS CVCを使い、SystemVerilog側からC言語関数を呼び出してみました。

環境

こんな感じです。

├── Makefile
├── src
│   └── tb.c
└── tb
    └── tb.sv

編集と実行は、SublimeTextを使用しました。

tb.c

「C_add」ごく普通の足し算です。結果を標準出力に出します。キャリーとか特に考慮していません。

tb.c
#include <stdio.h>
#include "svdpi.h"

void C_add(
  const svLogicVecVal* a,
  const svLogicVecVal* b,
  svLogicVecVal* c
  ) {

  c->aval = a->aval + b->aval;
  c->bval = 0;

  printf("[C] %1d\n", c->aval);

}

svLogicVecValはVerilogの4値をCの2値で扱うための型で、svdpi.hで定義されています。
中身は二つの符号無し32bit int型であるavalbvalメンバとする構造体で、以下のような対応でVerilogの4値を表現します。

4値 bval aval
0 0 0
1 0 1
z 1 0
x 1 1

なお、シミュレータによってはaval bvalがそれぞれa bと省略されている場合がありますので注意下さい。

tb.sv

8bit同士の信号を足し算をC言語から呼び出し、値を表示します。C言語関数をSystemVerilogから呼び出すには、import "DPI-C"で関数をVerilogのfunctionとして扱います。functionとしてimportするにはpurecontextという二通りの方法がありますが、この例ではどちらでも構いません。

tb.sv
module tb();

  localparam logic [7:0] LP_A = 8'd1;
  localparam logic [7:0] LP_B = 8'd2;

  logic [7:0] x, y, z;

  import "DPI-C" pure function void C_add(
    input  logic [7:0] a, b,
    output logic [7:0] c
  );

  function void print (input logic [7:0] n);
    $display("[V] %1d", n);
  endfunction

  task set_value(output logic [7:0] a, b);
    a = LP_A;
    b = LP_B;
  endtask

  initial begin
    z = '0;
    set_value(x, y);
    C_add(x, y ,z);
    print(z);
    $finish(1);
  end

endmodule

本当は、typedefを使用してスッキリ書きたかったのですが、どうもOSS CVCはtypedef未対応のようです…。

Makefile

シミュレーション実行にはMakefileを今回は使用します。OSS CVCはCコードをgccでコンパイルしてダイナミックリンクライブラリ作成し、OSS CVCはそのライブラリを参照してSystemVerilogコードをコンパイルします。

Makefile
WARNS  = -Wall

INCS   = -I /usr/local/tachyon/open-src-cvc.700c/pli_incs
CPATH  = ./src
VPATH  = ./tb

CFLAGS = -fPIC -Wall -g $(INCS)
LFLAGS = -G -shared

CC      = gcc
CVC     = cvc64
OBJ     = simv

run : cvc

tb.o: $(CPATH)/tb.c
    $(CC) $(CFLAGS) -c $(CPATH)/tb.c

tb.so: tb.o
    $(LD) $(LFLAGS) tb.o -o tb.so

cvc: tb.so
    ${CVC} -q -sv -sv_lib tb.so ${VPATH}/tb.sv -o $(OBJ)

run: cvc
    ./$(OBJ)

clean:
    rm -rf *.o *.so *.log simv

Sublime Text上でビルドする環境を作成します。

{
  "shell_cmd": "make"
}

実行結果

Sublime Textからctrl+ bで実行します。

gcc -fPIC -Wall -g -I /usr/tools/tachyon/open-src-cvc.700c/pli_incs -c ./src/tb.c
ld -G -shared tb.o -o tb.so
cvc64 -q -sv -sv_lib tb.so ./tb/tb.sv -o simv
Copyright (c) 1991-2014 Tachyon Design Automation Corp.
  All Rights reserved.  Licensed software subject to prohibitions and
  restrictions.  See OSS CVC artistic license included with release.
./simv
Copyright (c) 1991-2014 Tachyon Design Automation Corp.
  All Rights reserved.  Licensed software subject to prohibitions and
  restrictions.  See OSS CVC artistic license included with release.
[C] 3
[V] 3

スナップショット的にはこんな感じです。exe.png

おわりに

OSS CVCで少なくともimportでDPI機能が使えることがわかりました。次のバージョンアップがいつになるかわかりませんが、それまで、exportを使うようなコードを起こしつつ待ちたいと思います。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2