C6000 DSP优化技术入门
参考资料
SPRU198K-TMS320C6000 Programmer’s Guide
SPRUGH7-TMS320C66x DSP CPU and Instruction Set Reference Guide
主要是看了SPRU198K这个文档里的第三章,这一章里有5个Lesson,非常详细地介绍了一些很实用地优化方法。
在看这个之前最好对DSP数据路径和功能单元有了解,可以看SPRUGH7这个文档。只有充分发挥出8个功能单元的性能才能说是开发DSP,不然就只是单纯的C/C++开发。哦!还有我觉得起始看第三章之前可以先看一下第四章,第四章介绍了编译器反馈给用户的汇编文件中的一些短语的含义。
一些准备
DSP优化的过程并不是自己去写汇编而是尽可能多地告诉编译器一些信息,让编译器帮我们优化。
在工程选项中勾选上-mw和-k,那样可以在编译后生成汇编文件并且有软件流水线相关的信息,便于后续分析。
Lesson1 - 循环内部依赖
以两个向量的线性乘加运算为例:
sum=∑iω1xi+ω2yisum = \sum\limits_i { {\omega _1}{ ...
硬件FFT加速模块的应用
软硬件FFT性能测试
FFT在很多算法中都有应用,M6678 DSP支持软件FFT(调用DSP库),和硬件FFT(有一个独立的FFT硬件加速模块)。
测试条件
操作系统 Win11
CCS 6.2.0
CGT-Tools 7.4.4
XDCTools 3.25.5.94
SYS/BIOS 6.33.6.50
DSPLIB C66x 3.4.0.4
MATHLIB C66x 3.1.2.4
256kB L2 Cache, 32kB L1P/D Cache
堆区放在DDR,待处理数据与结果数据都在堆区开辟;
待处理的数据均为单精度浮点数,实部虚部交叉存储;
处理器主时钟 1GHz
测试结果
1、 单次运算
软件FFT以调用FFT函数开始计时,Cache写回之后结束计时。硬件FFT以启动FFT计算开始,收到FFT完成中断后结束计时。
FFT点数
软件FFT
硬件FFT
32
1327 ns
5292 ns
64
1840 ns
5828 ns
128
3078 ns
6372 ns
256
3956 ns
6918 ns
可以看到单次FFT运算 ...
近期C6000 DSP开发小结
复数乘法指令
TI的编译器提供的一些内联函数中可以直接调用复数乘法的汇编指令(CMPYSP,只有C66x DSP支持),完成复数乘法运算。
src1和src2是连续的两个32位寄存器组成的register pair,dst是由四个连续的32位寄存器组成的register quadruplets。这里只是做了乘法运算。
然后用DADDSP指令可以对上面的结果中的实数部分和虚数部分分别求和,即可实现复数乘法。
(a+bi)(c+di)=ac−bd+(ad+bc)i\left( {a + b{\rm{i} } } \right)\left( {c + d{\rm{i} } } \right) = ac - bd + \left( {ad + bc} \right){\rm{i} }
(a+bi)(c+di)=ac−bd+(ad+bc)i
另外编译器也提供了一种快速实现复共轭乘法的方式,即p×q∗p\times q^*p×q∗。乘数中需要求复共轭的数qqq放在src1寄存器对中作为a+bia+b\rm{i}a+bi,另一个乘数ppp放在src2寄存器对中,依次完成CMPYS ...
Vivado远程连接调试
Vivado对计算机的性能还是有比较高的要求,平时出门带的轻薄本一般跑不了Vivado。即使能运行,肯定也不如台式机来得高效。所以要是能够通过远程连接的方式,通过远程的台式机上的Vivado来调试本地的设备就好了。
内网穿透
一般我们很少能直接有公网IP,不管是台式机还是笔记本都是连接到某一个局域网里,比如校园网。
远程连接
傅里叶分析概述
傅里叶变换主要分为连续和离散两大块。对连续时间信号的分析,从周期信号的傅里叶级数展开到统一的傅里叶变换(FS),是一套完整地体系。离散时间信号的傅里叶分析和连续时间信号的分析非常像,但确实是不同,没法统一地表示,主要区别在“求和”和“积分”上。FS,FT,DFS,DTFT,DFT构成了整个傅里叶分析的体系。
不管是哪种变换,都满足“周期-离散”,“非周期-连续”的对应关系。这个关系对帮助记忆非常有用。
分析方法
缩写
变换过程 时域信号 → 频域信号
傅里叶级数
FS
连续周期 → 非周期离散
傅里叶变换
FT
连续周期 → 非周期离散 连续非周期 → 非周期连续
离散傅里叶级数
DFS
离散周期 → 周期离散
离散时间傅里叶变换
DTFT
离散非周期 → 周期连续
离散傅里叶变换
DFT
离散非周期 → 离散非周期 (本质)离散周期 → 周期离散
连续时间傅里叶分析
傅里叶级数
连续时间的分析得从傅里叶级数开始讲起。
f(t)=f(t+T0) f(t)=∑n=−∞+∞ane−jnω0f(t) = f(t + {T ...
基于STM32的ADC采样序列频谱分析
本文主要介绍对ADC采集得到的数字序列进行FFT频谱分析。
理论分析
确定采样率除了要遵守奈奎斯特采样定律意外还需要考虑一些问题。在数字系统中,我们只能进行一些有限的离散的运算,对于有限长的序列,我们不可能拿它去做DTFT,只能做DFT。这就需要把有限长序列也当作一个周期序列来看待。
归一化角频率
已知采样率为fsf_sfs,那么一个频率为f0f_0f0(f0<fs/2f_0<f_s/2f0<fs/2)的理想余弦信号被采样后得到的序列应该是:
x[n]=Acos(2πf0⋅nT0)=Acos(2πf0⋅nfs) n∈Zx[n] = A\cos \left( {2\pi {f_0} \cdot n{T_0} } \right) = A\cos \left( {2\pi {f_0} \cdot {n \over { {f_s} } } } \right)\;\;n \in {\rm{Z} }
x[n]=Acos(2πf0⋅nT0)=Acos(2πf0⋅fsn)n∈Z
从上面的式子可以看出,我们实际得到的序列和具体的采样率或信号频 ...
SYS/BIOS与SRIO应用实例
RTSC与XDCTools
基于SRIO的FPGA与DSP间高速数据传输
AXI Memory-Mapped SRIO收发控制器
SYS/BIOS是TI的实时内核,也叫做TI-RTOS,它是RTSC中的一个软件包,可以使DSP的软件设计更加方便。SRIO是适用于嵌入式系统中的高速接口,之前我也写过一些相关的文章,这次做了一些完善。
系统功能
整个系统实现的功能大概如上图所示。DSP外接的DDR中存放有两张640×512的图片,DSP与FPGA通过一条1x的SRIO链路相连。DSP周期性地向FPGA发送门铃事务包,由FPGA内的MicroBlaze软核解析后,FPGA端发送相应的多个SRIO NREAD事务包,从DSP外接的DDR中读取特定地址区域的图片,然后通过VGA交替显示两张图片。
DSP采用的是TMS320C6455,FPGA端实例化MicroBlaze软核处理器,由它向SRIO收发控制器发送命令。
SYS/BIOS的使用
自从开始使用它以来,我觉得大部分情况下,我们都可以在这个实时内核的框架下来完成应用的设计。它的主要优势在于灵活,相较于传统的 ...
OpenMP在多核DSP上的应用
TI的多核DSP支持OpenMP,可以方便地使用多核来加速一些计算过程。
编译器
我使用的DSP是TI的6678,编译器可以是7.4或者8.x版本。7.4版本的编译器只支持OpenMP3.0版本,而8.x版本的编译器支持OpenMP3.0和部分的OpenMP4.0的功能。因为我使用的是7.4版本的编译器,所以后面只对OpenMP3.0相关的设置进行介绍。
参考资料
OpenMP 3.0 Specification
OpenMP 3.0 Summary Card C/C++
Specification里面介绍了OpenMP实现的机制,重点理解第一章里的“Excution Model”和“Memory Model”。Summary Card是一个总结,相当于一个API手册,可以用它方便地查找命令的语法。
实际OpenMP的使用除了查阅这两个文档意外还有一些需要注意的地方。
OpenMP模块
BIOSMCSDK-C66X
TI对OpenMP的支持,我在官网上只找到了这个SDK里有一个omp的模块,这个2.01.02.06应该是在网上能找到的最新的也是唯一的版本了。 ...
C++开发STM32 FreeRTOS工程与添加DSP库
续上一篇文章的内容。由CubeMX构建的Makefile工程只支持C和汇编的编译,而且FreeRTOS的代码也需要作为C代码编译。
当我们想使用C++时,需要做一些准备并且修改Makefile;另外本文补充了一下DSP库的调用方式。参考了另外两位博主的文章:
STM32 DSP库的快速添加 基于cubemx 调用,使用DSP库
C++开发STM32 Makefile工程
FreeRTOS与C++
FreeRTOS的代码是必须作为C语言编译的。C++可以调用C函数,而且也可以在C++的源文件里写C函数。但是C的源文件里不能调用C++相关的东西,比如在C源文件里创建一个类的对象是不行的。
所以我觉得最好的做法是把任务的定义放到自己的C++源文件中,而在FreeRTOS的C文件中用“extern”声明任务函数。
具体做法就是在用CubeMX创建Task的时候,把任务的函数都设置成external。这里的默认选项是既有声明又有实现;exteral选项就是只有一个带extern的任务函数声明;还有一个weak选项表示这个任务函数有一个默认的实现,但可以被外部的定义覆盖, ...
CubeMX+Eclipse+Jlink STM32开发环境搭建
Eclipse还是我用得最多的IDE,不管是CCS还是Xilinx的SDK,都是Eclipse的开发环境。所以最近准备做STM32相关的开发时,也准备用Eclipse。
软件下载与安装
STM32CubeMX
Eclipse
CubeMX是ST的用于生成初始化代码的工具,能大大提升开发的效率。Eclipse是一个开源的IDE,从官网可以下载到这个eclipse installer,然后选择Eclipse IDE for Embedded C/C++ Developers。目前官网的Eclipse版本是2022-03,这也是我目前用的版本。
Eclipse Embedded CDT,Eclipse的C/C++嵌入式开发工具是一个非常大的开源项目。
从项目的官网中可以看到,它还提供了一些额外的工具链接,包括build tools和gcc工具链。build tools用来生成Makefile,gcc工具链负责真正的编译和链接。这些工具包都是通过xPack管理的。
要说xPack得从JavaScript说起,有一个包管理工具叫做npm(Node Package Ma ...