引言
在进行IC验证时,尤其是规模较大的时候,单纯用Verilog和SV来构建testbench,可能会稍显吃力。
在这种情况下,使用C或者C++等软件语言往往会大大加快验证速度,提高验证效率。
PLI,VPI,DPI正是基于这个原因开发的,很多仿真器都会提供支持。
之前,我们介绍过VPI的使用,本小结就来说一下更易使用的DPI。
1,基本功能
还是惯例,通过一个具体的实验来体会DPI的使用。
环境:IUS820(Ncsim)。
我们将使用C语言来分别实现一个加法器和一个乘法器。
其中加法器以task的形式实现,乘法器以function的形式实现。
需要注意的是,在实际的项目开发中,我们一般不建议在verilog或SV中直接调用用C语言实现的函数或者task,建议加一个verilog或者SV的wrapper,做一个隔离,利于维护和更新。
2,testbench
/*
* tb.v
* dpi test
* Rill
* 2014-09-28
*/
module tb;
reg clk;
reg rst_n;
reg enable;
reg [7:0] a;
reg [7:0] b;
wire [31:0] sum;
reg [7:0] c;
reg [7:0] d;
reg [31:0] mul_cd;
`include "mul.v"
add add0
(
.clk (clk),
.rst_n (rst_n),
.enable (enable),
.a (a),
.b (b),
.sum (sum)
);
always #1 clk = ~clk;
integer loop;
initial
begin
clk = 0;
rst_n = 0;
enable = 0;
repeat(10) @(posedge clk);
rst_n = 1;
repeat(10) @(posedge clk);
enable = 1;
for (loop=0;loop<10;loop=loop+1)
begin
@(posedge clk);
a = loop;
b = loop+1;
end
repeat(3) @(posedge clk);
@(posedge clk);
c = 2;
d = 2;
mul_cd = mul_dpi(c,d);
$display("%dx%d=%d",c,d,mul_cd);
$finish;
end
endmodule
3,add.v
/*
* add.v
* dpi test (wraper)
* Rill
* 2014-09-28
*/
module add
(
input clk,
input rst_n,
input enable,
input [7:0] a,
input [7:0] b,
output [31:0] sum
);
import "DPI-C" task add_dpi(
input int a,
input int b,
output int sum
);
reg [31:0] sum_r;
assign sum = sum_r;
always @(posedge clk)
begin
if(~rst_n)
sum_r <= 32'b0;
else if(enable)
add_dpi(a,b,sum_r);
end
endmodule
4,add_dpi.c
/*
* add_dpi.c
* dpi test
* Rill
* 2014-09-28
*/
#include <stdio.h>
int add_dpi(int a,int b,int* sum)
{
*sum = a + b;
printf("C_code: %d+%d=%d\n",a,b,*sum);
return 0;
}
5,mul.v
/*
* mul.v
* dpi test (wraper)
* Rill
* 2014-09-28
*/
import "DPI-C" function int mul_dpi(
input int c,
input int d
);
function [31:0] mul;
input [7:0] c;
input [7:0] d;
mul=mul_dpi(c,d);
endfunction //
6,mul_dpi.c
/*
* mul_dpi.c
* dpi test
* Rill
* 2014-09-28
*/
#include <stdio.h>
int mul_dpi(int c,int d)
{
return (c * d);
}
7,脚本
#! /bin/bash
#
# dpi.sh
# usage: ./dpi.sh c/w/r
# Rill create 2014-09-03
#
TOP_MODULE=tb
tcl_file=run.tcl
CDS_INST_DIR=/home/openrisc/opt/edatools/IUS08.20
if [ $# != 1 ];then
echo "args must be c/w/r"
exit 0
fi
if [ $1 == "c" ]; then
echo "compile lib..."
ncvlog -f ./vflist -sv -update -LINEDEBUG;
ncelab -delay_mode zero -access +rwc -timescale 1ns/10ps ${TOP_MODULE}
echo "compile DPI lib..."
gcc -fPIC -shared -o libdpi.so add_dpi.c mul_dpi.c -I$CDS_INST_DIR/tools/inca/include
exit 0
fi
if [ -e ${tcl_file} ];then
rm ${tcl_file} -f
fi
touch ${tcl_file}
if [ $1 == "w" ];then
echo "open wave..."
echo "database -open waves -into waves.shm -default;" >> ${tcl_file}
echo "probe -shm -variable -all -depth all;" >> ${tcl_file}
echo "run" >> ${tcl_file}
echo "exit" >> ${tcl_file}
fi
if [ $1 == "w" -o $1 == "r" ];then
echo "sim start..."
ncsim ${TOP_MODULE} -input ${tcl_file}
fi
echo "$(date) sim done!"
8,vflist
//vflist
tb.v
add.v
9,验证结果
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiNwkzN0gjMxITOykDM0EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
10,小结
相对于VCS,Ncsim对DPI的支持稍微弱一点,但是从上面的实验可以看出,基本的功能都是支持的,上面的实验虽然简单,但已经包含了实际项目中的大部分情况。
enjoy!
11,参考文献
Ncsim安装路径下的dpiEnrNbk.pdf及其示例代码,
我已上传:
http://download.csdn.net/detail/rill_zhen/7990949