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

了解一下DPI吧(续)

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x

: U8 s9 e+ }5 O) ~5 y引言; @' w/ o$ n; c1 ~# b6 T" f
, a; `  Y# M/ T/ c
对于SV,无论是构造测试激励,还是模拟硬件的并行行为,DPI都是非常方便的。上次我们介绍了SV里面通过“import”导入并调用C函数。8 K% T% H7 j! u7 s% ^% [+ p

! l% V6 J5 ~. U* b7 K- Y5 n+ Q; g本小节,我们通过一个简单的例子来说明C语言函数如何调用SV的task和function。
$ ^4 F9 w- _/ O
: Q0 J4 S) V2 n8 `, q; m" E! p  r
* D5 w' O9 D8 p5 u+ {9 f- ~' |7 ?1,SV部分
* q$ Y* }& A4 I3 S8 H( w+ N0 ^8 z: W! f- l4 o5 s
2 g8 S7 t% m% c
  • /*
  • * test.v  Rill create for dpi test at 2014-10-20
  • */
  •   e* J+ R2 }" z. ?/ ~
  • `timescale 1ns/1ns

  • % z. ?7 L; z1 Y1 _7 |( }3 }
  • 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

  •   ^- l2 Q6 P* `, f9 d+ L& p* [
  •    m1 M1();
  •    m2 M2();
  • endmodule // top

  • 3 k  }" k$ q2 m; r3 |1 C" _
  • module m1;
  •    import "DPI-C" context function void c_get_m1_scope();
  •    export "DPI" function m1_add;

  • ! y" G; C) r$ C2 K3 d) E" a
  •    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

  • * g! D% F/ k+ Z1 X( z1 O0 W
  •    initial begin
  •       c_get_m1_scope();
  •       m1_value = 8'd100;
  •    end
  • endmodule // m1

  • * ?8 j: S6 o" @4 l
  • % ?8 `% I. G% J9 X5 u
  • module m2;
  •    import "DPI-C" context function void c_get_m2_scope();
  •    export "DPI-C" task m2_add;
  • $ X' ^& c# L/ A
  •    reg tmp;
  •    reg [31:0] m2_value;
  •    task m2_add(input int num,output int sum);
  •       sum = num + m2_value;
  •    endtask // m2_add
  • 5 b" H( k; T, o5 U& g
  •    initial begin
  •       c_get_m2_scope();
  •       m2_value = 32'd200;
  •    end

  • ; |3 Q2 B' T. J4 A
  • endmodule // m18 p- g/ P: q" k
           ) u  j6 `( N  m" C  S/ K: X

: C: A1 b' _& C* e  o, r2,C部分+ ]* ^( t( d1 m& B1 n, L" \+ N
. ~0 j" X4 R0 N3 x; N5 ^5 X$ j
$ n7 {8 n) S: d# [" `6 q
  • /*
  • * test.c  Rill create for dpi test at 2014-10-20
  • */
  • ; r8 e( u8 I" c  S  ^; e
  • #include <stdio.h>
  • #include <svdpi.h>
  • ! e% F' _' O7 Y' A* t* [% I
  • svScope tmp_scope;
  • svScope m1_scope;
  • svScope m2_scope;
  • : p( Q4 T; g# j  H
  • //import task/funcs from sv
  • extern int m1_add();
  • extern int m2_add();

  • + i: {% b& G0 G* @) w
  • //==scope switch
  • void c_get_tmp_scope(void)
  • {
  •   tmp_scope = svGetScope();
  • }
  • ( V) p- z1 R3 P" w# L- S
  • void c_set_tmp_scope(void)
  • {
  •   svSetScope(tmp_scope);
  • }
  • ! g5 }) i: l$ n! {' k
  • void c_get_m1_scope(void)
  • {
  •   m1_scope = svGetScope();
  • }
  • , h5 t6 h( ?- _: [
  • void c_set_m1_scope(void)
  • {
  •   svSetScope(m1_scope);
  • }

  • / R7 y4 W# s: g' b+ x5 J) p( V
  • void c_get_m2_scope(void)
  • {
  •   m2_scope = svGetScope();
  • }

  • ; N& X" v" J1 E, R& g! Z8 i
  • void c_set_m2_scope(void)
  • {
  •   svSetScope(m2_scope);
  • }

  • ) e3 d8 T6 C3 \* k1 M
  • //==export c funcs to sv
  • int c_func(int num)
  • {
  •   int m1 = 0;
  •   int m2 = 0;

  • 9 h# Q# z: U9 ?
  •   c_get_tmp_scope();
  •   c_set_m1_scope();
  •   m1 = m1_add(num);
  •   c_set_tmp_scope();
  •   printf("m1:%d\n",m1);

  • * @( B9 e: h9 m& c( H& i
  •   c_get_tmp_scope();
  •   c_set_m2_scope();
  •   m2_add(num,&m2);
  •   c_set_tmp_scope();
  •   printf("m2:%d\n",m2);

  • % p0 T6 ^3 X; d7 D
  •   return 0;
  • }' G+ T! t& ^) |: G' |( y( c
            
& A; s5 N/ V+ o$ x( S
" N5 y# x; ?) \1 \3 g" |3,脚本* v# p/ s5 ~- `

2 _! Q8 V$ H& i* z1 f' F7 z# R, R
+ ]( f) k1 \: {7 t  N
  • #! /bin/bash
  • # `2 D  T( {  P: l
  • #
  • # test.sh
  • # usage: ./test.sh c/w/r
  • # Rill create 2014-10-20
  • #
  • ; A$ [3 L0 S2 {+ f- J, E' v

  • 9 m" @- X+ L" z, f8 m7 S: G( h
  • TOP_MODULE=tb
  • ; ^0 D" f/ T; K) Y" b
  • tcl_file=run.tcl
  • 3 N, }; J& ~/ M- s7 c9 ^  I0 L  J
  • CDS_INST_DIR=/home/openrisc/opt/edatools/IUS08.20
  • 7 I2 I/ h5 o+ s/ h- \  c1 B

  • - _+ v) U# x9 X8 L3 O2 b+ F
  • if [ $# != 1 ];then
  • echo "args must be c/w/r"
  • exit 0
  • fi
  • 9 y6 f4 x/ k! t5 v
  • 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}
  • . z  X5 x$ l' ^# V* G; ]
  • echo "compile dpi lib"
  • if [ -e libdpi.so ];then
  • rm libdpi.so -f
  • fi
  • . ^! V4 y1 T' m1 e2 m4 l
  • gcc -fPIC -shared -o libdpi.so test.c -I$CDS_INST_DIR/tools/inca/include
  • exit 0
  • fi
  • , c# {8 X, K0 _/ R
  • ( [/ h9 [* T1 U& r9 h, U
  • if [ -e ${tcl_file} ];then
  • rm ${tcl_file} -f
  • fi
  • touch ${tcl_file}
  • + I; `# L0 Y1 H$ ^
  • 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

  • 7 F8 q: ~  k4 f- V& i6 L
  • if [ $1 == "w" -o $1 == "r" ];then
  • echo "sim start..."
  • ncsim  ${TOP_MODULE} -input ${tcl_file}
  • fi
  • ' y$ Z7 y4 F9 \7 C1 O
  • echo "$(date) sim done!"2 n* ?$ m9 |; a/ W2 M1 l
               
2 c: h" ?) d/ V4 w
0 N+ B( _" b* j( T; V' \7 k& s4,说明
6 Z9 L$ U; ^  D  G仔细体会我们上面构造的例子,有几个问题需要弄清楚。/ l9 c. R' k# g: B7 ?6 E
( D5 f9 o5 E! ~' l0 e( s, f3 Q3 p
a,scope的含义:. N- R2 g% [4 J

% ^6 Z: K; @* P& z; F在SV端,m1是不能直接调用m2中的task/function的,所以m1里面调用的C函数也不能直接调用m2中export出来的task/function,如果想调用,必须进行scope切换。- Z5 [" P; M1 `/ W* }" e+ G
) P. `( w+ S& \
b,SV端,有task和function的区分,但是在C端,并没有区分,一律是C函数。8 Q+ h# Y0 f& u* i( r

0 I# ^8 w7 g2 v  q5 H. r/ r, v
! w$ D! {' U/ |7 k+ n5,关于用C模拟硬件的并行行为4 u" L# I4 K1 l8 r9 [& S; M2 f  v4 W1 E

  |3 R# V& O$ V! T方式a,将流水后面的模块写在前面。
8 |' Y; y. Y3 Z# i, s3 I3 t+ I! ^# I; Y
方式b,将所有并行的信号写成如下形式:
6 v4 m$ L# @# F5 I% j" v, I5 B
, w' w* ]9 h3 [6 k用c,n两个变量模拟reg的值。
+ c3 @3 L) K  }7 A! y& u. T# b
用init和update两个函数模拟reg的行为。2 L/ b1 \  E& j- r2 [% S0 r

4 P  c/ Z6 G3 Z9 f4 E
  • /*
  • * parallel.c  Rill create for simulater test at 2014-10-20
  • */
  • ! X) T; ?' m8 H6 Y6 q# t; e  j

  • : M  Q! O' ]7 m4 u* h
  • struct signal;
  •   N  A, L) t) K- `
  • struct sig_ops
  • {
  •         int (*init) (struct signal*);
  •         int (*update) (struct signal*);
  • };
  • " s) y) ?  v/ {6 d  C; X
  • struct signal
  • {
  •         unsigned int c; //current cycle value
  •         unsigned int n; //next cycle value
  •         char name[32];
  •         struct sig_ops* ops;
  • };
  • & D" E  H0 C- J. _
  • /* veritual functions
  • int sig_init(struct signal* signal)
  • {
  •         return signal->ops->init(signal);
  • }
  • + n* I  W* l; c3 F& m- J
  • int sig_update(struct signal* signal)
  • {
  •         return signal->ops->update(signal);
  • }
  • */

  • # u) k' ]  k, F! m0 `: q
  • //actual functions
  • int test_init(struct signal* signal)
  • {
  •         signal->c = 0;
  •         signal->n = 0;
  •         return 0;
  • }
  • - a8 s' O3 P: N6 z( @
  • int test_update(struct signal* signal)
  • {
  •         signal->c = signal->n;
  •         return 0;
  • }
  • # [6 Z' h/ R/ X" g; v& s! K+ k
  • , L* v: o+ V6 N) _8 X' n
  • ) w2 u0 P  Y- p! z/ E* r$ H9 Q5 P
  • int signal_create(struct signal* signal,char * name)
  • {
  •         signal->name = name;
  • }

  • 5 `' I8 ?- {' j
  • //============main.c====================//
  • //example signal
  • struct signal test;
  • struct sig_ops test_ops =
  • {
  •         test_init,
  •         test_update,
  • };

  • : t4 \' _3 ]. g  v$ C4 `
  • int main()
  • {
  •         signal_create(&test,"test");
  •         //when reset
  •         test->ops->init(&test);
  •         //per cycle
  •         test->ops->update(&test);
  •         return 0;
  • }" I& C8 y) L7 C. @2 j
             9 n5 J& X$ b0 J2 S9 [3 \3 V1 K7 R
8 j+ C9 o/ D& B5 O

$ x+ E& W" P/ w! E+ }0 Z: w% J9 |# _2 r! S, {+ {* n
* T5 A/ J! e/ z" A! J

( c* T$ L8 |# M& m' _
  ]$ I% I$ n! l& `" ^* `* i$ J3 J4 Z5 q
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-6-28 12:34 , Processed in 0.078125 second(s), 23 queries , Gzip On.

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

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

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