找回密码
 注册
关于网站域名变更的通知
查看: 206|回复: 1
打印 上一主题 下一主题

了解一下DPI吧(续)

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2020-7-23 14:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x

3 Z7 R0 S: J9 F) r3 U( y+ B: g引言6 c9 ~5 z+ z$ [) Z
- h4 B$ g! r! C7 @* a
对于SV,无论是构造测试激励,还是模拟硬件的并行行为,DPI都是非常方便的。上次我们介绍了SV里面通过“import”导入并调用C函数。8 ]6 y. s( }/ r9 A
7 K$ d) r. A. r8 B" ]
本小节,我们通过一个简单的例子来说明C语言函数如何调用SV的task和function。6 o: n, C2 O! q8 a

: n* r7 |% `. u5 [4 m% n# Q: T. ~6 E" p
1,SV部分4 ^4 i* E) I) O' l3 |: K

/ Y. g( v* b8 Z
6 s% {: r: T" v
  • /*
  • * test.v  Rill create for dpi test at 2014-10-20
  • */
  • # i* @! F6 j& U3 Z
  • `timescale 1ns/1ns

  • + q/ M: k; J. ?$ I7 S* j
  • module tb;
  •    import "DPI-C" context function int c_func(input int num);// or import "DPI-C" context task c_display(input int num);
  •       reg tmp;
  •       initial begin
  •          #10
  •            tmp = c_func(1);
  •       end
  • * A, j" c* o, R) G7 U) y
  •    m1 M1();
  •    m2 M2();
  • endmodule // top

  • 9 w9 i. F: r2 a: {
  • module m1;
  •    import "DPI-C" context function void c_get_m1_scope();
  •    export "DPI" function m1_add;
  • , X0 F2 ?' t. s8 B- S5 E( T1 Y
  •    reg tmp;
  •    reg [7:0] m1_value;
  •    function int m1_add(input [7:0] num);
  •       m1_add = num + m1_value; //or return (num + m1_value);
  •    endfunction // m1_add
  • : w  w; j" V) c: ^( u  u0 \/ V) Q! {1 g' }
  •    initial begin
  •       c_get_m1_scope();
  •       m1_value = 8'd100;
  •    end
  • endmodule // m1
  • ' H+ ?4 ]5 N  V9 e; X- Y, [

  • 4 U: o, f7 ]! [6 f. X. l
  • module m2;
  •    import "DPI-C" context function void c_get_m2_scope();
  •    export "DPI-C" task m2_add;

  • : @* U' l0 c2 D! a8 j$ `
  •    reg tmp;
  •    reg [31:0] m2_value;
  •    task m2_add(input int num,output int sum);
  •       sum = num + m2_value;
  •    endtask // m2_add

  • : s' n( Z3 ?- t; {. @
  •    initial begin
  •       c_get_m2_scope();
  •       m2_value = 32'd200;
  •    end
  • 6 ]7 A# m$ A0 K. T1 w7 L; W
  • endmodule // m1
    " y2 Y% e( h1 h! ~  o+ m9 k
             F# O# G7 P( T9 b

+ t" @* @' X. j4 I2 m  [- I( P- `) P8 C2,C部分
; Z; f4 Q4 \- s4 A4 H# v3 L% Y+ d  {. E  t0 b1 A. A& v- g7 L

7 ]8 @6 @! U3 \! v- T8 |
  • /*
  • * test.c  Rill create for dpi test at 2014-10-20
  • */
  • ) I2 j+ k5 f5 F6 m7 p* Z: E' n0 q
  • #include <stdio.h>
  • #include <svdpi.h>

  • % p1 a4 s6 R- I' a1 S
  • svScope tmp_scope;
  • svScope m1_scope;
  • svScope m2_scope;
  • ' V; D* C& {- w. {+ k, u& N
  • //import task/funcs from sv
  • extern int m1_add();
  • extern int m2_add();

  • " v8 ?0 v  k6 F
  • //==scope switch
  • void c_get_tmp_scope(void)
  • {
  •   tmp_scope = svGetScope();
  • }
  • 6 E9 Q  M( @# a( v( R' ?6 }' K
  • void c_set_tmp_scope(void)
  • {
  •   svSetScope(tmp_scope);
  • }
  •   h7 o3 t( u* ~; C" b. L9 H" o
  • void c_get_m1_scope(void)
  • {
  •   m1_scope = svGetScope();
  • }
  • & S5 I) k) H# A% X, F' w
  • void c_set_m1_scope(void)
  • {
  •   svSetScope(m1_scope);
  • }

  • . Q4 I3 P6 X7 \" p
  • void c_get_m2_scope(void)
  • {
  •   m2_scope = svGetScope();
  • }

  • / N- x/ `% O& ]# t1 E- g
  • void c_set_m2_scope(void)
  • {
  •   svSetScope(m2_scope);
  • }
  • , `1 ^5 w$ `" L/ A
  • //==export c funcs to sv
  • int c_func(int num)
  • {
  •   int m1 = 0;
  •   int m2 = 0;

  • % o( A/ V, \0 t: l
  •   c_get_tmp_scope();
  •   c_set_m1_scope();
  •   m1 = m1_add(num);
  •   c_set_tmp_scope();
  •   printf("m1:%d\n",m1);

  • & j. w, ~7 p* x; C$ A  @7 Z
  •   c_get_tmp_scope();
  •   c_set_m2_scope();
  •   m2_add(num,&m2);
  •   c_set_tmp_scope();
  •   printf("m2:%d\n",m2);

  • ; p. Z7 u6 a! _, j) `) T% o
  •   return 0;
  • }
    3 b7 \1 R4 n8 O) f6 V9 l
            
$ J8 G* q+ J5 c, U- u0 b
( {# G0 J9 M( X3,脚本7 S0 W$ n5 I* f  g8 v

3 n' T( W5 O+ |, x/ g
% Z* S& x: @8 n1 S- v6 Y5 r0 ]' n& W
  • #! /bin/bash
  • 5 i  N3 j  Q: T/ I) c" j
  • #
  • # test.sh
  • # usage: ./test.sh c/w/r
  • # Rill create 2014-10-20
  • #

  • ; w( i' f$ r8 ]! ?4 c4 R
  • ) R; j8 z/ j0 ~* J7 e. ]1 f
  • TOP_MODULE=tb

  • . i; y  M2 [. O* ^" g. T& \
  • tcl_file=run.tcl

  • ( @* q* K* _& L, x( o! W7 A
  • CDS_INST_DIR=/home/openrisc/opt/edatools/IUS08.20
  • ; n$ S2 |- M. n2 s8 W
  • 2 Z3 Z8 C1 @( N! q' H% Q
  • if [ $# != 1 ];then
  • echo "args must be c/w/r"
  • exit 0
  • fi
  • 6 t& w! N/ p. ~/ ?( l4 n* w1 o
  • if [ $1 == "c" ]; then
  • echo "compile rtl lib..."
  • ncvlog -f ./vflist -sv -update -LINEDEBUG;
  • ncelab -delay_mode zero -access +rwc -timescale 1ns/10ps ${TOP_MODULE}

  •   X6 L% j+ \: A2 k+ x
  • echo "compile dpi lib"
  • if [ -e libdpi.so ];then
  • rm libdpi.so -f
  • fi

  • ) s6 t% d2 r4 |* \
  • gcc -fPIC -shared -o libdpi.so test.c -I$CDS_INST_DIR/tools/inca/include
  • exit 0
  • fi
  • - i/ E1 |' H/ w6 m+ a

  • 8 [% E2 t+ ]( Z, J. w( l
  • if [ -e ${tcl_file} ];then
  • rm ${tcl_file} -f
  • fi
  • touch ${tcl_file}
  • # C6 t/ J: T2 t1 q
  • 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

  • ) ~- @' M, B" U5 K6 @6 V
  • if [ $1 == "w" -o $1 == "r" ];then
  • echo "sim start..."
  • ncsim  ${TOP_MODULE} -input ${tcl_file}
  • fi

  • 6 {2 K6 |- |) T' I
  • echo "$(date) sim done!"
    - e! d0 e- E. X/ K2 \
               + }7 q( I5 \- C6 Q4 U8 q: f

( K% A) w  A9 l4,说明2 o3 M1 f7 G0 q, x6 h8 ~9 W  b$ G
仔细体会我们上面构造的例子,有几个问题需要弄清楚。
& T- q  s: B' w6 r7 G, ~4 ]% x/ D4 H7 r% ~+ Y' y& M. k
a,scope的含义:# \5 E# \4 z5 {$ G7 ?

' K7 K& a9 [9 _. x; Q' F7 N在SV端,m1是不能直接调用m2中的task/function的,所以m1里面调用的C函数也不能直接调用m2中export出来的task/function,如果想调用,必须进行scope切换。
/ J& x( l8 q* ?4 ^# X( \7 P4 O1 U
b,SV端,有task和function的区分,但是在C端,并没有区分,一律是C函数。
) ~# G3 k& i5 t8 t" D2 a+ e2 x& Z' \) U% c! S" f# u6 G/ w

% n$ k% H# c1 S! @9 X( {  q5,关于用C模拟硬件的并行行为+ B" O4 u" b! w, O( z

' F( p) F7 k9 B# Y+ K3 {方式a,将流水后面的模块写在前面。" Q  N* d( F' \

2 R5 R3 G3 s& b. q4 G8 E方式b,将所有并行的信号写成如下形式:
! n! w# _% L3 m  z$ \' x1 V. I0 E; r9 d! s$ X% D0 X! F
用c,n两个变量模拟reg的值。/ P. F1 F& U, K# ~) X1 w8 v

) b+ L( l# `* V( m* I' y7 J* a用init和update两个函数模拟reg的行为。
! {' K" A: ^* M: p3 u% F" U( h, l# Z# c, S$ C: z! ~
  • /*
  • * parallel.c  Rill create for simulater test at 2014-10-20
  • */
  • ; Y" S+ F; {) D5 Y  T
  • / F+ D" C3 M- T& I/ N3 p
  • struct signal;

  • : K9 l( g8 g  N. u
  • struct sig_ops
  • {
  •         int (*init) (struct signal*);
  •         int (*update) (struct signal*);
  • };

  • # z, [( |" B; P& k
  • struct signal
  • {
  •         unsigned int c; //current cycle value
  •         unsigned int n; //next cycle value
  •         char name[32];
  •         struct sig_ops* ops;
  • };
  • 8 {9 X4 b* o/ W  j# o
  • /* veritual functions
  • int sig_init(struct signal* signal)
  • {
  •         return signal->ops->init(signal);
  • }
  • 8 T" V2 @8 i9 r$ Z' W
  • int sig_update(struct signal* signal)
  • {
  •         return signal->ops->update(signal);
  • }
  • */

  • - t1 L' \, b6 X
  • //actual functions
  • int test_init(struct signal* signal)
  • {
  •         signal->c = 0;
  •         signal->n = 0;
  •         return 0;
  • }

  • 5 b6 A) a+ D0 k
  • int test_update(struct signal* signal)
  • {
  •         signal->c = signal->n;
  •         return 0;
  • }
  • / D- m' F) D  q8 R1 |6 f

  • 6 E9 L* w, c: B8 @* t) E) w9 v( @

  • ( c% |" ^* j8 w1 `' @8 ?6 L6 C
  • int signal_create(struct signal* signal,char * name)
  • {
  •         signal->name = name;
  • }
  • ; J  ^1 G+ J3 {# Z, j
  • //============main.c====================//
  • //example signal
  • struct signal test;
  • struct sig_ops test_ops =
  • {
  •         test_init,
  •         test_update,
  • };

  • ! M) U4 [) K8 x1 v! a& b" I- ]
  • int main()
  • {
  •         signal_create(&test,"test");
  •         //when reset
  •         test->ops->init(&test);
  •         //per cycle
  •         test->ops->update(&test);
  •         return 0;
  • }$ ]6 \" W6 Y% F( T
            
" F: [- ?  |: h" X3 o7 J0 q
" e5 w- Z, w. `/ i1 c& @% {! _/ D  M. f1 V/ P
- M1 \) G9 K6 u2 B) [8 n7 k
* ^. }9 M& Y. y% ?' U# M% h

6 P1 a. n+ N, ^; J/ G- @$ k0 k
  i' T9 S# u+ k
$ i  |7 E2 j  [! ?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-11-25 01:18 , Processed in 0.156250 second(s), 23 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表