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

DSP学习经验

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
大学毕业至今,做了三年的DSP开发,将稍许经验记录下来,分享一下。) u9 u2 C: m- y3 u8 F# I8 D
  一、弄清DSP相关资源的来源及熟读手册5 t# \6 M; ]/ K" b
  一般主要来源于DSP芯片厂商的官方网站,虽然现在的DSP芯片厂商都提供了中文的官方网站浏览,但我建议还是上英文的网站,其一,有些资源在中文网站上没有(关于这点,我个人认为可能是中文这边的资源未及时上传),其二,一般资料很少有中文版,中文和英文版网站上下载的其实是同一个版本;再就是,要熟悉DSP芯片厂商的官方网站,开发时允分利用官方提供的资源及支持能大大地提高开发效率;最后要注意的是,一般DSP芯片厂商会开放一个技术交流论坛,里面的管理员一般都是DSP芯片厂商的开发工程师,可以以发贴的形式获取他们的技术支持。
  _/ n* S8 x. d3 N  h  还有一处资源的来源,就是跟DSP芯片厂商有合作的第三方公司(国内),这类公司跟DSP芯片厂商有很好的接触,一般相关的DSP芯片,他们都会先行做成教育开发板,这点当然主要用于教学,所以他们会有相关的中文资料及相应的demo程序,根据这点,可以很好的借鉴他们的经验及参考他们的资料及程序,其次,他们还会出售自制的仿真器,价格比原厂的会便宜,功能上肯定没有原厂出售的仿真器全面,但足以应对基本的项目开发。, c) _8 Y# q) |9 V& S
  第三处仅供参照,占据国内市场最大的两家DSP厂商TI和ADI在中国都开设的相应级别的DSP培训课程,但费用昂贵,一般都是公司派遣前去学习。
. A& H& E) j* f  Y/ ]  资源主要包含:, w6 _; E. r  |$ C& F( N: p
    Datasheet(数据手册,主要大体介绍一下DSP芯片的功能,内部结构及外设,软件及硬件一些简单介绍,主要作用是可以很快速的了解这款DSP). k6 v& E/ N- m5 H( D; i2 g- C
    Software Tool Manuals(这个手册主要介绍的DSP时钟、存储器、电源管理等等及所有外设的使用及注意事项,其实就是寄存器的配置,完全可以称之为DSP使用手册)  y4 t' w3 w5 v) J, k$ U% G
    Hardware Tool Manuals(这个手册主要是官方提供的原理图PCB的绘制)、Program Manuals(这个手册主要介绍编译器及内置C库的使用,汇编指令的使用及汇编语法的介绍,官方提供的仿真软件的使用)+ ~, M* J" `8 p. H- u! F6 z2 W
     Engineer to Engineer Note(工程师笔记,这个其实就是DSP芯片自己的工程师在开发这款DSP时所写的笔记,如果你有某个地方未明白,看相应的工程师笔记是最合适的)
* T6 M& |  O- {5 F6 Z7 \    Program Examples(主要是针对DSP不同的外设,官方提供的程序例子,包含C及汇编)( x! a6 Q. z' }9 E" N5 E
  二、官方仿真软件及仿真器的使用(如不使用,可暂时跳过,因为有些DSP可基于开源的操作系统进行开发,例如uClinux)1 {2 i' |! a/ }" A9 Z
  使用仿真软件的方法其实很简单,一般这种软件都设计成类似VC这种,你逐个去试每个菜单下的选项,此时你如配合Examples去使用,更能加深理解,不过我建议,做DSP软件开发,先简单看一下Datasheet、Software Tool Manuals和Program Manuals这三个文档再开始熟悉仿真软件的使用,当然在你熟悉时,肯定需要去不停的再去看这些文档的。仿真器的使用并没有什么需要注意的,一般的仿真器都做了仿呆处理,所以不会插反,仿真器一般都是配合仿真软件使用。(有一点要提醒的是一般DSP开发是基于C语言,如果不会C语言,请先学习C语言)! G  {& J, W# R) N$ t3 G0 G
  三、DSP最小系统的配置' D8 q. D9 x8 P# m3 f7 Q# {4 P9 n
  这部分就正式开始使用DSP了,最小系统主要指DSP的时钟及存储器系统,这时你需要对照着Software Tool Manualsh去仔细看里面的介绍及相关寄存器的配置,结合Examples及Engineer to Engineer Note,如果程序写完后,测试时钟其实很简单,用示波器直接去测量,看测量出来的时钟是否是你配置的那个数,紧接着就是测试存储器,这个测试必须写一段简单的小程序,其实主要就是测试数据总线是否能正常工作,如果在配置最小系统时出现问题,一般问题有二,一是寄存器未正确配置,解决方法是结合Examples及Engineer to Engineer Note仔细看手册,看例程,二是可能开发板上的硬件线路出了问题,解决方法是结合原理图,看线路上是否存在短路的问题,DSP工作电压是否正常等,这步可和硬件工程师一起去查。
+ O* E" ~& I" k- C! E3 r  四、DSP外设的使用% `, v. P) Z* u" i( t& a% `" R
  其实这部分和配置最小系统一样,只不过某些外设上可能连接了其它的芯片,不同的功能连接的芯片不一样,此时你需要去看这些芯片的资料,然后开始编写代码,然后再测试,测试方法根据不同的功能也会不同,不过DSP开发最常用的就是使用示波器,如有音视频方面的,可借助摄像头,显示屏等等之类的;如中间开发遇到问题,方法还是一样,结合Examples及Engineer to Engineer Note仔细看手册,看例程,有一点要注意,千万不能怀疑不能实现,要对自己有信心。' y& |  O1 j3 G
  五、DSP优化5 k0 O5 u# P8 k% B
  其实到这一步,你已经完全可以使用DSP了,接下来,你需要加深熟悉DSP的整个内部结构,主要包含有几个多少位的MAC,有几个多少位的ALU,有几个多少位的数据寄存器等等,还有外部数据总线上连接了哪些外设,内部数据总线是怎么连接的,并且这些数据总线是多少位,这些在Datasheet会有一张很清楚的DSP结构图,还有DSP的整个Memory Map是怎样的,片上有多少Data Memory,有多少Program Memory等等,了解这些其实就是让你知道DSP的运算性能到底可以达到多少,哪些外设会通过外部数据总线传输数据,DSP内部的寄存器是怎么传输数据的,通过这些可以帮助你解决你在开发中遇到的问题,不过最主要的是帮助你对已经编写完成的代码进行优化,我个人认为的优化方法有以下几种:
7 G7 n% Y% ?: r, z  1、一般编写代码首先是用C,基于C层面优化的方法,我如下举例说几种:
* J) E/ ]6 A9 P9 n3 [6 k" ~    (1)优化循环4 u$ @1 _2 ?$ y. s" Z5 u- M
    for(i = 0;i < max;i ++)
! F* ^+ c4 C& V     {1 Z9 h/ V0 y2 b/ G$ W3 e( @
        for(j = 0; j < max; j ++)" q9 c3 O' \4 [# i5 @/ B
        {
6 w: |4 A7 w. {  H            float sum = 0.0;  e4 x/ P$ Q: T6 \8 ]) Z* \
            for(k = 0; k < max; k ++)7 o# i7 W8 v0 ]8 J6 I7 R
            {
. I; ~+ g" q1 K8 H                sum += input[i * max + k] * input[j * max + k];& q7 T2 Z: d% q3 h4 N
            }: Y2 {" E4 J! B8 M8 H( {' }
            cover[i * max + j] = sum / max;
% M: b0 p, {/ f$ X* H( t        }
' n, T7 W$ G9 j' k    }8 ?; Y  g! B+ {" U
    实例,如input[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},得出的cover如下:
- y% S/ [1 f5 U     7    17   27   37
! m' i- b9 b0 C     17  43   69   95
. Z. \* {: e, U% D4 v' P; p     27  69  111  153
, y+ T2 k& I( V3 H     37  95  153  211  p* v' n& u# ]& K! q
    图示:0 b( k2 Q. l4 w& x
    
! F: s+ A9 k$ W4 I    原理:只需要得到左上角或右上角即可,然后半个矩阵赋值给另半个矩阵即可得到整个矩阵。; P* I7 H/ x, R$ j% {# W
    算法优化后:% o; z. L% m: `6 q0 N
    for(i = 0; i < max; i ++)  e! o" g; o: o& c
    {4 d% x1 z" }2 u4 I7 {( a, W2 {. E
        for(j = i; j < max; j ++)                  // 减少一半循环
- K. z+ o( h* `! ^        {
) I2 s% g9 H) s" o- h5 n- `; U" l            float sum = 0.0;
- ]- C# a6 }0 l% _+ e            for(k = 0; k < max; k ++)1 o. x$ P* X1 ]7 I) i6 B
            {) ^- y% X9 F" o
                sum += input[i * max + k] * input[j * max + k];0 L# a6 J" p1 w3 A4 `9 d, \9 x6 g
            }" [  v" C8 R/ c8 T" p9 V6 r
            cover[i * max + j] = sum / max;
1 s! s5 f9 D* g; v; l2 q& M            if(i != j)                    // 可加可不加,消除中线上的重复赋值
- j, V" N5 Z) q9 N& f! d2 x" m+ C            {
4 u7 g/ L/ M5 ]* }                cover[j *max + i] = sum / max;       // 赋值给另半个矩阵$ @0 H. |% m# a. W1 B/ p
            }
% e) u+ E: @, D* C        }; \" @. |5 K0 [' d5 R9 P9 Y3 t* k
    }: {9 @8 `, e: c% d! @
    (2)条件跳转(使用条件跳转会在流水线中浪费更多的周期)+ h! d& z  x0 N
    k = k -1;
  @" z, w7 B+ K* d3 I    if(k < -1)  ^  }: W" y1 D  {& U1 }
    {8 Q+ o# Q9 V1 R9 n9 N( i
        k = -1;* ?- U3 b- M7 \) l. m$ n+ \
    }9 {4 g# w6 \& V9 |% F7 T% h# V
    原理:C语言中的max函数在编译的过程中实际上实现的是DSP中的MAX指令。4 _7 a. g3 F+ x' V. _+ ?6 R' a
    优化后:# t& Q  ]. }" o% y2 f6 x
    k = max(k-1, -1);2 `' [+ B7 v3 `- l2 N6 p8 {9 S" y
    转换成汇编后:
% i6 e- `* n5 b5 N: v    R0 += -1;    // R0 == k;0 t, x" d1 w; W; k5 W
    R1 = -1;8 l; n. @2 u" o* Y' V/ i
    R0 = MAX(R0, R1);
! ^' D3 h- p9 q    (3)for循环中的条件跳转; K: z. w! D1 T/ X- i  s
    for
& d( a! U5 \2 h6 k" K    {
. y: i+ ]1 d0 B' u        if{...}else{...}
$ c$ d. V  N, o. n+ ?. f    }
7 p" E; w3 b2 `8 g* C    原理:减少频繁的条件跳转,当然并不是所有的情况都可以这样做。. e3 e3 T9 p7 l. Y' T
    优化后:. e, E1 e: T/ n( g$ m' ?5 T
    if
2 W& [$ B3 O1 ]$ ^  Q1 b$ t    {' r; Q6 `3 d/ Z0 h/ ?. D. J
        for{...}
4 G- O- P( {6 q* b4 A    }
  }! I) L) q8 H" \) g6 Q    else
: c$ C6 M- w0 X* b, I" M: A    {. t( x# L; D" R/ T
        for{...}
% p& P1 w8 P: d+ }& {3 E    }4 n4 u4 ^5 ~3 A" Q/ {; l" m
    (4)使用断言指令来避免条件跳转& V5 Q9 }% N$ C, o% f! B
    if(A)$ o5 |* F8 }3 r  V( e6 ^5 l
    {
: b7 V4 ?$ o; u4 f        X = exp1;
( F* W  {" L/ K     }
# f8 c8 _! f" i% v, U5 R9 A    else
, Y/ p3 r% u: A% i7 B/ _    {
6 R- l. N, _  G/ N, d8 H5 K9 \5 G% \        X = exp2;
" R! E, a' v, q7 V/ i$ }7 W    }    
5 F, F- @9 a: {. T4 I- }    原理:使用断言指令IF(CC) REG = REG,只会消耗一个周期。1 x- B9 p" ?6 i
    优化后:
' s2 o: S+ t7 L' n" h3 c6 T( L* Q    X = exp1;9 K' ~9 a, i" u; S
    if(!A)
. r1 I0 q/ }: J( L    {8 c+ Z4 F3 W- k$ V. z  q7 g7 `3 V
        X = exp2;
. L$ E) ~2 Q" S* J7 n& I5 \7 K    }
+ B+ S" B6 H- n4 `, G' ]) R3 \    (5)除法(取模)操作
" k- Z, L! |4 h/ k8 ]9 x    一般DSP中不支持除法,除法操作是通过仿真的方式来进行实现,有两种,分为低精度和高精度,但都需要相大多的周期。
# s/ Y4 J7 _8 ~" \. h4 e    除数为2的N次方时可采用右移法。
( e8 }1 `3 f8 l    如为提高性能,可采取查表的方式,这样会损失精度。$ N4 @  W3 g# h# F
    隐藏的除法:
5 |/ |: w. ]% C4 x% v        for(i = start; i < finish; i += step)% N0 K" a, c# `, B: S
        此时编译器会looper = (finish - start) / step 得到次数。
' N' Z7 u7 s; z4 X' P! F6 ?, b; ]    巧妙利用不等式法测:(不过可能会产生溢出,要小心使用)' K/ c/ o) n- C" t$ [
        if(x / y > a / b)- C) k1 T! B; S9 K% `0 \
        可转换为:! ?' K, r% `* ~' r$ k2 z
        if(x * b  > a * y)0 ?% ?9 A4 U8 X
    (6)数据类型
: h( F8 H+ P0 O6 k0 `8 V    对于定点DSP而言,对于浮点的操作是用仿真的方式实现的,会消耗很多周期,所以在定点DSP上对于浮点数一般是做定点化的处理,常用的方法我举一个例子:2.5 * a,其实可以转换成80 * a >> 5,不过在定点化时需要注意防溢出。
+ o6 l& U5 L5 K# \2 m$ d    对于64位数据,也是用仿真的方式实现的,会消耗很多周期。(一般最大仅支持32位数据)$ h; ^* h/ W# K- w$ a4 G$ a* Z7 n% c
    做数字信号处理操作时,如FFT,16bit的操作是比较合适的。
2 u4 g& ]: j9 ]" e    要做控制类,条件跳转时,32bit的操作是比较合适的。- ^' p7 ]( Y" s% r3 e4 J, H
    如你的DSP的MAC是16位的,做乘法时,尽量定义成16bit数据。
: `+ c3 A  ]% g: y1 L- w/ @: P7 p    (7)Memory分配
. n. ^/ H3 X: Y! D" O+ c    将运算比较频繁的数据和程序段放入片内Memory,开启cache。1 Q0 Y' E* z" u; I1 N1 ~+ i4 J
    如DSP能对SDRAM的不同4个bank可以同时访问,此时你可以将需要同时运算的数据放入不同的bank
; s# B4 u8 {/ x' @/ C; u4 h    (8)开启仿真软件的编译优化选项
. \' W$ H0 [$ Y# u. f0 [6 J9 L+ M9 {    在菜单相应的地方勾上即可,但值得注意时,开启自动编译优化选项后,可能会使执行的结果发生变化,所以需要测试对比一下未开编译优化选项之前的执行结果,一般来说,这个很方便,比较常用。
7 V. D& M, x$ D) H. `; I5 }5 U4 Y    以上8种是我常用到的优化方法,当然基于C层面算法类的优化还有很多种,这个需要慢慢积累,总结一下,一般来说先对C层面进行结构上的优化(上面的1-6均属于),然后进行Memory分配,开启仿真软件的编译优化选项,将运算频繁的程序段用汇编实现,当然如果性能满足要求,就没必要利用汇编了。4 `6 ~, {  I0 }) H. D
  六、总结
- u( Z8 p/ @5 u5 }$ `6 d  我认为学习DSP软件开发没有什么捷径,我花了大量的文字在“弄清DSP相关资源的来源及熟读手册”上,实际上是想说,懂得获取资源是很关键的,只有熟悉手册才能完全去使用你所要开发的DSP芯片,其次DSP的主要特点就是高性能,能做一些算法类的运算,所以DSP的优化是相当重要的,关于算法优化的方法有很多种,基本可分为C结构上的优化及利用DSP的特点来进行优化,优化的学习是日易积累的,所以就要多看看相关的资料了。
) `/ m( n" n" L7 C2 i6 \, E2 o  快速入门的步骤如下:+ A- J# }8 u1 {$ ]' n2 J1 l4 F7 d
  准备一开发板,简单熟悉一下手册及仿真软件,对照着例程看手册,然后再改例程,看是否能按你的意愿去实现,最小系统和每个外设都熟悉一边,恭喜你,你入门了,待续。。。

该用户从未签到

2#
发表于 2016-5-16 13:51 | 只看该作者
楼主很用心啊!- Z" {  Z7 B, J* ^! ]
感谢感谢!

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-6-16 13:08 , Processed in 0.078125 second(s), 23 queries , Gzip On.

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

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

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