##はじめに
前回紹介した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」ごく普通の足し算です。結果を標準出力に出します。キャリーとか特に考慮していません。
#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
型であるaval
とbval
メンバとする構造体で、以下のような対応で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
するにはpure
とcontext
という二通りの方法がありますが、この例ではどちらでも構いません。
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コードをコンパイルします。
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
##おわりに
OSS CVCで少なくともimport
でDPI機能が使えることがわかりました。次のバージョンアップがいつになるかわかりませんが、それまで、export
を使うようなコードを起こしつつ待ちたいと思います。