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

DSP学习经验

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
大学毕业至今,做了三年的DSP开发,将稍许经验记录下来,分享一下。0 k1 d7 J" q' v0 {
  一、弄清DSP相关资源的来源及熟读手册
& T1 \3 Z/ H# g4 R! ~  一般主要来源于DSP芯片厂商的官方网站,虽然现在的DSP芯片厂商都提供了中文的官方网站浏览,但我建议还是上英文的网站,其一,有些资源在中文网站上没有(关于这点,我个人认为可能是中文这边的资源未及时上传),其二,一般资料很少有中文版,中文和英文版网站上下载的其实是同一个版本;再就是,要熟悉DSP芯片厂商的官方网站,开发时允分利用官方提供的资源及支持能大大地提高开发效率;最后要注意的是,一般DSP芯片厂商会开放一个技术交流论坛,里面的管理员一般都是DSP芯片厂商的开发工程师,可以以发贴的形式获取他们的技术支持。. B9 [0 w' S9 v% G
  还有一处资源的来源,就是跟DSP芯片厂商有合作的第三方公司(国内),这类公司跟DSP芯片厂商有很好的接触,一般相关的DSP芯片,他们都会先行做成教育开发板,这点当然主要用于教学,所以他们会有相关的中文资料及相应的demo程序,根据这点,可以很好的借鉴他们的经验及参考他们的资料及程序,其次,他们还会出售自制的仿真器,价格比原厂的会便宜,功能上肯定没有原厂出售的仿真器全面,但足以应对基本的项目开发。; |& X+ W! Q! `% Q$ T: H+ L
  第三处仅供参照,占据国内市场最大的两家DSP厂商TI和ADI在中国都开设的相应级别的DSP培训课程,但费用昂贵,一般都是公司派遣前去学习。, f) x% \; A* a4 G( {: a3 F1 Q
  资源主要包含:
# y, X0 Z7 g7 P) h, K% m    Datasheet(数据手册,主要大体介绍一下DSP芯片的功能,内部结构及外设,软件及硬件一些简单介绍,主要作用是可以很快速的了解这款DSP)
9 G! _6 U- t; t' u: B* c2 D9 I    Software Tool Manuals(这个手册主要介绍的DSP时钟、存储器、电源管理等等及所有外设的使用及注意事项,其实就是寄存器的配置,完全可以称之为DSP使用手册)/ P6 Q- ~4 a+ o0 [6 u4 q6 l  `, W3 ]
    Hardware Tool Manuals(这个手册主要是官方提供的原理图PCB的绘制)、Program Manuals(这个手册主要介绍编译器及内置C库的使用,汇编指令的使用及汇编语法的介绍,官方提供的仿真软件的使用)
+ _1 B! E. L2 Z( Z/ @     Engineer to Engineer Note(工程师笔记,这个其实就是DSP芯片自己的工程师在开发这款DSP时所写的笔记,如果你有某个地方未明白,看相应的工程师笔记是最合适的)
" e  h- ?9 B. F0 A    Program Examples(主要是针对DSP不同的外设,官方提供的程序例子,包含C及汇编)
+ H) c3 J1 Z2 \7 K& u  二、官方仿真软件及仿真器的使用(如不使用,可暂时跳过,因为有些DSP可基于开源的操作系统进行开发,例如uClinux)# [$ x  A5 m8 s
  使用仿真软件的方法其实很简单,一般这种软件都设计成类似VC这种,你逐个去试每个菜单下的选项,此时你如配合Examples去使用,更能加深理解,不过我建议,做DSP软件开发,先简单看一下Datasheet、Software Tool Manuals和Program Manuals这三个文档再开始熟悉仿真软件的使用,当然在你熟悉时,肯定需要去不停的再去看这些文档的。仿真器的使用并没有什么需要注意的,一般的仿真器都做了仿呆处理,所以不会插反,仿真器一般都是配合仿真软件使用。(有一点要提醒的是一般DSP开发是基于C语言,如果不会C语言,请先学习C语言)
: R7 z- M: J  C9 h  三、DSP最小系统的配置% B6 Y5 t  Z, d" ]# x+ q3 p! @1 m
  这部分就正式开始使用DSP了,最小系统主要指DSP的时钟及存储器系统,这时你需要对照着Software Tool Manualsh去仔细看里面的介绍及相关寄存器的配置,结合Examples及Engineer to Engineer Note,如果程序写完后,测试时钟其实很简单,用示波器直接去测量,看测量出来的时钟是否是你配置的那个数,紧接着就是测试存储器,这个测试必须写一段简单的小程序,其实主要就是测试数据总线是否能正常工作,如果在配置最小系统时出现问题,一般问题有二,一是寄存器未正确配置,解决方法是结合Examples及Engineer to Engineer Note仔细看手册,看例程,二是可能开发板上的硬件线路出了问题,解决方法是结合原理图,看线路上是否存在短路的问题,DSP工作电压是否正常等,这步可和硬件工程师一起去查。
0 C5 `; m6 P7 E% x% m, M0 V  四、DSP外设的使用' z, }0 K/ v9 F% b
  其实这部分和配置最小系统一样,只不过某些外设上可能连接了其它的芯片,不同的功能连接的芯片不一样,此时你需要去看这些芯片的资料,然后开始编写代码,然后再测试,测试方法根据不同的功能也会不同,不过DSP开发最常用的就是使用示波器,如有音视频方面的,可借助摄像头,显示屏等等之类的;如中间开发遇到问题,方法还是一样,结合Examples及Engineer to Engineer Note仔细看手册,看例程,有一点要注意,千万不能怀疑不能实现,要对自己有信心。
! U2 F3 E( W- e- q& K5 K  五、DSP优化# o4 w5 D# e$ J2 e4 [: J  [
  其实到这一步,你已经完全可以使用DSP了,接下来,你需要加深熟悉DSP的整个内部结构,主要包含有几个多少位的MAC,有几个多少位的ALU,有几个多少位的数据寄存器等等,还有外部数据总线上连接了哪些外设,内部数据总线是怎么连接的,并且这些数据总线是多少位,这些在Datasheet会有一张很清楚的DSP结构图,还有DSP的整个Memory Map是怎样的,片上有多少Data Memory,有多少Program Memory等等,了解这些其实就是让你知道DSP的运算性能到底可以达到多少,哪些外设会通过外部数据总线传输数据,DSP内部的寄存器是怎么传输数据的,通过这些可以帮助你解决你在开发中遇到的问题,不过最主要的是帮助你对已经编写完成的代码进行优化,我个人认为的优化方法有以下几种:
) P7 ^; t1 }) R: J- q  1、一般编写代码首先是用C,基于C层面优化的方法,我如下举例说几种:/ }% Z9 C+ E) P" Y/ c
    (1)优化循环8 G9 {. b( h  H6 `( {9 O. H, h$ ]
    for(i = 0;i < max;i ++)# w5 G. Q" S) J$ `; V: O
     {
2 R* O6 f, }1 t& R  {        for(j = 0; j < max; j ++)+ s) o6 w) H* D5 j' c/ r$ e+ ^
        {+ ?! o- @0 m9 I" n8 L
            float sum = 0.0;
9 H& H- B) D5 J2 j) l' O            for(k = 0; k < max; k ++)
/ [5 m8 T) U# B/ g7 ^2 x- ?2 h            {/ ^2 ]" _1 T0 j; k' c
                sum += input[i * max + k] * input[j * max + k];9 O1 Y  I5 h( m; Q% O6 ]; z
            }$ F* |& e0 h2 T7 \+ W, ]
            cover[i * max + j] = sum / max;
+ Z/ w# }% ]7 O- G7 q3 F' y3 S        }# p7 V% V7 E- k
    }
7 F, g, O% X; Z( L  `" f7 H8 e, Y    实例,如input[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},得出的cover如下:
, T1 h! U; j% P- R; L     7    17   27   37
" y5 O: _+ g7 Z: F5 ?     17  43   69   95) o/ R  R: E9 i* j9 W5 Y+ h
     27  69  111  153
5 o# W7 l& p! N3 R3 e     37  95  153  211+ a! W  U: m9 s) I3 |% {/ q
    图示:5 K: l0 F  N3 i# o% B$ h8 z
    
7 Y1 f; K/ V* I    原理:只需要得到左上角或右上角即可,然后半个矩阵赋值给另半个矩阵即可得到整个矩阵。! g+ X4 u/ j3 I
    算法优化后:( i7 Z3 z7 F1 P; e6 D
    for(i = 0; i < max; i ++)* v0 }) j; G! z+ C2 Z4 t- S
    {: A* C" E8 w  l3 @3 P6 l" W
        for(j = i; j < max; j ++)                  // 减少一半循环8 [! }, ~  l8 W- O
        {0 X2 f  n4 C' A) F, D7 m( h
            float sum = 0.0;: o' }8 Z1 a) o. f8 ]: c4 W
            for(k = 0; k < max; k ++)
! Z- \9 m7 g4 V$ z5 @            {5 b% e6 u# M6 @: U: J: O
                sum += input[i * max + k] * input[j * max + k];8 T" D$ w% b5 D2 I
            }& A7 _& T' ^% r; i  b' y
            cover[i * max + j] = sum / max;
6 Q. c. g1 S" `0 \4 N            if(i != j)                    // 可加可不加,消除中线上的重复赋值; h& j9 z- q8 k3 l$ m
            {
/ K+ W" {* u  W$ W, I                cover[j *max + i] = sum / max;       // 赋值给另半个矩阵
$ |3 D  ]* N- K  ^% A) C% e            }! v/ U3 n0 M. m5 e+ q7 R  f
        }
% s! ^  w9 D; ^( H8 ?) A    }
2 S' Y& k: K! N& d) w$ }$ w) z8 q  A: }    (2)条件跳转(使用条件跳转会在流水线中浪费更多的周期)- @+ Y+ T. r6 O- {) P
    k = k -1;: G3 t! e, d6 r8 k. R  q1 }
    if(k < -1): u. R) h# \; i
    {
- F' x- }9 F6 G4 C0 w1 }        k = -1;+ b  H2 }' U& G+ O, L7 y! A* v/ ?+ D
    }
. l7 e0 ?6 x  ?- |& K    原理:C语言中的max函数在编译的过程中实际上实现的是DSP中的MAX指令。
# j- Z3 g4 c0 I    优化后:4 ]! z6 A" [+ [( @( m1 N* y  C9 ~
    k = max(k-1, -1);
9 M& A8 n6 N0 ^    转换成汇编后:
4 V# K  ^# W$ i, q8 F    R0 += -1;    // R0 == k;
8 j5 \. |7 _) }: b4 t    R1 = -1;
/ F% m3 E* g+ ?' i: K% O. W2 t    R0 = MAX(R0, R1);
' t1 f: n+ _& b6 `0 \8 K! J% _; s    (3)for循环中的条件跳转
8 x( s% M8 f  ~8 @3 g* P    for+ k+ W0 a1 {3 q( b
    {
7 I, p3 T2 W- S& w/ \        if{...}else{...}
  O$ J- d5 Q4 i# a- ^# g% }    }
8 ~2 d4 i2 u7 a0 a    原理:减少频繁的条件跳转,当然并不是所有的情况都可以这样做。0 p; s8 `, b  b# k9 t
    优化后:: b5 c! b3 f. ]- D( J7 G
    if7 M: y7 I9 y) G# l: F! d, [, X
    {, c& d  w/ x! L
        for{...}6 {9 b; c6 L# K' W1 y; u# ]
    }
! V4 G2 m  {- u" ?) L4 c! d    else0 l0 C  x/ k0 V4 e- W5 |0 V' e
    {
+ f. _1 R, y8 C8 m* ]0 |        for{...}" H& w& C. i2 l) K
    }/ o& t, n$ E$ `
    (4)使用断言指令来避免条件跳转
! z# G" [' {9 J  Z! p    if(A)
- X6 z8 B9 ~4 I    {
3 G  @: `) @4 |6 B        X = exp1;9 W3 H: u! Y1 w: P
     }% M. f$ b' @( x- y
    else' C1 J/ ^% s# i% C
    {- u  J. L( u: Q! A9 {
        X = exp2;
  k8 S! `7 {  O; e9 H% ~3 T    }    
: M: f! O+ R, J2 i* G. @/ i    原理:使用断言指令IF(CC) REG = REG,只会消耗一个周期。' g) S$ c  r9 g/ j/ d
    优化后:
3 a! `: ^' b( Y7 L; M' n. N$ R1 w    X = exp1;6 r/ m( O( J( I6 ]
    if(!A)
* E, R' u* k* F& }: |8 R+ y$ H$ `    {
. `) K" B7 i; Y        X = exp2;
2 Z9 Y2 _* r  Q! p, K    }1 u! w9 I1 H6 O8 g# ?
    (5)除法(取模)操作
$ h2 _. w6 C( j    一般DSP中不支持除法,除法操作是通过仿真的方式来进行实现,有两种,分为低精度和高精度,但都需要相大多的周期。
+ D% _4 y9 }' M0 V. C    除数为2的N次方时可采用右移法。# E' d' |- U5 j) o
    如为提高性能,可采取查表的方式,这样会损失精度。
2 r* ]+ H1 D) {/ {! z    隐藏的除法:7 Y0 ?9 J5 p% Y$ w1 M
        for(i = start; i < finish; i += step)- ]) v$ D3 s9 }" u* h# U; }3 Z
        此时编译器会looper = (finish - start) / step 得到次数。
8 |) N% f0 w% d4 q5 f    巧妙利用不等式法测:(不过可能会产生溢出,要小心使用)
; E" B+ z. |% P5 P7 O( ~        if(x / y > a / b)
7 |9 D0 X0 s( |* |6 T; @0 A" _, m        可转换为:
$ F3 I$ p( r# T; |8 E# i4 @        if(x * b  > a * y)
( K! l. k, A( r* @9 T7 {    (6)数据类型
8 R' C* v' y. n) d: r. i    对于定点DSP而言,对于浮点的操作是用仿真的方式实现的,会消耗很多周期,所以在定点DSP上对于浮点数一般是做定点化的处理,常用的方法我举一个例子:2.5 * a,其实可以转换成80 * a >> 5,不过在定点化时需要注意防溢出。4 j; K/ P) \$ }* |3 e, w5 z; r+ v' W% G/ ~
    对于64位数据,也是用仿真的方式实现的,会消耗很多周期。(一般最大仅支持32位数据)# @9 K3 {0 l5 o7 c
    做数字信号处理操作时,如FFT,16bit的操作是比较合适的。$ }9 E! L6 r" e) P! j0 t2 {  E1 U
    要做控制类,条件跳转时,32bit的操作是比较合适的。+ p/ d: P0 K( A
    如你的DSP的MAC是16位的,做乘法时,尽量定义成16bit数据。
) @+ b6 _4 P7 V, y! L+ P) A    (7)Memory分配
8 J# v3 y: k7 c- S% U1 h    将运算比较频繁的数据和程序段放入片内Memory,开启cache。
9 e3 ~* ]/ P: j8 f7 Z+ Z- C    如DSP能对SDRAM的不同4个bank可以同时访问,此时你可以将需要同时运算的数据放入不同的bank
6 A- E7 h1 X1 u2 a, n    (8)开启仿真软件的编译优化选项
  n5 T: }9 V8 `- T& q& c" V9 |    在菜单相应的地方勾上即可,但值得注意时,开启自动编译优化选项后,可能会使执行的结果发生变化,所以需要测试对比一下未开编译优化选项之前的执行结果,一般来说,这个很方便,比较常用。
# G0 U8 J) K) U; F4 K8 `( o, S    以上8种是我常用到的优化方法,当然基于C层面算法类的优化还有很多种,这个需要慢慢积累,总结一下,一般来说先对C层面进行结构上的优化(上面的1-6均属于),然后进行Memory分配,开启仿真软件的编译优化选项,将运算频繁的程序段用汇编实现,当然如果性能满足要求,就没必要利用汇编了。
0 W: n" ^5 s- m" J! c  六、总结) |! ]' H9 U' j( @3 n! j
  我认为学习DSP软件开发没有什么捷径,我花了大量的文字在“弄清DSP相关资源的来源及熟读手册”上,实际上是想说,懂得获取资源是很关键的,只有熟悉手册才能完全去使用你所要开发的DSP芯片,其次DSP的主要特点就是高性能,能做一些算法类的运算,所以DSP的优化是相当重要的,关于算法优化的方法有很多种,基本可分为C结构上的优化及利用DSP的特点来进行优化,优化的学习是日易积累的,所以就要多看看相关的资料了。1 J1 [) C3 `3 M" c( B
  快速入门的步骤如下:0 Y3 Z2 h- A- o' W
  准备一开发板,简单熟悉一下手册及仿真软件,对照着例程看手册,然后再改例程,看是否能按你的意愿去实现,最小系统和每个外设都熟悉一边,恭喜你,你入门了,待续。。。

该用户从未签到

2#
发表于 2016-5-16 13:51 | 只看该作者
楼主很用心啊!
4 z9 S1 L( x7 M/ S6 h+ F, G& G感谢感谢!

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

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

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

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

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