Verilog 시뮬레이터 "OSS CVC"의 DPI 기능을 사용해보십시오.

소개



지난번 소개한 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 로 정의되고 있습니다.
내용은 2개의 부호 없음 32bit int 형이다.


4값
bval
aval


0
0
0

1
0
1

z
1
0

x
1
1


덧붙여 시뮬레이터에 따라서는 aval bval 가 각각 aval bval

tb. sv



8bit끼리의 신호를 더해 산을 C언어로부터 호출해, 값을 표시합니다. C 언어 함수를 SystemVerilog에서 호출하려면 a에서 함수를 Verilog의 b로 취급합니다. import "DPI-C"function 하려면 functionimport 라는 두 가지 방법이 있지만 이 예제에서는 어느 쪽이든 상관 없습니다.

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

사실은 pure 를 사용하여 깨끗이 쓰고 싶었습니다만, 아무래도 OSS CVC는 context 미대응인 것 같습니다…

Makefile



시뮬레이션을 실행하려면 Makefile을 사용합니다. OSS CVC는 gcc로 C 코드를 컴파일하고 동적 링크 라이브러리를 생성하고 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에서 typedef + typedef 로 실행합니다.
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에서 적어도 ctrl에서 DPI 기능을 사용할 수 있음을 발견했습니다. 다음의 버전 업이 언제가 될지 모르겠지만, 그때까지 b 를 사용하는 것 같은 코드를 일으키면서 기다리고 싶습니다.

좋은 웹페이지 즐겨찾기