|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
引言9 [! e! E6 T/ X. I6 j4 |8 t' u
1 f! j2 s) F% m; }9 D, ?4 K在进行IC验证时,尤其是规模较大的时候,单纯用Verilog和SV来构建testbench,可能会稍显吃力。
# a4 g0 V9 V5 N0 b' V. ?
2 G# h' f3 E5 @! O2 c1 }在这种情况下,使用C或者C++等软件语言往往会大大加快验证速度,提高验证效率。
% m. J/ R" j3 ?! c( A% ?7 {. \7 G) R+ l
PLI,VPI,DPI正是基于这个原因开发的,很多仿真器都会提供支持。" y, e( S' ?& e A9 L" k4 R
7 D9 k3 T6 _8 [2 w z x之前,我们介绍过VPI的使用,本小结就来说一下更易使用的DPI。4 r5 q5 d5 D, w- b- Q, R
: k, ~! L# K3 V* H) [1 o- k
1,基本功能4 K# Z9 }* O. W3 h
0 I, x: M1 r" I4 ]( z3 R还是惯例,通过一个具体的实验来体会DPI的使用。
9 L2 E+ _3 p* E8 P: _) z3 H; q
) V. A7 p5 x2 e; _9 L8 P9 k# `2 ?$ w环境:IUS820(Ncsim)。/ C4 v& A. s) m0 Q; n8 Z
, B" Y7 X/ L1 W
我们将使用C语言来分别实现一个加法器和一个乘法器。2 p/ A3 E0 ~/ [! n
! I) I8 F. _* T6 v A a- W
其中加法器以task的形式实现,乘法器以function的形式实现。% g5 N8 Z5 m* y W% @) I* s o
4 j) @3 V) h, r* ~
需要注意的是,在实际的项目开发中,我们一般不建议在verilog或SV中直接调用用C语言实现的函数或者task,建议加一个verilog或者SV的wrapper,做一个隔离,利于维护和更新。
' A2 E n$ H9 ~ H' u0 T# B
! G J2 T: Q g4 V9 ?6 z+ ~! O7 j p+ E7 r& D' {* g
2,testbench
0 w1 Y* r1 @7 N/ `- V; ?
9 z! {& F( Y, Q! X0 D6 K. H( B# I' [' G# W# t4 W
- /*
- * 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
- ' f8 z6 S) i9 b6 A. X) x, n
+ ]1 Q" l( A+ R6 t7 [# n* _5 @" m* m1 S6 x9 r' Q
y) s' i& e; p
3,add.v
3 z D4 v' V; ]& D d, n
5 J2 r4 o# p1 t9 m+ F, @- /*
- * 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
- : u3 v/ u7 q9 W( F: N% ~1 S& a: W
( G) h' E. y/ N& l s! u' J* L
2 |6 o( _2 V: X( P% ` n! U3 {5 ]8 ^6 F
4,add_dpi.c
* [: U, g6 o' P( G3 Y. g* `3 r9 @
$ r+ s& T$ J+ }. Z" @% ^# d3 e- /*
- * 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;
- }
6 _# a4 f) z8 o3 `: f/ i v
) `( {8 N; E8 S) {+ H9 X; j* d) E
' r3 A5 K+ @8 Y0 i7 ^0 W/ j I; L3 Y! V. G! X
5,mul.v
/ c! f, l# U6 z0 _9 `; J9 w: Q s8 U" t! n4 H* ]- v7 ?; B( l8 m
- /*
- * 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 //: M4 a& [( C" Q3 u
+ ~9 [, W/ F0 K( w7 j8 E
" t9 d6 X8 i t- B6 I
: X4 y7 ^* W) k$ }6,mul_dpi.c
1 I* c) p5 J' {5 I5 |- C8 U( \2 s [- d, `: t
- /*
- * mul_dpi.c
- * dpi test
- * Rill
- * 2014-09-28
- */
- #include <stdio.h>
- int mul_dpi(int c,int d)
- {
- return (c * d);
- }. h0 R+ M: @# G
0 ^ }1 G! n2 L2 K
. ]( d: B' S5 _/ p
# D1 l2 j, w6 \
7,脚本4 f% J- Y% b( w) G9 v; Z1 C; {% @
1 i f' W p/ i$ S3 C- #! /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!"; b/ O3 P% K h: a' J( ~5 U# O
1 _- i5 X' V, [
1 v% H" S, e5 r+ [8 V' X
* v. A, ]2 |: O2 E# {1 G3 K8,vflist0 D' ]: d% Y3 L
. S& ]/ P! T; x1 w" h/ \# h3 P
- //vflist
- tb.v
- add.v
3 R$ w7 t: p" O, b% V8 {1 ~
3 i$ s2 ~9 S' j D" q3 n9 c
3 L6 g0 C) _, L: U8 y9 l7 }/ I; }9 P; B, W. w. q! S5 T2 Z
9,验证结果! y# j5 d. r2 x
. T- M: X5 x* d; R& @/ R- P6 b% H) u
+ d2 o0 ~$ g) p7 H+ D1 ]( V
& H2 H- S- i" a8 C: j3 _2 d5 j* c5 _& ]
10,小结, S& T5 c& _( ]# E; X G
相对于VCS,Ncsim对DPI的支持稍微弱一点,但是从上面的实验可以看出,基本的功能都是支持的,上面的实验虽然简单,但已经包含了实际项目中的大部分情况。 O& _6 d6 N+ q: @ I% @3 `
# H2 v' O) d8 ]6 p% e) ?* o1 T; Yenjoy!
( O& {# A; o9 N3 h, s' h2 k* c3 l4 w3 {; w( l9 [/ D5 Q
2 |1 W! b$ r" P/ H) B2 h& x; w
1 t& J9 N! A8 J& R( R5 g7 y |
|