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

了解一下DPI吧(续)

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x

+ D, M' N5 O- Z  x) l; E引言* N: L5 x8 e0 B1 Y. j5 b# F
; O' w" f8 h, P& X. |
对于SV,无论是构造测试激励,还是模拟硬件的并行行为,DPI都是非常方便的。上次我们介绍了SV里面通过“import”导入并调用C函数。8 ^  W+ N7 {. f, p

3 v3 d& s& f% O# V% l本小节,我们通过一个简单的例子来说明C语言函数如何调用SV的task和function。4 Y4 z. A9 ^* c; J# i- r2 }& O
: b; O' x, k( w

& P( v* V9 {. Q1 r+ E1,SV部分# [- `  |  L" G. O% y
. S! W$ e% y! P

. N- h4 b) T8 Q
  • /*
  • * test.v  Rill create for dpi test at 2014-10-20
  • */
  • : a+ V$ c, R8 l1 }
  • `timescale 1ns/1ns

  • * ^; j* M' a, k& |+ B
  • 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
  • 4 ^9 k) _% u, x$ Z8 T+ s; t- E
  •    m1 M1();
  •    m2 M2();
  • endmodule // top

  • $ m% u! a2 t6 ~  g) I, L
  • module m1;
  •    import "DPI-C" context function void c_get_m1_scope();
  •    export "DPI" function m1_add;
  • - g/ N1 K! k2 V5 ^4 O% x
  •    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

  • 9 G8 W1 a# e; {( k
  •    initial begin
  •       c_get_m1_scope();
  •       m1_value = 8'd100;
  •    end
  • endmodule // m1
  • , J! l( X; l7 t, u$ \$ `2 _
  • 7 [; x; ~1 o8 N
  • module m2;
  •    import "DPI-C" context function void c_get_m2_scope();
  •    export "DPI-C" task m2_add;
  • , Y4 l" S1 H9 d8 D% X3 ]# \
  •    reg tmp;
  •    reg [31:0] m2_value;
  •    task m2_add(input int num,output int sum);
  •       sum = num + m2_value;
  •    endtask // m2_add

  • 8 O, G1 U$ ]4 k7 @  _0 N# X
  •    initial begin
  •       c_get_m2_scope();
  •       m2_value = 32'd200;
  •    end
  • 4 k. c$ T& R* a
  • endmodule // m1
    % t% M# F0 N  F2 t5 D
           
3 G1 R+ ^: C# X" l! \) A& _4 `9 y( j, P* c6 c
2,C部分
3 k1 X7 |6 w% T, X& ^+ A  R: b8 z' z  U) T( j0 m& x8 e

! u6 ?" B* r& g  h7 X! M$ G* r7 `
  • /*
  • * test.c  Rill create for dpi test at 2014-10-20
  • */

  • 6 A7 g3 j/ ^' d% s0 r
  • #include <stdio.h>
  • #include <svdpi.h>

  • 7 I1 N# n% E3 s* o! F
  • svScope tmp_scope;
  • svScope m1_scope;
  • svScope m2_scope;
  • ( m  x4 d' `, g
  • //import task/funcs from sv
  • extern int m1_add();
  • extern int m2_add();

  •   H. K! Y$ t( g5 f. I2 `. t
  • //==scope switch
  • void c_get_tmp_scope(void)
  • {
  •   tmp_scope = svGetScope();
  • }
  • 3 J0 @' n: P/ f2 s3 O2 V: k+ f' M
  • void c_set_tmp_scope(void)
  • {
  •   svSetScope(tmp_scope);
  • }

  • + C+ i$ P( K( b: b
  • void c_get_m1_scope(void)
  • {
  •   m1_scope = svGetScope();
  • }
  • % o3 s8 X0 O  D  {0 e( n$ r
  • void c_set_m1_scope(void)
  • {
  •   svSetScope(m1_scope);
  • }
  • 4 \$ r* |" S: U' l9 i0 L
  • void c_get_m2_scope(void)
  • {
  •   m2_scope = svGetScope();
  • }
  • 1 k. M: y) S$ u% w& x
  • void c_set_m2_scope(void)
  • {
  •   svSetScope(m2_scope);
  • }

  • 2 Z$ I5 Q0 `) [+ A
  • //==export c funcs to sv
  • int c_func(int num)
  • {
  •   int m1 = 0;
  •   int m2 = 0;

  • , S& A/ s8 J5 `* a" E) a
  •   c_get_tmp_scope();
  •   c_set_m1_scope();
  •   m1 = m1_add(num);
  •   c_set_tmp_scope();
  •   printf("m1:%d\n",m1);

  • # I( _% C7 E9 d8 t9 d
  •   c_get_tmp_scope();
  •   c_set_m2_scope();
  •   m2_add(num,&m2);
  •   c_set_tmp_scope();
  •   printf("m2:%d\n",m2);

  • , J! _. u! k: D& t  J6 J1 J
  •   return 0;
  • }
    3 [+ o( v9 \  Y- |- B$ N: u' v: K
             2 c: b" e& P$ x' _7 ?  a6 I# R
3 ~# r3 X- q9 y7 h1 A8 F9 [6 n) A" J
3,脚本) _8 l7 z0 _6 D, H

% b4 t8 @1 T: [2 t* N$ i' G
$ _' @: s3 r! Y5 i9 P4 L# d
  • #! /bin/bash

  • ! A* A6 ~. f8 s  K* Q4 k' D
  • #
  • # test.sh
  • # usage: ./test.sh c/w/r
  • # Rill create 2014-10-20
  • #

  • 8 m( ?% I- f8 A

  • . v8 S* `* \) o5 B5 }
  • TOP_MODULE=tb

  • - C9 L' ?$ r. q' g
  • tcl_file=run.tcl
  • : L2 W: \2 T0 A' v! V! I
  • CDS_INST_DIR=/home/openrisc/opt/edatools/IUS08.20
  • ' [5 ^) F# s% e& ]

  • % W+ t' \8 N5 b' c+ ?) G  F; @
  • if [ $# != 1 ];then
  • echo "args must be c/w/r"
  • exit 0
  • fi
  • 2 Q- Y# h% G; J; ^
  • 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}

  • ; S' e  v$ {% h/ N$ S  X5 T, S
  • echo "compile dpi lib"
  • if [ -e libdpi.so ];then
  • rm libdpi.so -f
  • fi
  • - ^$ Z6 E% O1 h. L1 L! u7 q
  • gcc -fPIC -shared -o libdpi.so test.c -I$CDS_INST_DIR/tools/inca/include
  • exit 0
  • fi
  • / A4 ~4 C8 s* ?1 w
  • & ^2 c  }, J9 I
  • if [ -e ${tcl_file} ];then
  • rm ${tcl_file} -f
  • fi
  • touch ${tcl_file}

  • ) f" q; h; j9 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
  • # d; z6 x4 A5 T4 `1 `; z$ T
  • if [ $1 == "w" -o $1 == "r" ];then
  • echo "sim start..."
  • ncsim  ${TOP_MODULE} -input ${tcl_file}
  • fi
  • " X' K% D6 D2 u
  • echo "$(date) sim done!"7 V, L7 @- j2 P
                 M5 o, j/ s# u
3 T( K' Z3 l( Z. N1 }0 S! U
4,说明6 Y/ F; A8 j9 \+ R
仔细体会我们上面构造的例子,有几个问题需要弄清楚。+ \6 q  ^( Y2 j8 O

4 h6 u+ C; e" x" j7 ~a,scope的含义:
. h! v  M% |3 \
) ]- J4 R' _7 U  c* w9 m在SV端,m1是不能直接调用m2中的task/function的,所以m1里面调用的C函数也不能直接调用m2中export出来的task/function,如果想调用,必须进行scope切换。
  k5 R8 X5 \" |. P/ F, O
( H, t' {1 _( u/ n* Sb,SV端,有task和function的区分,但是在C端,并没有区分,一律是C函数。" A3 }; S$ Z8 {+ }/ g9 @" f6 u
$ n5 l9 y7 V% z1 U& g
- n$ o$ u7 ^% K* h( l
5,关于用C模拟硬件的并行行为
% [8 I9 q3 m0 i5 F9 J. ]; n* s( n
方式a,将流水后面的模块写在前面。
( F# Y* D2 ?" m
" n7 ?2 d2 Y+ Q  D方式b,将所有并行的信号写成如下形式:
# S* e. P3 l! Y/ q$ [7 g, E2 x3 h, D; _' k( m& w
用c,n两个变量模拟reg的值。
2 K2 F$ u; C; k# i; F# B6 T$ N4 t
用init和update两个函数模拟reg的行为。- s% C0 ?9 C( O9 ]# Z
1 H, j% D" x) V, i7 Y1 }. [$ t9 q
  • /*
  • * parallel.c  Rill create for simulater test at 2014-10-20
  • */

  • 4 C9 d1 d: U) G+ y  i  A  ?# R

  • ( g3 p/ o4 @7 k: D
  • struct signal;
  • , s) V: I6 X8 x$ f( R
  • struct sig_ops
  • {
  •         int (*init) (struct signal*);
  •         int (*update) (struct signal*);
  • };

  • : w3 d) k+ H5 c& @$ A" b. w( L
  • struct signal
  • {
  •         unsigned int c; //current cycle value
  •         unsigned int n; //next cycle value
  •         char name[32];
  •         struct sig_ops* ops;
  • };
  • 1 d" R7 n! K. i' x
  • /* veritual functions
  • int sig_init(struct signal* signal)
  • {
  •         return signal->ops->init(signal);
  • }

  • - f$ i2 I8 Z: e+ y- _
  • int sig_update(struct signal* signal)
  • {
  •         return signal->ops->update(signal);
  • }
  • */
  • , K6 |2 {' o! y( ?% d& ], P
  • //actual functions
  • int test_init(struct signal* signal)
  • {
  •         signal->c = 0;
  •         signal->n = 0;
  •         return 0;
  • }
  • , j$ _% ]5 y3 o! c& ]6 t
  • int test_update(struct signal* signal)
  • {
  •         signal->c = signal->n;
  •         return 0;
  • }

  • 2 k( G+ J/ X% v: v4 s
  • 1 P( ~1 ^& `! g" O8 q7 f1 C; K

  • 3 Y! G  S6 t: D$ ?+ S, j9 }
  • int signal_create(struct signal* signal,char * name)
  • {
  •         signal->name = name;
  • }

  • 7 \( Z: b& S; t; n2 }# X/ _
  • //============main.c====================//
  • //example signal
  • struct signal test;
  • struct sig_ops test_ops =
  • {
  •         test_init,
  •         test_update,
  • };
  • ; M8 g- V( T6 {* Y( p1 u6 m5 T6 a+ N
  • int main()
  • {
  •         signal_create(&test,"test");
  •         //when reset
  •         test->ops->init(&test);
  •         //per cycle
  •         test->ops->update(&test);
  •         return 0;
  • }
    1 n- D  E% C( o, j7 `9 t( n
             3 w/ e8 F( }8 o
' M) p* S6 o# J

- g. b  |7 b$ E
' B5 S/ K+ _/ o9 O
' ~6 j0 G! c0 T' d3 s3 H
3 o9 |; C" l6 B' Q- U. K4 m% s* @. l2 t# R1 b2 ]
& l  _" ]. m) I9 G
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

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

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

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

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