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

DSP学习经验

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
大学毕业至今,做了三年的DSP开发,将稍许经验记录下来,分享一下。
, z7 b/ b% X! `1 L$ l) j  一、弄清DSP相关资源的来源及熟读手册
4 b% S1 q  ?4 B4 v. F9 \2 U  一般主要来源于DSP芯片厂商的官方网站,虽然现在的DSP芯片厂商都提供了中文的官方网站浏览,但我建议还是上英文的网站,其一,有些资源在中文网站上没有(关于这点,我个人认为可能是中文这边的资源未及时上传),其二,一般资料很少有中文版,中文和英文版网站上下载的其实是同一个版本;再就是,要熟悉DSP芯片厂商的官方网站,开发时允分利用官方提供的资源及支持能大大地提高开发效率;最后要注意的是,一般DSP芯片厂商会开放一个技术交流论坛,里面的管理员一般都是DSP芯片厂商的开发工程师,可以以发贴的形式获取他们的技术支持。0 J1 Y6 v: C* {3 K2 U
  还有一处资源的来源,就是跟DSP芯片厂商有合作的第三方公司(国内),这类公司跟DSP芯片厂商有很好的接触,一般相关的DSP芯片,他们都会先行做成教育开发板,这点当然主要用于教学,所以他们会有相关的中文资料及相应的demo程序,根据这点,可以很好的借鉴他们的经验及参考他们的资料及程序,其次,他们还会出售自制的仿真器,价格比原厂的会便宜,功能上肯定没有原厂出售的仿真器全面,但足以应对基本的项目开发。0 Q1 a" S8 ?, ]4 q8 [
  第三处仅供参照,占据国内市场最大的两家DSP厂商TI和ADI在中国都开设的相应级别的DSP培训课程,但费用昂贵,一般都是公司派遣前去学习。3 C. r; F: ?: V' X9 m9 q
  资源主要包含:
1 n% l! s6 }, F9 a1 }' [. V  E8 V2 d    Datasheet(数据手册,主要大体介绍一下DSP芯片的功能,内部结构及外设,软件及硬件一些简单介绍,主要作用是可以很快速的了解这款DSP)7 x# t* c; M# j* S( N; T+ `
    Software Tool Manuals(这个手册主要介绍的DSP时钟、存储器、电源管理等等及所有外设的使用及注意事项,其实就是寄存器的配置,完全可以称之为DSP使用手册)
$ ~8 e/ G. @: G: Y  N( h' l    Hardware Tool Manuals(这个手册主要是官方提供的原理图PCB的绘制)、Program Manuals(这个手册主要介绍编译器及内置C库的使用,汇编指令的使用及汇编语法的介绍,官方提供的仿真软件的使用)
* N: c2 b& }  G/ Z     Engineer to Engineer Note(工程师笔记,这个其实就是DSP芯片自己的工程师在开发这款DSP时所写的笔记,如果你有某个地方未明白,看相应的工程师笔记是最合适的)
' {% W* R3 x& n6 J    Program Examples(主要是针对DSP不同的外设,官方提供的程序例子,包含C及汇编); J8 p0 {; ?, A# q* t
  二、官方仿真软件及仿真器的使用(如不使用,可暂时跳过,因为有些DSP可基于开源的操作系统进行开发,例如uClinux)
: g: s: {$ k: }3 G' `  使用仿真软件的方法其实很简单,一般这种软件都设计成类似VC这种,你逐个去试每个菜单下的选项,此时你如配合Examples去使用,更能加深理解,不过我建议,做DSP软件开发,先简单看一下Datasheet、Software Tool Manuals和Program Manuals这三个文档再开始熟悉仿真软件的使用,当然在你熟悉时,肯定需要去不停的再去看这些文档的。仿真器的使用并没有什么需要注意的,一般的仿真器都做了仿呆处理,所以不会插反,仿真器一般都是配合仿真软件使用。(有一点要提醒的是一般DSP开发是基于C语言,如果不会C语言,请先学习C语言)! X& b* S, o# ]! \& x
  三、DSP最小系统的配置
+ i+ }) R4 |: {0 w( F6 E0 Z. ~  这部分就正式开始使用DSP了,最小系统主要指DSP的时钟及存储器系统,这时你需要对照着Software Tool Manualsh去仔细看里面的介绍及相关寄存器的配置,结合Examples及Engineer to Engineer Note,如果程序写完后,测试时钟其实很简单,用示波器直接去测量,看测量出来的时钟是否是你配置的那个数,紧接着就是测试存储器,这个测试必须写一段简单的小程序,其实主要就是测试数据总线是否能正常工作,如果在配置最小系统时出现问题,一般问题有二,一是寄存器未正确配置,解决方法是结合Examples及Engineer to Engineer Note仔细看手册,看例程,二是可能开发板上的硬件线路出了问题,解决方法是结合原理图,看线路上是否存在短路的问题,DSP工作电压是否正常等,这步可和硬件工程师一起去查。
4 Z: Q9 P# x; P6 I. b/ H! W  四、DSP外设的使用& r* U" a* w' ]
  其实这部分和配置最小系统一样,只不过某些外设上可能连接了其它的芯片,不同的功能连接的芯片不一样,此时你需要去看这些芯片的资料,然后开始编写代码,然后再测试,测试方法根据不同的功能也会不同,不过DSP开发最常用的就是使用示波器,如有音视频方面的,可借助摄像头,显示屏等等之类的;如中间开发遇到问题,方法还是一样,结合Examples及Engineer to Engineer Note仔细看手册,看例程,有一点要注意,千万不能怀疑不能实现,要对自己有信心。! Y! Z* c2 R9 J$ E7 j: t9 g4 t
  五、DSP优化- L6 R) v7 a, ]
  其实到这一步,你已经完全可以使用DSP了,接下来,你需要加深熟悉DSP的整个内部结构,主要包含有几个多少位的MAC,有几个多少位的ALU,有几个多少位的数据寄存器等等,还有外部数据总线上连接了哪些外设,内部数据总线是怎么连接的,并且这些数据总线是多少位,这些在Datasheet会有一张很清楚的DSP结构图,还有DSP的整个Memory Map是怎样的,片上有多少Data Memory,有多少Program Memory等等,了解这些其实就是让你知道DSP的运算性能到底可以达到多少,哪些外设会通过外部数据总线传输数据,DSP内部的寄存器是怎么传输数据的,通过这些可以帮助你解决你在开发中遇到的问题,不过最主要的是帮助你对已经编写完成的代码进行优化,我个人认为的优化方法有以下几种:! Y& [# }+ P3 s6 L( W3 I
  1、一般编写代码首先是用C,基于C层面优化的方法,我如下举例说几种:
( Q  {+ v$ m. t8 b+ ~: G% d$ I    (1)优化循环
/ B$ B, n: |+ J6 r: S, m! n" Q8 A    for(i = 0;i < max;i ++)7 E5 B% G- h5 I) Y
     {
3 h5 h7 D  l! f! f- |        for(j = 0; j < max; j ++)
- X' J( ~% v1 r) i/ Z        {
2 V: \* o% M' }# V) i$ g4 b- E            float sum = 0.0;' J( o0 ]* W. g0 x
            for(k = 0; k < max; k ++)1 k' J+ [/ Q) C( U/ A# K
            {% \, C/ J# `+ t+ u- Y' z, c
                sum += input[i * max + k] * input[j * max + k];
! m0 H! F  c& Z            }
% [, ^( f+ F9 l1 Q& G6 x; [+ D            cover[i * max + j] = sum / max;
8 J" h' n# {+ l$ s/ D% `: V        }" ?+ m1 G6 i9 E6 W; ]
    }# w7 ^. [  I# C. W/ K/ r! M
    实例,如input[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},得出的cover如下:: {$ x4 v# D. O9 g
     7    17   27   37. t( }4 n9 H6 Y1 O
     17  43   69   95; s; E5 o8 v% b& X. `
     27  69  111  1536 v! r5 A  Y% }' }7 u/ q$ m4 |( f
     37  95  153  211
4 D& D5 l7 Z3 Z' y1 b5 |4 n    图示:* c' z4 k7 Y; c3 X+ @& c3 o
    / _: m( A+ v4 m3 o
    原理:只需要得到左上角或右上角即可,然后半个矩阵赋值给另半个矩阵即可得到整个矩阵。  r) i7 N: x+ `0 ^+ p& E0 R
    算法优化后:
* W1 Q- |( A1 X0 z! z8 L3 a1 }9 |    for(i = 0; i < max; i ++)
% m- F: @, i" F" f    {
+ m8 q% h# P6 t3 M7 z2 N        for(j = i; j < max; j ++)                  // 减少一半循环
! ?# u, x1 v* Z        {
! p* v% g6 s! l& P% Z! W, L" }) k            float sum = 0.0;
3 j' J$ f) K8 ]2 C3 ^9 h" W' V            for(k = 0; k < max; k ++)& A3 K, r% p6 i7 W
            {9 Z6 Z3 V% x9 {+ E
                sum += input[i * max + k] * input[j * max + k];9 |& {2 O9 ^$ z4 {
            }, N- s6 {$ i4 W
            cover[i * max + j] = sum / max;* S! K  N6 f) w$ g% _
            if(i != j)                    // 可加可不加,消除中线上的重复赋值6 n( Q4 @, X# z
            {
" I% S5 {1 r4 Q2 ]                cover[j *max + i] = sum / max;       // 赋值给另半个矩阵2 Y: h, v8 w0 b; {) _+ C
            }4 p+ M1 \# q9 H# D0 w( F$ w
        }
$ l/ R" i. q1 @+ E& r  [    }
1 ?) d( |+ k% ^: @) i    (2)条件跳转(使用条件跳转会在流水线中浪费更多的周期)5 Q* X% T( K. G+ p1 Z% l' I
    k = k -1;
. N( D+ h' T5 P, F: ]5 G1 a    if(k < -1)
3 k% `  ]) `, P9 Z, f1 A9 V- ~9 W    {
; D" M6 h. W7 l; j4 t        k = -1;, V0 z/ S9 G0 k+ i
    }2 Z6 u7 \# D5 V1 w+ e5 i
    原理:C语言中的max函数在编译的过程中实际上实现的是DSP中的MAX指令。
2 l. V; s% P+ _* |& q" i2 Z    优化后:* P) g, \6 K+ m" a, z6 p. c
    k = max(k-1, -1);' p/ k1 H6 \3 {6 A
    转换成汇编后:
# `# ]( F2 z1 g6 u; @; G& @% d    R0 += -1;    // R0 == k;, k# L% |* s& X$ f( d
    R1 = -1;) k" Y; P$ U% l
    R0 = MAX(R0, R1);. O  L2 ]9 ?+ V" u7 k
    (3)for循环中的条件跳转4 i) B0 q+ T: ]  O5 c! i: ?
    for
+ O& H  R$ l0 q& g7 t    {: y: ~. }- D3 C& w
        if{...}else{...}9 H" d8 I) Z" V
    }
; ^2 i4 ]4 b$ ~7 q* q2 g    原理:减少频繁的条件跳转,当然并不是所有的情况都可以这样做。
& i% R) m" ]3 w# ~; ?$ j# K7 Q$ C    优化后:' s8 o: u7 s6 h5 n8 X# D
    if
- C" {3 w. j4 g; a) F    {
0 M- r/ O- r# v        for{...}
8 j1 j" J+ q3 f6 c1 o    }. g9 t! P  j/ h  G- V, [
    else
& J/ _9 v1 u1 O7 P) l7 n( K    {/ u  J; C4 z: R5 g* j: r0 X2 x
        for{...}
- c1 r! H1 U: M5 I    }; M) K- R8 |; g2 u5 `9 Y# z) C
    (4)使用断言指令来避免条件跳转
; z3 s: R! ~* W2 C    if(A): g1 U/ X4 L3 m7 ~' J9 R
    {
, N+ v( |' V3 W. B6 _9 L        X = exp1;
. D# }8 L3 p! ~+ z4 V4 ~$ X+ w     }
) e" c/ |& R9 \6 H    else! }; k" z2 ?6 T6 y$ B2 u
    {
+ E. s0 W8 t! s* [- l# T) v, w& O) r        X = exp2;
! D/ f/ u, R, z1 |0 \    }    
! v* \7 F3 g# t0 y    原理:使用断言指令IF(CC) REG = REG,只会消耗一个周期。. x: W" ^* S* @
    优化后:
6 ^! x  `6 c7 L/ ~* U) V  T    X = exp1;
* q8 Z! x  T" m- k    if(!A)
1 _, ^; W, K' [* i% i' T' J    {/ k" ^5 s# t5 c9 `( P  B
        X = exp2;  q* \1 F, |4 S' [5 }& x! w/ o4 ~
    }
, ]# ~6 j$ B6 [5 T6 R    (5)除法(取模)操作
  Q' L. x$ l; G" y( v/ E    一般DSP中不支持除法,除法操作是通过仿真的方式来进行实现,有两种,分为低精度和高精度,但都需要相大多的周期。- ~# f2 P- v( q3 Q$ g
    除数为2的N次方时可采用右移法。+ u8 \; _: I) D- y- J+ z- a" V3 e
    如为提高性能,可采取查表的方式,这样会损失精度。
9 C3 J/ c) r% V/ @    隐藏的除法:$ L6 _* g0 O1 N0 I2 W
        for(i = start; i < finish; i += step)* a- Q/ F# D# G
        此时编译器会looper = (finish - start) / step 得到次数。7 E/ _# k7 i1 r; ?1 ~8 |
    巧妙利用不等式法测:(不过可能会产生溢出,要小心使用)
" h$ K2 `' n; r/ N3 f' ^        if(x / y > a / b)
: M$ w, u, W+ N0 m; S4 Q: S7 `        可转换为:
, v5 y/ x0 l2 U( D7 Q        if(x * b  > a * y)- `' t2 {" @. ^6 L+ ^9 x6 }: `  V/ I
    (6)数据类型; a: U5 @0 O8 O2 B
    对于定点DSP而言,对于浮点的操作是用仿真的方式实现的,会消耗很多周期,所以在定点DSP上对于浮点数一般是做定点化的处理,常用的方法我举一个例子:2.5 * a,其实可以转换成80 * a >> 5,不过在定点化时需要注意防溢出。
8 F9 [2 a' `5 M+ N    对于64位数据,也是用仿真的方式实现的,会消耗很多周期。(一般最大仅支持32位数据)
$ b  f/ h4 l- s8 U7 z( G; H    做数字信号处理操作时,如FFT,16bit的操作是比较合适的。
7 [4 N; k! b# d% P    要做控制类,条件跳转时,32bit的操作是比较合适的。3 l, R  O, C3 P0 R8 l
    如你的DSP的MAC是16位的,做乘法时,尽量定义成16bit数据。
5 `5 N% s9 v* o0 N9 [5 Y0 H6 [    (7)Memory分配5 S4 P9 p0 ?2 w; }! g; S1 R# v) d
    将运算比较频繁的数据和程序段放入片内Memory,开启cache。& ?2 D/ X5 F+ U. i  D/ z( Q
    如DSP能对SDRAM的不同4个bank可以同时访问,此时你可以将需要同时运算的数据放入不同的bank5 {' v% u. E; l+ ]& _  I2 V
    (8)开启仿真软件的编译优化选项% H: q; `' [/ U' K4 T. H
    在菜单相应的地方勾上即可,但值得注意时,开启自动编译优化选项后,可能会使执行的结果发生变化,所以需要测试对比一下未开编译优化选项之前的执行结果,一般来说,这个很方便,比较常用。7 l, L6 `" i% v! x
    以上8种是我常用到的优化方法,当然基于C层面算法类的优化还有很多种,这个需要慢慢积累,总结一下,一般来说先对C层面进行结构上的优化(上面的1-6均属于),然后进行Memory分配,开启仿真软件的编译优化选项,将运算频繁的程序段用汇编实现,当然如果性能满足要求,就没必要利用汇编了。
6 A% A; [# n6 {2 ~6 k- m  J  六、总结
7 ]  S( w0 i1 ?9 S( D1 j' K  我认为学习DSP软件开发没有什么捷径,我花了大量的文字在“弄清DSP相关资源的来源及熟读手册”上,实际上是想说,懂得获取资源是很关键的,只有熟悉手册才能完全去使用你所要开发的DSP芯片,其次DSP的主要特点就是高性能,能做一些算法类的运算,所以DSP的优化是相当重要的,关于算法优化的方法有很多种,基本可分为C结构上的优化及利用DSP的特点来进行优化,优化的学习是日易积累的,所以就要多看看相关的资料了。5 D  P$ E. ?' X
  快速入门的步骤如下:
  s( {" ^, h/ h' O  准备一开发板,简单熟悉一下手册及仿真软件,对照着例程看手册,然后再改例程,看是否能按你的意愿去实现,最小系统和每个外设都熟悉一边,恭喜你,你入门了,待续。。。

该用户从未签到

2#
发表于 2016-5-16 13:51 | 只看该作者
楼主很用心啊!
  t" R! w( v% C# v- q  A感谢感谢!

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-9-6 18:35 , Processed in 0.140625 second(s), 23 queries , Gzip On.

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

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

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