数字集成电路设计-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
",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




原文地址:https://www.cnblogs.com/wzjhoutai/p/6742464.html