首页 > 代码库 > SV通过DPI调用C

SV通过DPI调用C

Verilog与C之间进行程序交互,PLI(Programming Language Interface)经过了TF,ACC,VPI等模式。

使用PLI可以生成延时计算器,来连接和同步多个仿真器,并可以通过波形显示等调试工具。

通过PLI方式连接一个简单的C程序,需要编写很多代码,并理解多仿真阶段的同步,调用段,实例指针等概念。

PLI方式给仿真带来了额外的负担,为了保护Verilog的数据结构,仿真器需要不断的在Verilog和C之间复制数据。

 

SystemVerilog引入了DPI(Direct Programming Interface),能够更简洁的连接C,C++或者其他非Verilog的编程语言。
只要使用import声明和使用,导入一个C子程序,就可以像调用SystemVerilog中的子程序一样来调用它。

 

SystemVerilog和C语言之间传递的最基本的数据类型是int,双状态的32位的数据类型,

 

import "DPI-C" function int factorial(input int i);

               program automatic test;     

                               initial  begin                

                                            for(int i=1;i<=10;i++)                

                                            $dispaly("%0d != %0d",i,factorial(i));             

                                         end

              endprogram

 

通过DPI传递的每个变量都有两个相匹配的定义,一个在SystemVerilog中,一个在C语言中。 在使用中必须,确认使用的是兼容的数据类型。

SystemVerilog                         C(输入)                         C(输出)

     byte                                    char                       char* shortint      

   short int                             short int                        short int*             

      int                                      int                                int*

    longint                             long long int                    long int*

      bit                            svBit/unsigned char       svBit*/unsigned char

   logic/reg                     svLogic/unsigned char   svLogic*/unsigned char*

    bit[N:0]                      const svBitVecVal*              svBitVecVal*

   reg[N:0]                      const svLogicVecVal*          svLogicVecVal*

  

通过import声明定义C任务和函数的原型,带有返回值的C函数被映射成一个systemverilog的函数(function),

void类型的C函数被映射为一个systemverilog的任务(task)或者void 函数(function)

如果C函数名和SystemVerilog中的命名冲突,可以在import导入时,赋予新的函数名。

  

   program automatic test;

           import "DPI-C" test=function void my_test();  //将C中的test函数,映射为function void的my_test名字。

                 intial  begin           

                              my_test();                       

                          end

 

在systemverilog中,凡是允许声明子程序的地方都可以导入,C子程序,

例如program,module,interface,package 或者编译单元空间$unit,被导入的子程序只在它被声明的空间中有效。

被导入的C子程序,可以有多个参数或者没有参数,缺省情况下,参数的方向是input(数据从SystemVerilog流向C函数)

参数的方向也可以定义为output和inout,ref类型目前不支持。

 

                import "DPI-C" function int addmul(input int a, b,                                   

                                                                  output int sum);

 

对输入的参数也可以被定义为const。这样一旦对输入的变量进行写操作,C编译器就会报错。

              int factorial (const int i) {}

 

连接C语言的例子。

#include <svdpi.h>

void counter7(svBitVecVal * o,

                     const svBitVecVal * i,

                     const svBit reset,

                     const svBit load)

{   static unsigned char count = 0;

     if(reset)   count = 0;

     else if(load)  count = * i;

     else count++;

     count &= 0x7F;

     *o = count;

}

reset和load是一个双状态的比特信号,以svBit类型进行传递。

输入i是双状态7bit 变量,用svBitVecVal类型传递。

头文件svdpi.h包含了SystemVerilog DPI结构和方法的定义。

测试平台:

import  “DPI-C” function void counter7(output bit [6:0] out,

                                                         input bit [6:0] in,

                                                         input bit reset, load);

 

program  automatic  counter;

    bit[6:0]  out, in;

    bit  reset, load;

    initial  begin

                   $monitor("SV: out=% 3d, in =%3d, reset = %0d, load = %0d\n", out,in,reset,load);

                    reset = 0;

                    load = 0;

                    in = 126;

                    out = 42;

                    counter7(out, in, reset, load);

              end

endprogram

 

chandle类型允许在System Verilog中存储一个C/C++的指针,

typedef struct{unsigned char cnt;} c7;

void *counter7_new() { c7* c=(c7*) malloc (sizeof(c7));

                                    c-> cnt = 0;

                                    return c;}

void counter7(c7* inst, ...)

测试平台:

import “DPI-C” function  chandle  counter7_new();

import "DPI-C" function void counter7(input chandle inst, ...)

 

使用关键字DPI-C表示,使用压缩值的方式来保存数据类型。

SV通过DPI调用C