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

DSP学习经验

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
大学毕业至今,做了三年的DSP开发,将稍许经验记录下来,分享一下。/ {2 y, N; s$ ?# t7 Q
  一、弄清DSP相关资源的来源及熟读手册
3 c/ a% b2 T% ^* `1 _" W+ o  E  一般主要来源于DSP芯片厂商的官方网站,虽然现在的DSP芯片厂商都提供了中文的官方网站浏览,但我建议还是上英文的网站,其一,有些资源在中文网站上没有(关于这点,我个人认为可能是中文这边的资源未及时上传),其二,一般资料很少有中文版,中文和英文版网站上下载的其实是同一个版本;再就是,要熟悉DSP芯片厂商的官方网站,开发时允分利用官方提供的资源及支持能大大地提高开发效率;最后要注意的是,一般DSP芯片厂商会开放一个技术交流论坛,里面的管理员一般都是DSP芯片厂商的开发工程师,可以以发贴的形式获取他们的技术支持。8 D/ L  f1 e8 E# I) }# Z. v% l
  还有一处资源的来源,就是跟DSP芯片厂商有合作的第三方公司(国内),这类公司跟DSP芯片厂商有很好的接触,一般相关的DSP芯片,他们都会先行做成教育开发板,这点当然主要用于教学,所以他们会有相关的中文资料及相应的demo程序,根据这点,可以很好的借鉴他们的经验及参考他们的资料及程序,其次,他们还会出售自制的仿真器,价格比原厂的会便宜,功能上肯定没有原厂出售的仿真器全面,但足以应对基本的项目开发。
* T$ ]4 I1 R* b7 }8 U% T2 x) L  第三处仅供参照,占据国内市场最大的两家DSP厂商TI和ADI在中国都开设的相应级别的DSP培训课程,但费用昂贵,一般都是公司派遣前去学习。
5 r$ t4 n" J# O7 k4 s# C) u8 O  资源主要包含:
8 ~5 M0 @, B$ F( M% f" |* m2 S    Datasheet(数据手册,主要大体介绍一下DSP芯片的功能,内部结构及外设,软件及硬件一些简单介绍,主要作用是可以很快速的了解这款DSP)1 {- Q- x/ ?7 I  N( z$ H
    Software Tool Manuals(这个手册主要介绍的DSP时钟、存储器、电源管理等等及所有外设的使用及注意事项,其实就是寄存器的配置,完全可以称之为DSP使用手册); Z" s7 D1 z$ u
    Hardware Tool Manuals(这个手册主要是官方提供的原理图PCB的绘制)、Program Manuals(这个手册主要介绍编译器及内置C库的使用,汇编指令的使用及汇编语法的介绍,官方提供的仿真软件的使用)! U* o- F, J$ h8 q' P8 h: [- z
     Engineer to Engineer Note(工程师笔记,这个其实就是DSP芯片自己的工程师在开发这款DSP时所写的笔记,如果你有某个地方未明白,看相应的工程师笔记是最合适的)( e' T) E7 f% R( q4 z
    Program Examples(主要是针对DSP不同的外设,官方提供的程序例子,包含C及汇编)% w8 S) u+ O6 a, w/ N
  二、官方仿真软件及仿真器的使用(如不使用,可暂时跳过,因为有些DSP可基于开源的操作系统进行开发,例如uClinux)  y6 f# C; W5 T& J( a
  使用仿真软件的方法其实很简单,一般这种软件都设计成类似VC这种,你逐个去试每个菜单下的选项,此时你如配合Examples去使用,更能加深理解,不过我建议,做DSP软件开发,先简单看一下Datasheet、Software Tool Manuals和Program Manuals这三个文档再开始熟悉仿真软件的使用,当然在你熟悉时,肯定需要去不停的再去看这些文档的。仿真器的使用并没有什么需要注意的,一般的仿真器都做了仿呆处理,所以不会插反,仿真器一般都是配合仿真软件使用。(有一点要提醒的是一般DSP开发是基于C语言,如果不会C语言,请先学习C语言)
8 M. n, I# P# G  三、DSP最小系统的配置* n5 x$ d# n! W4 p6 h- m/ m  k
  这部分就正式开始使用DSP了,最小系统主要指DSP的时钟及存储器系统,这时你需要对照着Software Tool Manualsh去仔细看里面的介绍及相关寄存器的配置,结合Examples及Engineer to Engineer Note,如果程序写完后,测试时钟其实很简单,用示波器直接去测量,看测量出来的时钟是否是你配置的那个数,紧接着就是测试存储器,这个测试必须写一段简单的小程序,其实主要就是测试数据总线是否能正常工作,如果在配置最小系统时出现问题,一般问题有二,一是寄存器未正确配置,解决方法是结合Examples及Engineer to Engineer Note仔细看手册,看例程,二是可能开发板上的硬件线路出了问题,解决方法是结合原理图,看线路上是否存在短路的问题,DSP工作电压是否正常等,这步可和硬件工程师一起去查。5 Y9 i* e; u# j3 _5 W
  四、DSP外设的使用, H4 k6 g* U% |' F- t
  其实这部分和配置最小系统一样,只不过某些外设上可能连接了其它的芯片,不同的功能连接的芯片不一样,此时你需要去看这些芯片的资料,然后开始编写代码,然后再测试,测试方法根据不同的功能也会不同,不过DSP开发最常用的就是使用示波器,如有音视频方面的,可借助摄像头,显示屏等等之类的;如中间开发遇到问题,方法还是一样,结合Examples及Engineer to Engineer Note仔细看手册,看例程,有一点要注意,千万不能怀疑不能实现,要对自己有信心。4 ~6 Q5 h: B8 {  C
  五、DSP优化
0 O4 ~* p* J' D+ X' v, R  其实到这一步,你已经完全可以使用DSP了,接下来,你需要加深熟悉DSP的整个内部结构,主要包含有几个多少位的MAC,有几个多少位的ALU,有几个多少位的数据寄存器等等,还有外部数据总线上连接了哪些外设,内部数据总线是怎么连接的,并且这些数据总线是多少位,这些在Datasheet会有一张很清楚的DSP结构图,还有DSP的整个Memory Map是怎样的,片上有多少Data Memory,有多少Program Memory等等,了解这些其实就是让你知道DSP的运算性能到底可以达到多少,哪些外设会通过外部数据总线传输数据,DSP内部的寄存器是怎么传输数据的,通过这些可以帮助你解决你在开发中遇到的问题,不过最主要的是帮助你对已经编写完成的代码进行优化,我个人认为的优化方法有以下几种:2 A" Q" p& v3 b
  1、一般编写代码首先是用C,基于C层面优化的方法,我如下举例说几种:
6 S1 ~+ O: G3 o8 h" P% h1 t" F  M    (1)优化循环! G" d1 d' t" C& i, j, u3 a
    for(i = 0;i < max;i ++)
: [5 I) P, k2 C* F: \     {) |; L; v- c! i, V
        for(j = 0; j < max; j ++)! }# U. J  }& a2 E6 Y. d! A
        {
* w& j" a$ N& A% L% n8 V            float sum = 0.0;
9 j3 w! o4 A9 R& U$ Y3 Q            for(k = 0; k < max; k ++)3 ?1 `- t$ Z# u0 J! }: N
            {
6 y3 Q  _3 H& U6 c                sum += input[i * max + k] * input[j * max + k];" f5 ~  h. j& |% e. Q8 A% }
            }0 I# ]  R' d, b+ [: ?8 {" T' i; r
            cover[i * max + j] = sum / max;; E8 V9 ]) X2 o5 L+ ?; O2 K* G5 x
        }5 z2 P0 t) c9 A9 ]) h
    }
3 h, X9 E+ i- K4 R2 o    实例,如input[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},得出的cover如下:* K# f3 t1 ^4 u. t! S7 @  A
     7    17   27   37( Y$ V+ S) Q1 u% N! p
     17  43   69   95
+ y- r, S# J" B9 v2 T: L     27  69  111  1533 N; |( X, Z- Q# I, Q5 b
     37  95  153  211# A4 F( p) U" N% P8 R4 a
    图示:
. K5 }: _; e9 O# ~    ! R! p' V+ ?; T1 q
    原理:只需要得到左上角或右上角即可,然后半个矩阵赋值给另半个矩阵即可得到整个矩阵。
: m/ X, d7 V4 A; S# E" r4 Z    算法优化后:
( s9 X9 c9 f: D    for(i = 0; i < max; i ++)5 }9 ?! V2 ?0 `& n' }2 C/ @
    {
+ ?2 r4 U" V, Z, M: D        for(j = i; j < max; j ++)                  // 减少一半循环. a. k* ~8 t, [) W
        {
/ ]' B" I; u& M, ], e0 I7 B9 {            float sum = 0.0;
/ z0 w/ c, s1 g: H" U' t: [            for(k = 0; k < max; k ++)
, B) H- B: Y1 t            {+ P( Y/ q7 |/ i: y) G9 q& p
                sum += input[i * max + k] * input[j * max + k];8 k" \8 A$ z6 W( a" [+ D
            }
! G0 i7 w. _3 C# _1 o" |0 d            cover[i * max + j] = sum / max;* ~& g/ _+ F, Q2 E4 Z5 l
            if(i != j)                    // 可加可不加,消除中线上的重复赋值/ @( E. u( X0 o% M% s* g
            {" }; X5 ~8 ]( E. V8 G
                cover[j *max + i] = sum / max;       // 赋值给另半个矩阵+ F' z9 ?) M& X+ w$ W9 v
            }
7 H0 W5 E3 k& ?3 c1 b        }
) V" X2 h( n: T2 x; I    }
# o& Q8 g7 w1 |2 P( j% G* n    (2)条件跳转(使用条件跳转会在流水线中浪费更多的周期)
) T& v8 ]* l1 P" U5 t    k = k -1;) c5 @- F; T  r' n4 m
    if(k < -1)" Q3 D) W) |5 `+ t0 p- N7 l  V; {3 S
    {
' M: u6 [7 I7 n5 Q        k = -1;1 j  |+ {, h6 \7 w7 v
    }
4 f3 Z) N! ~. Q7 @    原理:C语言中的max函数在编译的过程中实际上实现的是DSP中的MAX指令。
* ^3 d6 u0 k9 L" Z    优化后:
  ]( H7 q! E  Z    k = max(k-1, -1);
% z2 f  S( M& I6 ?# k    转换成汇编后:: D  m7 e0 n; K
    R0 += -1;    // R0 == k;
3 m4 \5 e; Q2 B, O. o' D    R1 = -1;
3 m+ {8 m; z1 m6 p5 I& \3 I# Y    R0 = MAX(R0, R1);
2 z  g) D2 q% I    (3)for循环中的条件跳转
4 Z& T3 z1 i" P4 H$ S) d( W    for
' ~3 ^( T' i$ e9 y1 ?    {6 F: b: c; e" D+ U* ^7 U+ w  D
        if{...}else{...}/ a3 J$ C" O6 Z, P3 ]
    }
- j0 a3 `( @  S/ i% J    原理:减少频繁的条件跳转,当然并不是所有的情况都可以这样做。
1 R/ K, X1 V1 k- F% a    优化后:  p3 ^" Y; f2 I4 y  V
    if6 g+ ?7 }+ I$ ?& C* U+ J
    {
  _/ U/ p% E2 D& l8 j        for{...}" W. n" z0 [! I# c
    }* c. S: n- [& }5 B3 y
    else# a6 S% Q3 D/ g/ b$ Y5 T% a
    {
- M. R4 n' u" \: B- H( R( U        for{...}
& i0 x' u) x. f- x: x    }
4 n6 t: l0 d3 c2 P    (4)使用断言指令来避免条件跳转
1 D6 [6 f" K3 P. C3 ^    if(A)
4 p0 a" y9 X- j8 k. Y    {
9 l0 u0 {" G  R4 i        X = exp1;6 H! [2 s3 n2 b/ y$ j5 A) e; S* {
     }* V5 i+ R! O+ t$ k5 ?) ?
    else" u9 D( b% S) N& b
    {1 g1 l9 F- t. t# P
        X = exp2;
) a9 g1 z# K; l0 G3 T/ r* m+ K    }    
. }* c% O: T# ]( L8 [6 [    原理:使用断言指令IF(CC) REG = REG,只会消耗一个周期。* _9 f7 B& z; u: p# e; P7 f
    优化后:
2 R2 i. l+ E! j* E1 _2 R3 [    X = exp1;/ e6 P8 e7 c0 |1 m
    if(!A)
% C5 k; E! ]8 A: u  ~6 }0 t7 G    {. E6 z. S) V7 P, s7 Z
        X = exp2;- |3 t7 O# ~, p# a  R
    }6 d8 ~4 A8 B- j5 J! t3 B4 u
    (5)除法(取模)操作7 L- Q! a7 w* p3 W" i4 i' p  G7 n9 V
    一般DSP中不支持除法,除法操作是通过仿真的方式来进行实现,有两种,分为低精度和高精度,但都需要相大多的周期。
2 r3 D' ~; h4 A% w% i    除数为2的N次方时可采用右移法。
7 X% j( b: {4 p) Q" x    如为提高性能,可采取查表的方式,这样会损失精度。
7 J. ]* B' k' ?  X, y/ f% e4 U    隐藏的除法:
5 _; b. W: l8 M        for(i = start; i < finish; i += step)
6 m; v6 L. ]# B- R) `        此时编译器会looper = (finish - start) / step 得到次数。
3 y" L/ r* ~5 A( k& Z: b" }/ o    巧妙利用不等式法测:(不过可能会产生溢出,要小心使用)
' b+ w& J* f7 M  R        if(x / y > a / b): z2 a2 J2 L9 D1 T
        可转换为:
# o( C0 H$ w5 M" ]        if(x * b  > a * y)) U) Z" x% r. Q" A( h7 s/ k# X, c
    (6)数据类型, t  j8 c3 K' F2 f8 |) l
    对于定点DSP而言,对于浮点的操作是用仿真的方式实现的,会消耗很多周期,所以在定点DSP上对于浮点数一般是做定点化的处理,常用的方法我举一个例子:2.5 * a,其实可以转换成80 * a >> 5,不过在定点化时需要注意防溢出。
; J: f' t5 G* s3 B( l    对于64位数据,也是用仿真的方式实现的,会消耗很多周期。(一般最大仅支持32位数据)2 K' `+ ]* H* V, |
    做数字信号处理操作时,如FFT,16bit的操作是比较合适的。
0 q- _& P7 H3 I% o/ l+ h0 u4 c) P5 m    要做控制类,条件跳转时,32bit的操作是比较合适的。
- n  ^' ^9 ]% J' A3 x" I7 R    如你的DSP的MAC是16位的,做乘法时,尽量定义成16bit数据。
! [! P" c" {' c# C    (7)Memory分配+ F; W0 b& f7 [+ X8 j" F6 d
    将运算比较频繁的数据和程序段放入片内Memory,开启cache。4 S( I. {5 h' b* o7 U
    如DSP能对SDRAM的不同4个bank可以同时访问,此时你可以将需要同时运算的数据放入不同的bank
$ f) @& u3 x9 d' t( V3 A/ b$ J    (8)开启仿真软件的编译优化选项, Z" I: j6 v: L/ z$ C; }
    在菜单相应的地方勾上即可,但值得注意时,开启自动编译优化选项后,可能会使执行的结果发生变化,所以需要测试对比一下未开编译优化选项之前的执行结果,一般来说,这个很方便,比较常用。* C% C- _* n/ S6 G( u7 Z: R' f
    以上8种是我常用到的优化方法,当然基于C层面算法类的优化还有很多种,这个需要慢慢积累,总结一下,一般来说先对C层面进行结构上的优化(上面的1-6均属于),然后进行Memory分配,开启仿真软件的编译优化选项,将运算频繁的程序段用汇编实现,当然如果性能满足要求,就没必要利用汇编了。
$ A' ]4 J3 s: N) y, d7 M  六、总结
, k  v3 I9 ~& D8 m! s  我认为学习DSP软件开发没有什么捷径,我花了大量的文字在“弄清DSP相关资源的来源及熟读手册”上,实际上是想说,懂得获取资源是很关键的,只有熟悉手册才能完全去使用你所要开发的DSP芯片,其次DSP的主要特点就是高性能,能做一些算法类的运算,所以DSP的优化是相当重要的,关于算法优化的方法有很多种,基本可分为C结构上的优化及利用DSP的特点来进行优化,优化的学习是日易积累的,所以就要多看看相关的资料了。+ Q  K. E3 Z8 w! k- e
  快速入门的步骤如下:
6 D$ D( k1 _( h* B" N; S  准备一开发板,简单熟悉一下手册及仿真软件,对照着例程看手册,然后再改例程,看是否能按你的意愿去实现,最小系统和每个外设都熟悉一边,恭喜你,你入门了,待续。。。

该用户从未签到

2#
发表于 2016-5-16 13:51 | 只看该作者
楼主很用心啊!
( r/ Z8 L+ ?+ I! \  s% p# o感谢感谢!

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-23 19:56 , Processed in 0.171875 second(s), 23 queries , Gzip On.

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

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

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