数字集成电路设计-14-DPI
引言
在进行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,验证结果
10,小结
相对于VCS,Ncsim对DPI的支持略微弱一点。可是从上面的实验能够看出。主要的功能都是支持的,上面的实验尽管简单,但已经包括了实际项目中的大部分情况。
enjoy!
11,參考文献
Ncsim安装路径下的dpiEnrNbk.pdf及其演示样例代码,
我已上传:
http://download.csdn.net/detail/rill_zhen/7990949