找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

巢课
电巢直播8月计划
查看: 55|回复: 3
打印 上一主题 下一主题

DSP学习经验

[复制链接]

171

主题

616

帖子

1306

积分

四级会员(40)

Rank: 4Rank: 4Rank: 4Rank: 4

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

EDA365欢迎您!

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

x
大学毕业至今,做了三年的DSP开发,将稍许经验记录下来,分享一下。
( z: r  w: p/ y2 B8 p) d" o  一、弄清DSP相关资源的来源及熟读手册
, x" f3 i$ F$ ~" Y  S  一般主要来源于DSP芯片厂商的官方网站,虽然现在的DSP芯片厂商都提供了中文的官方网站浏览,但我建议还是上英文的网站,其一,有些资源在中文网站上没有(关于这点,我个人认为可能是中文这边的资源未及时上传),其二,一般资料很少有中文版,中文和英文版网站上下载的其实是同一个版本;再就是,要熟悉DSP芯片厂商的官方网站,开发时允分利用官方提供的资源及支持能大大地提高开发效率;最后要注意的是,一般DSP芯片厂商会开放一个技术交流论坛,里面的管理员一般都是DSP芯片厂商的开发工程师,可以以发贴的形式获取他们的技术支持。- c1 K+ v- d( c- _% f  e0 b, N
  还有一处资源的来源,就是跟DSP芯片厂商有合作的第三方公司(国内),这类公司跟DSP芯片厂商有很好的接触,一般相关的DSP芯片,他们都会先行做成教育开发板,这点当然主要用于教学,所以他们会有相关的中文资料及相应的demo程序,根据这点,可以很好的借鉴他们的经验及参考他们的资料及程序,其次,他们还会出售自制的仿真器,价格比原厂的会便宜,功能上肯定没有原厂出售的仿真器全面,但足以应对基本的项目开发。( ^' W6 {9 V0 g9 ^& \
  第三处仅供参照,占据国内市场最大的两家DSP厂商TI和ADI在中国都开设的相应级别的DSP培训课程,但费用昂贵,一般都是公司派遣前去学习。4 C; ~: L& H$ L9 K
  资源主要包含:4 z8 K% Z5 X3 s) g) t, i
    Datasheet(数据手册,主要大体介绍一下DSP芯片的功能,内部结构及外设,软件及硬件一些简单介绍,主要作用是可以很快速的了解这款DSP)
5 g2 F7 u/ A, e0 K& D* M) `    Software Tool Manuals(这个手册主要介绍的DSP时钟、存储器、电源管理等等及所有外设的使用及注意事项,其实就是寄存器的配置,完全可以称之为DSP使用手册)
% n, R- k6 j7 l) ^$ K    Hardware Tool Manuals(这个手册主要是官方提供的原理图PCB的绘制)、Program Manuals(这个手册主要介绍编译器及内置C库的使用,汇编指令的使用及汇编语法的介绍,官方提供的仿真软件的使用)
% |. G- h1 e0 N- R& i( o0 b( ~6 l- Q9 ~" Q     Engineer to Engineer Note(工程师笔记,这个其实就是DSP芯片自己的工程师在开发这款DSP时所写的笔记,如果你有某个地方未明白,看相应的工程师笔记是最合适的)0 d- e8 A" Q- Q( c3 ?) b4 |
    Program Examples(主要是针对DSP不同的外设,官方提供的程序例子,包含C及汇编)
' `6 o( A* R" o! t3 o: O% G3 s  二、官方仿真软件及仿真器的使用(如不使用,可暂时跳过,因为有些DSP可基于开源的操作系统进行开发,例如uClinux)( m- o1 O2 [, E/ R+ B; B
  使用仿真软件的方法其实很简单,一般这种软件都设计成类似VC这种,你逐个去试每个菜单下的选项,此时你如配合Examples去使用,更能加深理解,不过我建议,做DSP软件开发,先简单看一下Datasheet、Software Tool Manuals和Program Manuals这三个文档再开始熟悉仿真软件的使用,当然在你熟悉时,肯定需要去不停的再去看这些文档的。仿真器的使用并没有什么需要注意的,一般的仿真器都做了仿呆处理,所以不会插反,仿真器一般都是配合仿真软件使用。(有一点要提醒的是一般DSP开发是基于C语言,如果不会C语言,请先学习C语言)
1 y) w: o% t( c. K/ {& _  |4 L  三、DSP最小系统的配置
. e* F& v5 Q0 S' h! ?  这部分就正式开始使用DSP了,最小系统主要指DSP的时钟及存储器系统,这时你需要对照着Software Tool Manualsh去仔细看里面的介绍及相关寄存器的配置,结合Examples及Engineer to Engineer Note,如果程序写完后,测试时钟其实很简单,用示波器直接去测量,看测量出来的时钟是否是你配置的那个数,紧接着就是测试存储器,这个测试必须写一段简单的小程序,其实主要就是测试数据总线是否能正常工作,如果在配置最小系统时出现问题,一般问题有二,一是寄存器未正确配置,解决方法是结合Examples及Engineer to Engineer Note仔细看手册,看例程,二是可能开发板上的硬件线路出了问题,解决方法是结合原理图,看线路上是否存在短路的问题,DSP工作电压是否正常等,这步可和硬件工程师一起去查。
5 Y4 n: m/ \) `/ @! k  四、DSP外设的使用- Q0 S* u# K6 {7 o! a) W, d1 Y
  其实这部分和配置最小系统一样,只不过某些外设上可能连接了其它的芯片,不同的功能连接的芯片不一样,此时你需要去看这些芯片的资料,然后开始编写代码,然后再测试,测试方法根据不同的功能也会不同,不过DSP开发最常用的就是使用示波器,如有音视频方面的,可借助摄像头,显示屏等等之类的;如中间开发遇到问题,方法还是一样,结合Examples及Engineer to Engineer Note仔细看手册,看例程,有一点要注意,千万不能怀疑不能实现,要对自己有信心。
. {% H: `' b' I4 G  五、DSP优化
( H6 d1 V5 N* L  其实到这一步,你已经完全可以使用DSP了,接下来,你需要加深熟悉DSP的整个内部结构,主要包含有几个多少位的MAC,有几个多少位的ALU,有几个多少位的数据寄存器等等,还有外部数据总线上连接了哪些外设,内部数据总线是怎么连接的,并且这些数据总线是多少位,这些在Datasheet会有一张很清楚的DSP结构图,还有DSP的整个Memory Map是怎样的,片上有多少Data Memory,有多少Program Memory等等,了解这些其实就是让你知道DSP的运算性能到底可以达到多少,哪些外设会通过外部数据总线传输数据,DSP内部的寄存器是怎么传输数据的,通过这些可以帮助你解决你在开发中遇到的问题,不过最主要的是帮助你对已经编写完成的代码进行优化,我个人认为的优化方法有以下几种:
( ^* |. G5 ]7 O: b$ |  1、一般编写代码首先是用C,基于C层面优化的方法,我如下举例说几种:
! R/ j" b1 P8 p2 k    (1)优化循环/ u) i- k/ P1 l5 \9 w3 S9 C. }
    for(i = 0;i < max;i ++)( O8 Y& p- ^/ x5 v$ X) f
     {
, r6 G6 F: D$ S6 u; m9 }  ?1 Z, Y        for(j = 0; j < max; j ++)
- ~5 v/ p) m, o# I0 z        {
& O! m$ [1 M, b+ m3 s" A- y, w2 O) M0 q            float sum = 0.0;
0 h. Y6 L+ G- B1 A4 [            for(k = 0; k < max; k ++)2 x. ^8 c* n8 w. I5 O* n; X- w; g1 w: o
            {4 R, x$ d' c0 |9 M; q' B. ^. O
                sum += input[i * max + k] * input[j * max + k];: |- T, V9 T4 |( [* b
            }
7 G8 n" }4 ~; F' \: ~  V1 c5 Z( }' \/ E            cover[i * max + j] = sum / max;
( K$ j3 e) c7 f7 h) v' q$ m        }9 {: o- \( O2 A* m% y( u1 Z: @+ g
    }3 P0 i$ v: ^! c6 Y) y" l
    实例,如input[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},得出的cover如下:! P! p; R' t$ V* {9 a! {
     7    17   27   37  e6 w! z2 D# L0 H
     17  43   69   95
' O, r% J& U$ ~3 [4 n     27  69  111  153
- h2 s* C, M+ W+ v( i     37  95  153  2114 |2 t& D! Y, a& S9 g" P8 x
    图示:
2 T2 ^+ X/ I* D- _( K    ( }- Z, e1 c  d0 O, J4 o. X
    原理:只需要得到左上角或右上角即可,然后半个矩阵赋值给另半个矩阵即可得到整个矩阵。$ ~1 k8 Z5 J  [1 l
    算法优化后:! Y, Q- B( [. {/ ]& |& J+ L$ _
    for(i = 0; i < max; i ++)# q: U; u& B1 ~% I+ {& t1 \
    {
! ^8 h" M, n' w1 k3 }/ H. R; Q  `        for(j = i; j < max; j ++)                  // 减少一半循环0 P) s/ ^4 Q8 X) x
        {
  v/ R  @5 a" ^3 G" B/ s5 ~: s            float sum = 0.0;6 M4 d8 y, g% S$ I) x% W( F+ I
            for(k = 0; k < max; k ++)( @) I( Z0 C5 j) j/ K: T
            {
4 O) a$ @  x# c+ i2 w! c                sum += input[i * max + k] * input[j * max + k];4 H2 y; [, F) A) R
            }8 O8 ]+ n6 h5 w; ~
            cover[i * max + j] = sum / max;
% ?, S) z# q  l4 H% S2 g  ?5 _            if(i != j)                    // 可加可不加,消除中线上的重复赋值
6 v/ C- |2 c/ p+ G. b0 x5 P            {/ X8 K& N. [5 Z1 }* M7 d0 I& Y
                cover[j *max + i] = sum / max;       // 赋值给另半个矩阵9 N7 T4 v; i0 H/ ]* `
            }
' k6 s- J7 G; C8 [+ x        }) ^  `/ C6 X! i
    }; L) [# d2 D6 u# z- q9 F
    (2)条件跳转(使用条件跳转会在流水线中浪费更多的周期)
5 g. [: d3 F# ?1 S# Y0 h    k = k -1;) V( h1 E) S! w* h, Z; J5 b9 v
    if(k < -1)4 x9 H( x6 y4 c3 ^, F
    {. O9 d- L# Z; K+ O( r/ |
        k = -1;5 C6 s* |6 c9 `: }# n
    }
( T, C- z7 ^9 w& ~; A    原理:C语言中的max函数在编译的过程中实际上实现的是DSP中的MAX指令。) l& K$ i/ j) }: y
    优化后:" i2 L& f  O  Z5 ]/ G) c
    k = max(k-1, -1);) y! ~' M# l0 O) z' e9 A
    转换成汇编后:" i) v4 C& I3 Z# t$ U/ O" D& P) k# N- P
    R0 += -1;    // R0 == k;* f: P, V% B* O( A4 I- L# f
    R1 = -1;
) B# H/ C6 x: G5 X3 V  n    R0 = MAX(R0, R1);% k8 ~/ K; V6 @$ _9 D9 a$ \
    (3)for循环中的条件跳转/ O8 o& H* i' V" m  S5 Q& _
    for
$ X7 P( a' z6 }/ V    {' ^/ ^5 V7 Y3 i* [, A! R
        if{...}else{...}1 T) R$ \& W: `7 ^( w) ?6 \0 f. ~2 \
    }3 E  M) y8 g  ]- D$ ]; `# k0 D
    原理:减少频繁的条件跳转,当然并不是所有的情况都可以这样做。+ ?4 R7 J0 u; X/ q" _
    优化后:" s  q* \' G. M  R; W
    if# t4 q1 H' X% ?% w2 ~
    {: A% g* C: B" _$ X" E+ B
        for{...}
$ \9 e" _. N' @3 N) j& p% w    }  s. Q& e! ]  G& _2 K
    else
1 x( Q$ W+ `9 x# B    {% M  @! G- v- T2 m; S3 [
        for{...}3 S& I. n( ]4 Y
    }
; z3 r' H1 B$ V( ^& G* D    (4)使用断言指令来避免条件跳转, ]3 B0 E# C% L/ `! ?/ e
    if(A)
" Q- l5 W, |. F% h- {    {
% d6 T3 b' D+ c& K; X/ Z' m        X = exp1;1 J6 y1 G0 e) y7 T( l7 h
     }2 Z% U; V7 F' X8 C$ u3 [
    else
7 b8 T: I4 x" @9 ^0 O9 C    {
* L" ]0 u" [# C( F% I$ }5 m        X = exp2;
, x# M2 O5 G% E" s$ M4 M    }    
/ ]; }4 i* R% [5 T5 N    原理:使用断言指令IF(CC) REG = REG,只会消耗一个周期。% d' x; Z& P5 ~: T: j# N' j# {+ L! o
    优化后:" l" P4 Z; M' |# v5 _/ V$ ~
    X = exp1;4 x/ h& R7 u5 \# Z; G! Y
    if(!A)
5 J( K, ]7 q" P8 ?0 ^    {! d/ Q; w8 x! r; O$ ~" ]& m
        X = exp2;* v+ _/ |5 H! V; l  u
    }
& L" F3 ?; e0 B" g5 k" u8 W7 A9 i    (5)除法(取模)操作
/ m- u/ o8 t, X5 o    一般DSP中不支持除法,除法操作是通过仿真的方式来进行实现,有两种,分为低精度和高精度,但都需要相大多的周期。
% K8 k( o- l% F, l" p& B    除数为2的N次方时可采用右移法。
5 o/ f4 C" X' H    如为提高性能,可采取查表的方式,这样会损失精度。; l! ]& P6 A# O7 W# F. w
    隐藏的除法:
7 k% w8 B- B$ C# p) r! ]        for(i = start; i < finish; i += step)
! z* P3 ?2 i5 M9 q0 ^        此时编译器会looper = (finish - start) / step 得到次数。9 m3 a9 y# e  \# Z7 e6 k0 w
    巧妙利用不等式法测:(不过可能会产生溢出,要小心使用)
: P% n! B, i% L  o* M( `- e        if(x / y > a / b); U% [5 q1 V# O& Y
        可转换为:4 v: b9 i6 o1 g! v; I
        if(x * b  > a * y)+ U! U, w8 D5 |
    (6)数据类型
9 j- a( W# p6 `& \    对于定点DSP而言,对于浮点的操作是用仿真的方式实现的,会消耗很多周期,所以在定点DSP上对于浮点数一般是做定点化的处理,常用的方法我举一个例子:2.5 * a,其实可以转换成80 * a >> 5,不过在定点化时需要注意防溢出。
6 b( a* f0 U/ z2 z: v4 O. H    对于64位数据,也是用仿真的方式实现的,会消耗很多周期。(一般最大仅支持32位数据)
- W' \( U  a( T/ P; T. }5 a9 w    做数字信号处理操作时,如FFT,16bit的操作是比较合适的。
; Q+ z% Z' J  q- U    要做控制类,条件跳转时,32bit的操作是比较合适的。
  w  E4 C- w$ {% J    如你的DSP的MAC是16位的,做乘法时,尽量定义成16bit数据。
" `. S! D2 p/ O; p" o    (7)Memory分配
  r- G9 ]# \! ?; a- b6 e    将运算比较频繁的数据和程序段放入片内Memory,开启cache。
0 U% W. z  ^6 T0 u    如DSP能对SDRAM的不同4个bank可以同时访问,此时你可以将需要同时运算的数据放入不同的bank
. k, M2 T5 @: w  E1 q    (8)开启仿真软件的编译优化选项
9 {  \! W& R) x8 p! }5 w    在菜单相应的地方勾上即可,但值得注意时,开启自动编译优化选项后,可能会使执行的结果发生变化,所以需要测试对比一下未开编译优化选项之前的执行结果,一般来说,这个很方便,比较常用。
& i4 E& y7 T$ A, d/ X7 Z    以上8种是我常用到的优化方法,当然基于C层面算法类的优化还有很多种,这个需要慢慢积累,总结一下,一般来说先对C层面进行结构上的优化(上面的1-6均属于),然后进行Memory分配,开启仿真软件的编译优化选项,将运算频繁的程序段用汇编实现,当然如果性能满足要求,就没必要利用汇编了。
  G" |& y) n* F! q7 W  六、总结1 c( {6 Z' W* F& \0 ?
  我认为学习DSP软件开发没有什么捷径,我花了大量的文字在“弄清DSP相关资源的来源及熟读手册”上,实际上是想说,懂得获取资源是很关键的,只有熟悉手册才能完全去使用你所要开发的DSP芯片,其次DSP的主要特点就是高性能,能做一些算法类的运算,所以DSP的优化是相当重要的,关于算法优化的方法有很多种,基本可分为C结构上的优化及利用DSP的特点来进行优化,优化的学习是日易积累的,所以就要多看看相关的资料了。
4 ^& }) M1 n* D9 _  快速入门的步骤如下:, @) R& c0 T0 |: }& X
  准备一开发板,简单熟悉一下手册及仿真软件,对照着例程看手册,然后再改例程,看是否能按你的意愿去实现,最小系统和每个外设都熟悉一边,恭喜你,你入门了,待续。。。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 支持!支持! 反对!反对!

162

主题

614

帖子

1255

积分

四级会员(40)

Rank: 4Rank: 4Rank: 4Rank: 4

积分
1255
2#
发表于 2016-5-16 13:51 | 只看该作者
楼主很用心啊!8 S. [5 q) |" [
感谢感谢!

156

主题

503

帖子

1186

积分

四级会员(40)

Rank: 4Rank: 4Rank: 4Rank: 4

积分
1186
3#
发表于 2016-6-1 16:26 | 只看该作者
$ S/ L% I% V3 }0 m
haohao

159

主题

527

帖子

1197

积分

四级会员(40)

Rank: 4Rank: 4Rank: 4Rank: 4

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

本版积分规则

关闭

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

巢课

技术风云榜

关于我们|手机版|EDA365 ( 粤ICP备18020198号 )

GMT+8, 2025-2-19 06:09 , Processed in 0.056039 second(s), 32 queries , Gzip On.

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

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

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