c/c++ reference model可以是on-line或者是off-line类型,on-line类型在rtl运行时输出spec item,off-line类型是在rtl运行完成之后将rtl输出结果和spec结果进行对比。
c/c++ ref model的on-line类型可以使用DPI-C方式实现:
一、使用import function 不消耗仿真时间:
1. 在c/c++文件中声明并实现函数:
#include <stdint.h>
#include <stdio.h>
#include "svdpi.h"
void add(svBitVec32* o_sum,
svBitVec32* o_overflow,
const svBitVec32 *a,
const svBitVec32 *b,
const svBitVec32 *c){
uint64_t sum;
uint64_t ta,tb,tc;
ta = a[0];
tb = b[0];
tc = c[0];
sum = ta+tb+tc;
o_sum[0] = sum;
if(sum>0xffffffff){
o_overflow[0]=1;
}
else {
o_overflow[0]=0;
}
#ifdef DEBUG_C
dpi_print("a",a[0]); // dpi_print:exported from sv code
dpi_print("b",b[0]);
dpi_print("c",c[0]);
dpi_print("sum",sum);
#endif
}
该示例中,在C函数中并没有声明变量输入输出方向, 但是,输入方向的参数最好添加const修饰符。参数类型选择svBitVec32,是因为sv中使用bit[31:0]数据。
对于input 参数,以下三种类型的变量类型直接使用 值传递 方式:
byte, shortint, int, longint,real,shortreal,
chandle,string
packed bit 小于32
2.在ref_model.sv中(或者在package中)导入该函数:
import "DPI-C" context function add(output bit [31:0] o_sum,output bit [31:0] o_overflow,input bit [32-1:0] i_a,input bit [32-1:0] i_b,input bit [32-1:0] i_c);
在以上import语句中,使用了context 关键字和function关键字,在函数变量列表中指明了IO的方向。
context function/task | 当c code需要使用sv中的export 函数或PLI、VPI。 function/task的消耗仿真、嵌套属性跟systemverilog一样。 |
---|---|
pure function | function没有result需要保留或者输出result固定时可以使用pure修饰。 function不能包含output、inout,且为非void。 function中不能执行文件操作;不能读写IO、环境变量、process/program中的其他变量、shared mem、socket等;不能访问持久化变量,如全局变量、静态变量等。 |
3.使用export关键字,导出c/c++需要调用的sv函数:
在sv文件中export需要c调用的函数:
export "DPI-C" function dpi_print ;
4,.声明export的函数原型:
function dpi_print(input string message,input longint data);
$display({message," 'h%16h"},data);
endfunction