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

DSP学习经验

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
大学毕业至今,做了三年的DSP开发,将稍许经验记录下来,分享一下。
, U; V, }5 g7 N3 g8 U+ X  一、弄清DSP相关资源的来源及熟读手册7 X, ^. i8 y& l9 I
  一般主要来源于DSP芯片厂商的官方网站,虽然现在的DSP芯片厂商都提供了中文的官方网站浏览,但我建议还是上英文的网站,其一,有些资源在中文网站上没有(关于这点,我个人认为可能是中文这边的资源未及时上传),其二,一般资料很少有中文版,中文和英文版网站上下载的其实是同一个版本;再就是,要熟悉DSP芯片厂商的官方网站,开发时允分利用官方提供的资源及支持能大大地提高开发效率;最后要注意的是,一般DSP芯片厂商会开放一个技术交流论坛,里面的管理员一般都是DSP芯片厂商的开发工程师,可以以发贴的形式获取他们的技术支持。1 [2 }# v6 k, V  `' l/ [, u
  还有一处资源的来源,就是跟DSP芯片厂商有合作的第三方公司(国内),这类公司跟DSP芯片厂商有很好的接触,一般相关的DSP芯片,他们都会先行做成教育开发板,这点当然主要用于教学,所以他们会有相关的中文资料及相应的demo程序,根据这点,可以很好的借鉴他们的经验及参考他们的资料及程序,其次,他们还会出售自制的仿真器,价格比原厂的会便宜,功能上肯定没有原厂出售的仿真器全面,但足以应对基本的项目开发。/ }* t# w- B3 u- I
  第三处仅供参照,占据国内市场最大的两家DSP厂商TI和ADI在中国都开设的相应级别的DSP培训课程,但费用昂贵,一般都是公司派遣前去学习。4 [& P) c" ~5 H% {' K8 r
  资源主要包含:
& Z; L3 O0 y, \) i% E- }7 F    Datasheet(数据手册,主要大体介绍一下DSP芯片的功能,内部结构及外设,软件及硬件一些简单介绍,主要作用是可以很快速的了解这款DSP)
' U7 A' h- e/ ~    Software Tool Manuals(这个手册主要介绍的DSP时钟、存储器、电源管理等等及所有外设的使用及注意事项,其实就是寄存器的配置,完全可以称之为DSP使用手册)
" f" _; _7 j/ s1 b" k% r1 G    Hardware Tool Manuals(这个手册主要是官方提供的原理图PCB的绘制)、Program Manuals(这个手册主要介绍编译器及内置C库的使用,汇编指令的使用及汇编语法的介绍,官方提供的仿真软件的使用)  C3 i! v$ ?, v
     Engineer to Engineer Note(工程师笔记,这个其实就是DSP芯片自己的工程师在开发这款DSP时所写的笔记,如果你有某个地方未明白,看相应的工程师笔记是最合适的)* Q+ g- I- v) Z' @
    Program Examples(主要是针对DSP不同的外设,官方提供的程序例子,包含C及汇编)
) i$ X1 [5 Q8 F& P  二、官方仿真软件及仿真器的使用(如不使用,可暂时跳过,因为有些DSP可基于开源的操作系统进行开发,例如uClinux)4 p, d+ y+ F# b- T0 L1 E5 t
  使用仿真软件的方法其实很简单,一般这种软件都设计成类似VC这种,你逐个去试每个菜单下的选项,此时你如配合Examples去使用,更能加深理解,不过我建议,做DSP软件开发,先简单看一下Datasheet、Software Tool Manuals和Program Manuals这三个文档再开始熟悉仿真软件的使用,当然在你熟悉时,肯定需要去不停的再去看这些文档的。仿真器的使用并没有什么需要注意的,一般的仿真器都做了仿呆处理,所以不会插反,仿真器一般都是配合仿真软件使用。(有一点要提醒的是一般DSP开发是基于C语言,如果不会C语言,请先学习C语言)5 f, m9 u& {, ?0 X0 A6 d- o
  三、DSP最小系统的配置+ d' ?3 g! q/ X. G* O* G" L+ I
  这部分就正式开始使用DSP了,最小系统主要指DSP的时钟及存储器系统,这时你需要对照着Software Tool Manualsh去仔细看里面的介绍及相关寄存器的配置,结合Examples及Engineer to Engineer Note,如果程序写完后,测试时钟其实很简单,用示波器直接去测量,看测量出来的时钟是否是你配置的那个数,紧接着就是测试存储器,这个测试必须写一段简单的小程序,其实主要就是测试数据总线是否能正常工作,如果在配置最小系统时出现问题,一般问题有二,一是寄存器未正确配置,解决方法是结合Examples及Engineer to Engineer Note仔细看手册,看例程,二是可能开发板上的硬件线路出了问题,解决方法是结合原理图,看线路上是否存在短路的问题,DSP工作电压是否正常等,这步可和硬件工程师一起去查。
8 d1 c* d/ |1 S, i6 d; B% a  K, @8 o  四、DSP外设的使用
- C( Z) H1 r- S; {  其实这部分和配置最小系统一样,只不过某些外设上可能连接了其它的芯片,不同的功能连接的芯片不一样,此时你需要去看这些芯片的资料,然后开始编写代码,然后再测试,测试方法根据不同的功能也会不同,不过DSP开发最常用的就是使用示波器,如有音视频方面的,可借助摄像头,显示屏等等之类的;如中间开发遇到问题,方法还是一样,结合Examples及Engineer to Engineer Note仔细看手册,看例程,有一点要注意,千万不能怀疑不能实现,要对自己有信心。8 x5 b# G+ g% O5 `  c9 ?1 `6 D
  五、DSP优化9 Q9 B! I# g& K' ^& l$ W
  其实到这一步,你已经完全可以使用DSP了,接下来,你需要加深熟悉DSP的整个内部结构,主要包含有几个多少位的MAC,有几个多少位的ALU,有几个多少位的数据寄存器等等,还有外部数据总线上连接了哪些外设,内部数据总线是怎么连接的,并且这些数据总线是多少位,这些在Datasheet会有一张很清楚的DSP结构图,还有DSP的整个Memory Map是怎样的,片上有多少Data Memory,有多少Program Memory等等,了解这些其实就是让你知道DSP的运算性能到底可以达到多少,哪些外设会通过外部数据总线传输数据,DSP内部的寄存器是怎么传输数据的,通过这些可以帮助你解决你在开发中遇到的问题,不过最主要的是帮助你对已经编写完成的代码进行优化,我个人认为的优化方法有以下几种:" z% Y  W' W5 K  w( U, y
  1、一般编写代码首先是用C,基于C层面优化的方法,我如下举例说几种:2 w/ w) V, D$ c0 F5 J& u
    (1)优化循环
1 L6 k8 j- e5 s! T# z- a' K    for(i = 0;i < max;i ++)0 I) p, H! r" [- L2 P
     {
, G7 z9 a8 i- R. i0 O        for(j = 0; j < max; j ++)& b7 }6 @. j7 V0 I: u! m  O
        {
. t3 N# _0 f( R, ]            float sum = 0.0;/ d4 S3 v  _5 O# k
            for(k = 0; k < max; k ++)
3 X$ n. p$ O* I& x- E  G            {
* @; Z5 r$ M7 G( E- U% N                sum += input[i * max + k] * input[j * max + k];: T. ^0 n6 x; ?) N; u( D6 ?
            }  e! g4 u1 n6 [4 h# c, [
            cover[i * max + j] = sum / max;- Y9 v# l, }) u9 r. Z
        }* I4 a5 q. x' d, A- X; K* u
    }5 e# Z! u& J+ ]
    实例,如input[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},得出的cover如下:
* i( s' l* C& v5 t4 A) b     7    17   27   373 z/ d- n4 i' U. }* t; s1 s
     17  43   69   95
& p( r5 z% Y! ?7 x" P0 x     27  69  111  153: j' |" X; H$ }4 ^) {; s
     37  95  153  2117 O$ U% n) e+ G
    图示:
0 Q3 q4 d$ P/ n0 @9 U% k- w7 m    
3 r2 Z8 s% }" a9 P' n, Z! n0 m5 w5 R    原理:只需要得到左上角或右上角即可,然后半个矩阵赋值给另半个矩阵即可得到整个矩阵。8 V% A2 R# ]8 Z2 j6 m8 B' j
    算法优化后:
5 ]; y. D" ^' p; @' }7 F7 g9 X    for(i = 0; i < max; i ++)! h% @0 _% J  |& s6 D! q% b
    {4 c5 t8 M0 D% q2 E7 P
        for(j = i; j < max; j ++)                  // 减少一半循环5 B% {# u) a3 ]3 Y) D' ?8 ~
        {
' F+ T# K7 z7 i0 n            float sum = 0.0;
5 r5 o& |% ]  O- P! W( q7 p3 [            for(k = 0; k < max; k ++)- B( p) G, U4 x* e9 A4 ^( I
            {
0 W4 @- F6 d8 v5 z5 |8 `: S                sum += input[i * max + k] * input[j * max + k];
6 D. t: n6 B2 e& ^1 \  V9 k" I4 a            }
0 H' l1 n: l2 e1 n& Y+ E( R! C4 T% q            cover[i * max + j] = sum / max;
5 X' q/ J1 \5 V$ F            if(i != j)                    // 可加可不加,消除中线上的重复赋值
5 Z4 Z% H; L( \; I% D            {3 L9 S4 j! H( G2 c
                cover[j *max + i] = sum / max;       // 赋值给另半个矩阵
, v+ y1 L1 F% x/ k8 U( n5 S7 H            }
  \6 t7 d$ q# s! b/ K1 c/ R        }* a: x/ z% d) E8 ^2 ^  h- z$ M6 b( Y
    }
/ U. q. \3 l4 h+ ^9 V    (2)条件跳转(使用条件跳转会在流水线中浪费更多的周期)7 p7 e  @  ?) n
    k = k -1;
# U& z. x1 x' i: S0 j+ N  C    if(k < -1)1 X0 P: d: d' g4 w: e  l8 M
    {1 {7 i6 U1 S4 Z3 [* |
        k = -1;+ h' ?5 i+ G* X6 b
    }* u7 g1 E9 j& Z% a' o; R1 }0 \
    原理:C语言中的max函数在编译的过程中实际上实现的是DSP中的MAX指令。1 k% s' j) n5 i
    优化后:
+ Q, }& _1 a( n% T6 T    k = max(k-1, -1);& X/ m" r% b7 z3 x% B6 l* E! y0 u. {
    转换成汇编后:
: l8 H; C/ p; d) e6 n    R0 += -1;    // R0 == k;  u& w/ y' h/ e/ V* t& j" k3 X
    R1 = -1;) P) t/ \9 K& V% U( d; u
    R0 = MAX(R0, R1);8 J( f( t0 Z: Q1 [
    (3)for循环中的条件跳转
0 j0 v9 {' f  P    for
- t% D2 {9 w: f* W! s* W    {/ O! N7 i: S- v: R3 }3 X
        if{...}else{...}
# ^* T% N) n! O0 N0 l) E    }# G3 v( R/ x$ ?
    原理:减少频繁的条件跳转,当然并不是所有的情况都可以这样做。
: C! y; u& y- P! ~% q: S    优化后:3 B! T& ?* c/ v) I
    if
, W4 Z, a. ~2 m6 D    {
8 b$ k) h/ R& Q" g. @2 N3 J$ u        for{...}5 h+ n# ^$ e, t+ p+ X! A. q+ Y
    }, K: Q: }( ?6 S) E. \. L
    else
5 Z( N# @2 T# W( j9 v. E1 [$ z    {( H" l  q9 H* m; f# a
        for{...}
1 U% Y0 J2 U+ g    }
2 N2 ~4 s# F: j  S0 K1 G    (4)使用断言指令来避免条件跳转9 \- W% R" K: q9 G/ T1 @5 G  G
    if(A)6 Y5 S* T  ~6 K
    {8 r$ p4 O0 C. x. H0 y) F
        X = exp1;
1 t( ]* ^4 ~& p6 n9 W7 l  P1 P     }3 P' s: W. M5 g* m
    else
4 C# s. X: P7 w+ ~# D) r  f4 m( h/ @    {
) W& X; \7 S5 n5 p8 W# O2 M* [        X = exp2;
! j: P$ B$ b3 r* F% ]& t    }    4 f5 c! ~. k, d4 l* d, P% g) m( A0 a5 N
    原理:使用断言指令IF(CC) REG = REG,只会消耗一个周期。5 L; i5 Z" H( k
    优化后:& W2 ]" r3 c+ _: m* E0 o
    X = exp1;$ e% a. h0 g0 t9 |9 ~8 |; B0 r
    if(!A)+ _$ x1 `7 _: o" Y8 Y" I
    {
7 R2 }* N$ q7 R0 J& q        X = exp2;
7 ~" |: n5 F+ p$ S/ L3 B- s    }$ T0 ?# k/ [# @8 K- u
    (5)除法(取模)操作- [7 k0 q7 r8 [3 I
    一般DSP中不支持除法,除法操作是通过仿真的方式来进行实现,有两种,分为低精度和高精度,但都需要相大多的周期。
" q+ ]5 y7 @2 K( l$ Y& M; I0 H    除数为2的N次方时可采用右移法。9 }! M2 e, k2 D; y! m6 o( s3 L- }
    如为提高性能,可采取查表的方式,这样会损失精度。; {' }. |  q) ]
    隐藏的除法:
; ]  G& c( _+ k6 p) b) t  }        for(i = start; i < finish; i += step)
& P! |. c$ ]; U. ~( {        此时编译器会looper = (finish - start) / step 得到次数。
; }" }# Z2 B; \    巧妙利用不等式法测:(不过可能会产生溢出,要小心使用)
' Z/ x& N$ l4 U$ l& s. o" }" ]& m        if(x / y > a / b)
$ G9 E- T6 N9 i2 ]) z- b) {6 v' |        可转换为:
! I; v+ ?: U9 b$ D0 p        if(x * b  > a * y)
3 A* a! ^5 n, {# t' R# X9 l/ \    (6)数据类型
8 E* v' N; Z, O% Q    对于定点DSP而言,对于浮点的操作是用仿真的方式实现的,会消耗很多周期,所以在定点DSP上对于浮点数一般是做定点化的处理,常用的方法我举一个例子:2.5 * a,其实可以转换成80 * a >> 5,不过在定点化时需要注意防溢出。
7 J0 k0 w% I$ W6 E8 g6 Z" T    对于64位数据,也是用仿真的方式实现的,会消耗很多周期。(一般最大仅支持32位数据)
5 U+ f, G) D% h) N0 F9 z: L    做数字信号处理操作时,如FFT,16bit的操作是比较合适的。! a$ b& b- g7 k' S
    要做控制类,条件跳转时,32bit的操作是比较合适的。
/ H1 Q6 A/ ?1 i1 E    如你的DSP的MAC是16位的,做乘法时,尽量定义成16bit数据。
5 L% z  s2 s+ F* O2 U    (7)Memory分配
, r. A  e* h& C! V7 I, Z    将运算比较频繁的数据和程序段放入片内Memory,开启cache。
2 ?6 g, A. i4 _2 `4 a$ A& d    如DSP能对SDRAM的不同4个bank可以同时访问,此时你可以将需要同时运算的数据放入不同的bank
) M4 E# R9 P8 ^' S! o' ^1 S" J    (8)开启仿真软件的编译优化选项
6 l( s* T' H' E& X4 V2 k& s0 i    在菜单相应的地方勾上即可,但值得注意时,开启自动编译优化选项后,可能会使执行的结果发生变化,所以需要测试对比一下未开编译优化选项之前的执行结果,一般来说,这个很方便,比较常用。
! r6 x: M2 X9 @: e7 ^# E8 m5 Z    以上8种是我常用到的优化方法,当然基于C层面算法类的优化还有很多种,这个需要慢慢积累,总结一下,一般来说先对C层面进行结构上的优化(上面的1-6均属于),然后进行Memory分配,开启仿真软件的编译优化选项,将运算频繁的程序段用汇编实现,当然如果性能满足要求,就没必要利用汇编了。. M$ X5 S/ A4 T$ y7 L' X
  六、总结, w; X' @+ ~6 x4 @8 I$ I6 [2 H! b
  我认为学习DSP软件开发没有什么捷径,我花了大量的文字在“弄清DSP相关资源的来源及熟读手册”上,实际上是想说,懂得获取资源是很关键的,只有熟悉手册才能完全去使用你所要开发的DSP芯片,其次DSP的主要特点就是高性能,能做一些算法类的运算,所以DSP的优化是相当重要的,关于算法优化的方法有很多种,基本可分为C结构上的优化及利用DSP的特点来进行优化,优化的学习是日易积累的,所以就要多看看相关的资料了。2 E' e- m# |4 q& ^% ?2 g- O
  快速入门的步骤如下:& Z. N/ c3 q7 d( k, O
  准备一开发板,简单熟悉一下手册及仿真软件,对照着例程看手册,然后再改例程,看是否能按你的意愿去实现,最小系统和每个外设都熟悉一边,恭喜你,你入门了,待续。。。

该用户从未签到

2#
发表于 2016-5-16 13:51 | 只看该作者
楼主很用心啊!
, G. e8 m+ Q4 X0 M: v感谢感谢!

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

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

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

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

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