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

DSP学习经验

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2016-5-10 17:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

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

x
大学毕业至今,做了三年的DSP开发,将稍许经验记录下来,分享一下。; T; y0 `7 O- \. T: D
  一、弄清DSP相关资源的来源及熟读手册
3 ~1 j+ ]- s- K4 \$ ~  一般主要来源于DSP芯片厂商的官方网站,虽然现在的DSP芯片厂商都提供了中文的官方网站浏览,但我建议还是上英文的网站,其一,有些资源在中文网站上没有(关于这点,我个人认为可能是中文这边的资源未及时上传),其二,一般资料很少有中文版,中文和英文版网站上下载的其实是同一个版本;再就是,要熟悉DSP芯片厂商的官方网站,开发时允分利用官方提供的资源及支持能大大地提高开发效率;最后要注意的是,一般DSP芯片厂商会开放一个技术交流论坛,里面的管理员一般都是DSP芯片厂商的开发工程师,可以以发贴的形式获取他们的技术支持。
* ?" Q% {+ E, Y  @+ j. K  还有一处资源的来源,就是跟DSP芯片厂商有合作的第三方公司(国内),这类公司跟DSP芯片厂商有很好的接触,一般相关的DSP芯片,他们都会先行做成教育开发板,这点当然主要用于教学,所以他们会有相关的中文资料及相应的demo程序,根据这点,可以很好的借鉴他们的经验及参考他们的资料及程序,其次,他们还会出售自制的仿真器,价格比原厂的会便宜,功能上肯定没有原厂出售的仿真器全面,但足以应对基本的项目开发。/ ]9 O7 o% G6 k, ]
  第三处仅供参照,占据国内市场最大的两家DSP厂商TI和ADI在中国都开设的相应级别的DSP培训课程,但费用昂贵,一般都是公司派遣前去学习。0 `# r9 a( _2 X+ w" E
  资源主要包含:/ I9 D3 r) V" {: T1 K$ x
    Datasheet(数据手册,主要大体介绍一下DSP芯片的功能,内部结构及外设,软件及硬件一些简单介绍,主要作用是可以很快速的了解这款DSP)1 `/ F( F  M% A' W
    Software Tool Manuals(这个手册主要介绍的DSP时钟、存储器、电源管理等等及所有外设的使用及注意事项,其实就是寄存器的配置,完全可以称之为DSP使用手册)
5 |' O1 H' a8 y% I0 }    Hardware Tool Manuals(这个手册主要是官方提供的原理图PCB的绘制)、Program Manuals(这个手册主要介绍编译器及内置C库的使用,汇编指令的使用及汇编语法的介绍,官方提供的仿真软件的使用). j7 T# T! L4 T; D
     Engineer to Engineer Note(工程师笔记,这个其实就是DSP芯片自己的工程师在开发这款DSP时所写的笔记,如果你有某个地方未明白,看相应的工程师笔记是最合适的)
/ l- Y5 ~  g+ ~: w+ H8 _5 W2 h+ }    Program Examples(主要是针对DSP不同的外设,官方提供的程序例子,包含C及汇编)5 S( L( v, ~8 _! j) _6 k
  二、官方仿真软件及仿真器的使用(如不使用,可暂时跳过,因为有些DSP可基于开源的操作系统进行开发,例如uClinux)  r: i' j" {1 v3 s& L" Z3 k. E- Y' f
  使用仿真软件的方法其实很简单,一般这种软件都设计成类似VC这种,你逐个去试每个菜单下的选项,此时你如配合Examples去使用,更能加深理解,不过我建议,做DSP软件开发,先简单看一下Datasheet、Software Tool Manuals和Program Manuals这三个文档再开始熟悉仿真软件的使用,当然在你熟悉时,肯定需要去不停的再去看这些文档的。仿真器的使用并没有什么需要注意的,一般的仿真器都做了仿呆处理,所以不会插反,仿真器一般都是配合仿真软件使用。(有一点要提醒的是一般DSP开发是基于C语言,如果不会C语言,请先学习C语言)
% Q. m4 O  [* [4 {. e3 x2 j" C+ O  三、DSP最小系统的配置
) v3 @& o; \: G" p: c  这部分就正式开始使用DSP了,最小系统主要指DSP的时钟及存储器系统,这时你需要对照着Software Tool Manualsh去仔细看里面的介绍及相关寄存器的配置,结合Examples及Engineer to Engineer Note,如果程序写完后,测试时钟其实很简单,用示波器直接去测量,看测量出来的时钟是否是你配置的那个数,紧接着就是测试存储器,这个测试必须写一段简单的小程序,其实主要就是测试数据总线是否能正常工作,如果在配置最小系统时出现问题,一般问题有二,一是寄存器未正确配置,解决方法是结合Examples及Engineer to Engineer Note仔细看手册,看例程,二是可能开发板上的硬件线路出了问题,解决方法是结合原理图,看线路上是否存在短路的问题,DSP工作电压是否正常等,这步可和硬件工程师一起去查。
+ P# ^9 F) `. G  B  四、DSP外设的使用1 Y5 ^( |1 R1 O& G, ]
  其实这部分和配置最小系统一样,只不过某些外设上可能连接了其它的芯片,不同的功能连接的芯片不一样,此时你需要去看这些芯片的资料,然后开始编写代码,然后再测试,测试方法根据不同的功能也会不同,不过DSP开发最常用的就是使用示波器,如有音视频方面的,可借助摄像头,显示屏等等之类的;如中间开发遇到问题,方法还是一样,结合Examples及Engineer to Engineer Note仔细看手册,看例程,有一点要注意,千万不能怀疑不能实现,要对自己有信心。
: D, o1 ]! K4 T5 m& q/ C# O  五、DSP优化
* x; N; p4 r) ^8 |4 G% y; b+ F  其实到这一步,你已经完全可以使用DSP了,接下来,你需要加深熟悉DSP的整个内部结构,主要包含有几个多少位的MAC,有几个多少位的ALU,有几个多少位的数据寄存器等等,还有外部数据总线上连接了哪些外设,内部数据总线是怎么连接的,并且这些数据总线是多少位,这些在Datasheet会有一张很清楚的DSP结构图,还有DSP的整个Memory Map是怎样的,片上有多少Data Memory,有多少Program Memory等等,了解这些其实就是让你知道DSP的运算性能到底可以达到多少,哪些外设会通过外部数据总线传输数据,DSP内部的寄存器是怎么传输数据的,通过这些可以帮助你解决你在开发中遇到的问题,不过最主要的是帮助你对已经编写完成的代码进行优化,我个人认为的优化方法有以下几种:
4 _/ p8 |' N' n4 t- V1 J8 L  1、一般编写代码首先是用C,基于C层面优化的方法,我如下举例说几种:- A; O, l& O* \! [2 ]4 m
    (1)优化循环% |+ C& X% e: P2 @0 J9 r) E
    for(i = 0;i < max;i ++)
$ p% \5 C8 ]- R  J     {
0 e" i0 U! }7 H4 F2 r        for(j = 0; j < max; j ++)9 Y; @# p! w0 ^( l7 i! C9 A- f. u
        {( {" i4 N. z6 g5 e/ G8 `
            float sum = 0.0;
6 H5 G, X! `6 e% x            for(k = 0; k < max; k ++)
7 \2 i5 x, J# u+ r; [) z# n* q" I            {" Y5 [: \- W1 d5 m0 h5 D
                sum += input[i * max + k] * input[j * max + k];( A9 I/ Y6 E& F( z
            }
0 r8 J, H2 V4 y9 M0 b5 `. P            cover[i * max + j] = sum / max;. Z: x" @1 O$ j/ C, t# S
        }
( }# Q  l- H* j; H    }3 _9 Q$ d; [% ^+ a+ p
    实例,如input[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},得出的cover如下:1 V& a. Q0 D+ t# o$ f8 v; f
     7    17   27   37
# D) t+ q% B' |! e, D! V     17  43   69   95
$ f5 x$ m/ L2 D8 V& }     27  69  111  153
- p& \2 C& ?& e. ~     37  95  153  211
( {, H6 a. \' u! b6 [8 o7 C    图示:# e2 m% X% O7 x, v* [
    : [% o0 J' F% ~# F% _, ^
    原理:只需要得到左上角或右上角即可,然后半个矩阵赋值给另半个矩阵即可得到整个矩阵。  ^( M" L' v" A& T8 X5 B% }
    算法优化后:# a3 U8 V0 |% i* Y6 y
    for(i = 0; i < max; i ++)
7 B/ w3 C% _8 y7 ~) B    {/ m) ^) V7 c+ I6 Z4 k
        for(j = i; j < max; j ++)                  // 减少一半循环
  [7 H9 Z* F$ d1 J8 i        {2 S, P4 k. p1 F3 k
            float sum = 0.0;* j$ s1 U6 `% k* U
            for(k = 0; k < max; k ++)2 p2 p# A. Z/ B, i
            {- f# b; E4 T* Z. Z/ G" w
                sum += input[i * max + k] * input[j * max + k];: N" X: G1 u6 N8 k0 m
            }
+ ~0 L3 `6 V( ^            cover[i * max + j] = sum / max;; f7 V6 h/ \4 F* \
            if(i != j)                    // 可加可不加,消除中线上的重复赋值- ~- B; j0 ]  ~, r( A8 C
            {* m6 W( x. p" l7 X% w
                cover[j *max + i] = sum / max;       // 赋值给另半个矩阵
$ B1 w2 c" s( ]6 v& l% ~% J8 b            }
. D% a8 N/ X8 w        }; j5 P& E# y# J$ K  K% e6 K7 s
    }4 @9 x5 V' T) E9 A  l
    (2)条件跳转(使用条件跳转会在流水线中浪费更多的周期)6 ~* {+ X6 l2 j, I) f" Q
    k = k -1;
# B& z  b) ~1 e1 ?6 `- U  o" `6 h    if(k < -1)3 V% ~2 a2 y) X% }. p0 u% G  j
    {
+ y+ {" e( Z& g9 b9 c- S  i2 @        k = -1;
/ {- T. u; l( H. l( N    }( G7 a# }% w" B; i* z/ Y
    原理:C语言中的max函数在编译的过程中实际上实现的是DSP中的MAX指令。
' ~4 U+ F$ r+ P% ?+ R    优化后:
5 G  f' N9 n+ \8 ]# L- g    k = max(k-1, -1);
4 l( U$ R) K8 |- J# }# o- x1 V    转换成汇编后:( ^- _! s9 }! L% P
    R0 += -1;    // R0 == k;: b+ w- N! ~+ x  [, R% _4 J. _
    R1 = -1;
! a3 e; b9 L/ o1 `. ?$ y6 ~    R0 = MAX(R0, R1);3 X4 t1 s: ]. g* W7 `
    (3)for循环中的条件跳转, z" W$ f( t6 K6 _! l" d
    for
, `" U$ s  ]4 [, ?    {% ]$ B- `2 y: ^3 x5 x9 u
        if{...}else{...}
: I4 F+ N5 F5 {: B3 M! G, ?" v" o    }- J, Q3 H: q5 L
    原理:减少频繁的条件跳转,当然并不是所有的情况都可以这样做。! _6 n) ?0 E2 D* R  |/ K' V
    优化后:& E. S% ]! _3 ~3 L
    if
7 Q4 |$ V! u4 ^  [9 ~; _* W+ }    {
- W' T% Y& [. ?1 R7 c        for{...}; ?: [) U$ v& B' _5 K
    }: D6 `! [' F% U' d5 O0 h
    else
+ Z3 r, N' o* o4 S    {  l  X; X; O8 W/ v* L; L" Z
        for{...}2 j& Q! P7 l/ Y4 F( H. Y
    }$ l5 K  d( B5 S' L7 E
    (4)使用断言指令来避免条件跳转& V+ ^& a1 E% q/ ]6 l
    if(A)
0 x+ ^0 x0 d4 v: Q1 m    {
, v% q$ e+ U2 O0 B' h/ M- j        X = exp1;
- y  p0 C7 f6 k- @     }
4 C& T, e! z0 a8 L- N/ q# c3 K, h    else2 t4 M- m2 S0 w# a
    {
5 V( M% a$ Q% d  e        X = exp2;5 _1 I4 W5 {% ?' K$ A5 K3 }1 x6 h
    }    
/ S5 t+ F# f9 a# h& f    原理:使用断言指令IF(CC) REG = REG,只会消耗一个周期。  h5 z$ z* A& }# B
    优化后:
* G! y  w4 [4 R1 B1 E4 Z) K$ L4 y% E    X = exp1;
4 x* R  O5 H- I( K) c$ i7 u  Q    if(!A)" `* z  o* n' f
    {. {- e: u4 F3 y7 ~
        X = exp2;. [' j6 @1 z# Y
    }
/ t2 z" l% k3 o    (5)除法(取模)操作2 K4 o  N2 T" J, r2 m
    一般DSP中不支持除法,除法操作是通过仿真的方式来进行实现,有两种,分为低精度和高精度,但都需要相大多的周期。, s! @+ B+ T; U; ~
    除数为2的N次方时可采用右移法。" j; U7 I$ Z3 M" [, F! @4 r
    如为提高性能,可采取查表的方式,这样会损失精度。
% S5 x+ x4 }2 A' f- _+ ?    隐藏的除法:
7 x6 y! N) O8 D+ b        for(i = start; i < finish; i += step)
, i! m' D& Y% }. N- `( l2 q; {        此时编译器会looper = (finish - start) / step 得到次数。
0 e, d7 |9 f' S6 l+ j$ y8 w    巧妙利用不等式法测:(不过可能会产生溢出,要小心使用)
$ Q/ [2 b, Q+ W) Z$ q        if(x / y > a / b)
9 |' L& C, Z9 F: H6 W' ?9 v        可转换为:
3 J: x. O( W! m" M: N( L- _. n* t, W+ ]+ m        if(x * b  > a * y)
1 `. b- }8 I  ?; @! U# n( A* E    (6)数据类型! n/ Z- N! r4 S3 ]( }
    对于定点DSP而言,对于浮点的操作是用仿真的方式实现的,会消耗很多周期,所以在定点DSP上对于浮点数一般是做定点化的处理,常用的方法我举一个例子:2.5 * a,其实可以转换成80 * a >> 5,不过在定点化时需要注意防溢出。8 c+ J8 w  p1 Z5 H, L- l# j
    对于64位数据,也是用仿真的方式实现的,会消耗很多周期。(一般最大仅支持32位数据)
5 I* G5 V% c5 p$ }" o* b    做数字信号处理操作时,如FFT,16bit的操作是比较合适的。
4 t: b  s% E! {- j1 A) y    要做控制类,条件跳转时,32bit的操作是比较合适的。
# S% B1 h: e& y" k    如你的DSP的MAC是16位的,做乘法时,尽量定义成16bit数据。
3 u0 R, }; D! N% G4 V6 [    (7)Memory分配
3 h7 T5 I  j% e1 P2 D4 V1 @    将运算比较频繁的数据和程序段放入片内Memory,开启cache。- o$ N4 Q  a9 T+ N0 k* D/ {
    如DSP能对SDRAM的不同4个bank可以同时访问,此时你可以将需要同时运算的数据放入不同的bank. Y& e0 l: s3 q3 e7 h9 `; B% |. ^
    (8)开启仿真软件的编译优化选项9 f' h# a3 x* o  i6 M) c% H. a
    在菜单相应的地方勾上即可,但值得注意时,开启自动编译优化选项后,可能会使执行的结果发生变化,所以需要测试对比一下未开编译优化选项之前的执行结果,一般来说,这个很方便,比较常用。3 D$ M& \! @% `" d% @* {/ R# z$ z3 Z
    以上8种是我常用到的优化方法,当然基于C层面算法类的优化还有很多种,这个需要慢慢积累,总结一下,一般来说先对C层面进行结构上的优化(上面的1-6均属于),然后进行Memory分配,开启仿真软件的编译优化选项,将运算频繁的程序段用汇编实现,当然如果性能满足要求,就没必要利用汇编了。
3 l1 U1 f7 ~% ~1 L2 e' f4 V. T  六、总结7 `# S! C% \& Y' ?* F
  我认为学习DSP软件开发没有什么捷径,我花了大量的文字在“弄清DSP相关资源的来源及熟读手册”上,实际上是想说,懂得获取资源是很关键的,只有熟悉手册才能完全去使用你所要开发的DSP芯片,其次DSP的主要特点就是高性能,能做一些算法类的运算,所以DSP的优化是相当重要的,关于算法优化的方法有很多种,基本可分为C结构上的优化及利用DSP的特点来进行优化,优化的学习是日易积累的,所以就要多看看相关的资料了。! S0 k: Y. b9 O
  快速入门的步骤如下:. Y! A8 d0 j3 B
  准备一开发板,简单熟悉一下手册及仿真软件,对照着例程看手册,然后再改例程,看是否能按你的意愿去实现,最小系统和每个外设都熟悉一边,恭喜你,你入门了,待续。。。

该用户从未签到

2#
发表于 2016-5-16 13:51 | 只看该作者
楼主很用心啊!& K, c! G. A, }# k5 k4 n, l
感谢感谢!

该用户从未签到

4#
发表于 2016-6-2 15:28 | 只看该作者
谢谢O(∩_∩)O哈哈~谢谢O(∩_∩)O
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-6-10 12:39 , Processed in 0.093750 second(s), 23 queries , Gzip On.

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

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

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