关于C6000的寻址
C6000提供32bit的寻址能力,但是经EMIF直接输出的地址信号只有EA[21:2],直接使用这个地址可以达到1M word的寻址,EA的最低2位译码后有BEx输出,所以结合BEx可以进行Byte访问,即4M Byte寻址,这是每个CE空间的范围,对于整个CE空间(CE3:0)就是有16M Byte的外部存储器寻址能力。
注意:对于C620X/670X来说,EMIF支持32bit宽度的ASRAM、SDRAM和SBSRAM,只有CE1空间支持16bit和8bit的ROM接口。
遗留问题,为什么会有4位BE(BE3:0),如何使用?
No comments yet.
No trackbacks yet.
在TMS320C62x上实现扩展精度的复数基2FFT/IFFT算法
about 3 years ago - 2 comments
本文翻译自TI的文档《spra696a_Extended-Precision Complex Radix-2 FFT_IFFT Implemented on TMS320C62x.pdf》。——哎,没过CET4,看E文就是累啊!
— 文首预览 —
定点DSP有限的动态范围导致在计算FFT时精度不够。这是因为使用了量化和缩放来防止输出溢出。因此,会需要使用扩展精度来执行计算,特别是对于大尺寸的FFT。高度优化的扩展精度的FFT和IFFT汇编程序,可以在TMS320C62X上,通过适度增加运行时间来提高运算精度。
目录:
1. 快速傅立叶变换FFT
2. 快速傅立叶反变换IFFT
3. 精度扩展的需要
4. C62x上的扩展精度乘法
5. FFT的实现
6. IFFT的实现
7. 比例缩放问题
8. 误差估计
9. 基准(Benchmarks)
10. 输出位反转
11. 代码
12. 参考文档
注:本人E文极差,请慎重考虑是否要下载全文!
全文下载地址
DSP中数的定标
about 3 years ago - 4 comments
在TI的文档<spru402 _TMS320C62x DSP Library Programmer’s Reference>中,提到了Q格式。关于这个,我手上的两本书,都没有提到,而TI的这个文档里也只是在附录里简单说明了一下。大意是:DSPLIB函数一般都使用Q15格式。其实这个Q15确切的说是Q0.15。格式是Qm.n,m指小数点前(即整数部分)的数的个数,n指小数点后(即小数部分)的数的个数,再加上最高位是符号位,这样Q15就是一个16位的word。它表示的范围是(1,-1)。它表示的数分辨率是2的-15次方,数是用2的补码来表示的。
如此,既然可以有Q.15,那也可以有Q.31,当然也可以有Q3.12这样形式的。可以看出,不同的Q所表示的数不仅范围不同,而且精度也不相同。Q越大,数值范围越小,但精度越高;相反,Q越小,数值范围越大,但精度就越低。范围与精度是一对不可调和的矛盾,实际应用中,只能视实际需要来取平衡。
有了Q格式,就可以用定点DSP来计算浮点数。
———- 关于补码相关知识的温故知新 ———-
原码就是这个数本身的二进制形式。如:00000001 就是+1 10000001 就是-1。 反码表示法规定:正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。 补码表示法规定:正数的补码与其原码相同;负数的补码是在其反码的末位加1。
补码的意义: (1)补码统一正0和负0 (2)补码中符号位要与有效值部分一起进行运算。 (3)使减法运算转换为加法运算。 [a-b]补=[a]补+[-b]补
链接1:关于补码的详细介绍
链接2:DSP定点算数运算
FFT在C6000DSP上的仿真
about 3 years ago - 1 comment
经过一段时间的学习,今天在CCS内成功仿真了基2频域抽取FFT(radix2 DIF FFT)。
环境:CCS 3.1 + C6201 Device Simulator
仿真结果如下图:
全部代码在下面,为了描述简单,把所有函数写在了一起,实际运用中不应该这样做。另外位反转索引表和旋转因子表都是在里面实时生成的,实际运用时,应该做好表格后嵌入,或在编译时生成而不是运行时生成。
感谢 pacificxu 的教程,他貌似曾经是闻亭的高手。
#include “math.h”
/*========================================*/
/* GLOBAL CONSTANTS */
/*========================================*/
#define PI 3.14159265358979
#define N 2048
/*========================================*/
/* GLOBAL VARIABLES */
/*========================================*/
static short index1[64], w1[N];
static short x1[N*2];
static int x2[N];
int i;
void DSP_radix2(int n, short *restrict xy, const short *restrict w)
{
short n1,n2,ie,ia,i,j,k,l;
short xt,yt,c,s;
n2 = n;
ie = 1;
for (k=n; k > 1; k = (k >> 1) )
{
n1 = More >
CCS的一些问题(转)
about 3 years ago - 3 comments
来自DSP交流网
CCS版本:V3.1
1.run和animate的区别
如果没有断点的话,这两个没区别.
如果有断点,那么run的时候到断点会停止,直到再次按run或者F5才继续执行.
而Animate到断点的时候,会停一小会,将所有窗口刷新一遍,然后就继续执行
一般就是在要看数据变化的时候,先把曲线画出来,然后在改变数据的循环里面设个断点,然后用animate,就能看到图片动态改变了,可以参考 Help->tutorial里面的”Code Composer Studio? IDE”->”Using Debug Tools”这一个教程
2.Probe Point 和Breakpoints的区别和联系
共性:他们都会暂停程序运行
区别:
1.Probe Point暂停程序,执行一个设定的任务(如File I/O),然后继续执行程序.而BreakPoint暂停后必须手动继续(当用run的时候)
2.BreakPoints会刷新所有窗口,而ProbePoint不会
3.Probe Point可以执行一些任务(如File I/O),而BreakPoints就是纯粹的停止.
3.阻塞(blocked)和中断(interrupt)的区别和联系
共性:他们都能停止一个tsk(任务,具体见我的另一篇文章:关于tsk和mbx)的执行
区别:
1.只有tsk(任务)能被阻塞,而swi(软中断)和hwi(硬中断)不能阻塞,只能中断
2.停止的原因不一样,阻塞是在某些条件不满足的时候停止tsk,中断是因为有高优先级的事情要做而停止
3.恢复运行的条件不一样,阻塞是要等到原来不满足的条件满足后才能继续,而中断是要等高优先级的任务返回后才继续执行.
4.阻塞改变tsk的任务队列,而中断一个tsk不会改变tsk的任务队列.
举个现实的例子:
如果你在写作业,写着写着,碰到一道很难的题,你百思不得其解,这个时候写作业的这个tsk就被阻塞了,只有等到你想出来这道题怎么做,才能继续做下去.
另外一种情况,还是在写作业,突然门铃响了,你必须去开门,那写作业这个tsk就被中断了,你开完门就能回来继续写作业.
4.LOG_printf和printf的区别和联系
共性:都是用于输出一些内容,一般用于显示一些调试信息,而且可以格式化输出,比如用’%d’输出整数
区别:
1.输出目标不同,printf输出到output窗口,而LOG_printf输出到BIOS的log窗口
2.汇编指令条数不同,printf需要上万条汇编指令,而LOG_printf只要30多条汇编指令,因此LOG_printf的运行速度比printf要快的多,一般在实时系统中,都使用LOG_printf来输出,这样对系统的实时性影响才不大
3.参数个数不同,printf后面的参数个数可以有很多个(具体多少个没测试过),而LOG_printf后面最多只能有4个参数,第一个是写入的地址,第二个是字符串,后面最多加上两个格式化输出的数据,这两个数据还必须是整型,或者指针,或者常量字符串
4.可以输出的格式不同,printf有很多的格式,而LOG_printf只有有限的几种.(%d整型,%x无符号16进制数,%o无符号8进制数,%s常量字符串,%p指针)
5.LOG_printf输出的长度受设定的buffer大小限制,如果超出buffer大小,根据设置的不同,可以是停止输出,或者覆盖原来的内容
6.LOG_printf的优先级比较低,可能是在KNL层,只有系统比较空闲的时候,才会输出,而printf是必然会输出.(比如在一个i=1到 100的循环中,用printf就会输出100个数,而用LOG_printf就只会输出一部分数,而且在没有碰到断点的时候,根本不会输出,因为他的优 先级相当低,只有在走到断点的时候,系统才允许他执行.)
5.设置tab的宽度
1.打开”Option -> Editor -> language”
2.在左边的File Type里面选择要修改的扩展名(CCS中每种不同扩展名的文件都能设置不同的tab宽度,而不是象一般的代码编辑器,可以全局设置)
3.在右边顶部选择”Tabs/Indenting”选项卡
4.在”Tab Columns”下面的框中输入”3 5″(默认值是5 9,注意两个数值中间有空格)
5.点击OK按钮
解释一下”3 5″的意义,第一个数字等于在一行的最开头按Tab键时跳过的列数加1,第二个数减去第一个数的结果,等于除去每行最开头外的Tab的宽度.
设置成”3 5″表示如果在每行开头按Tab,缩进3-1=2列,而其它地方的缩进是5-3=2列,也就是无论什么地方Tab键的宽度都是2列.
个人觉得,CCS的这个设置Tab键宽度挺有意思的.
窄带随机信号分析的数学工具
about 3 years ago - No comments
窄带随机信号x(t)的数学表示:
- 发射信号的中心频率
- 慢变的随机函数
————————-
希尔伯特(Hilbert)变换
希尔伯特变换常在通信理论中用来处理窄带信号。
假定输入x(t)经过滤波器H(ω)后产生输出y(t)。如果H(ω)具有以下特性:
(1) 幅频特性是全通型的。
(2) 相频特性是-90°相移。
这时滤波器的输出y(t)便称为x(t)的希尔伯特变换,用 表示。H(ω) 称为希尔伯特变换器。
可见,它实质就是全频带的-90°相移网络。
————————-
解析信号和复数包络
将x(t)和它的希尔伯特变换结合起来组成一个复值信号:
xa(t) 就称为x(t) 的解析信号
那么对于窄带信号
它的希尔伯特变换:
它的解析信号:
定义:
则有:
式中: – 复数包络
- 包络函数
- 相位函数
当x(t)是随机信号时, x(t)、xa(t) 和 的功率谱之间有如下关系:
1. xa(t)的功率谱 的构成:将 的负频率部分取消,正频率部分加大四倍。
2. 的功率谱 的构成:将 沿频率轴向左移ω0,便得到了
上图为 x(t)、xa(t) 和 的功率谱
————————-
窄带随机信号的正交分量表示法
对于窄带随机信号
可以用三角函数的和差公式展开成
式中:
上式称为窄带信号的正交分量表示法。
如果把nc(t)和ns(t)合成复值信号v(t)=nc(t)+jns(t),则有
可见,v(t)就是x(t)的复数包络函数,它的功率谱应该具有上图所示的特征。
CCS中DSP的编译连接
about 3 years ago - No comments
源代码,经编译器,生成可重定位的代码块和数据块(称为段-section).
然后经连接器,将这些段分配到目标存储器。
可通过.cmd文件用两个伪指令来定义连接:
memory – 定义存储器各部分的起始地址和长度
sections – 定义把各个段放在存储器的什么位置
可通过生成.map文件来观察代码和数据空间的映射关系。
CCS例程中的一个.cmd文件如下:
MEMORY
{
IPRAM : origin = 0×0, len = 0×10000
IDRAM : origin = 0×80000000, len = 0×10000
}
SECTIONS
{
.vectors > IPRAM
.text > IPRAM
.bss > IDRAM
.cinit More >
数字信号处理的基本概念
about 4 years ago - No comments
线性时不变系统:数字信号处理涉及的是离散时间系统,其中最经常遇到的是线性时不变系统,他具有如下特征:
1. 叠加性和均匀性 – 即线性
2. 时不变 – 含义是,同样起始条件下系统响应与激励施加于系统的时刻无关。
卷积:如果一个线性时不变系统的单位冲激响应h(n)已知,那么对于任意输入x(n),系统输出y(n)为:
— * 表示卷积运算
傅立叶变换:
连续时间函数f(t)的傅立叶变换为 —
式中,F(ω)是f(t)的频谱函数,一般是复函数,可写成:
F(ω)=| F(ω)|·ejψω
| F(ω)| — 模,代表信号中各频率分量的相对大小
ejψω – 相位函数,表示各频率分量之间的相位关系
时域卷积定理:
两个时间函数卷积的频谱等于两个时间函数频谱的乘积,时域中两信号的卷积等效于频域中两频谱相乘
频域卷积定理:
两时间函数频谱的卷积等效于两时间函数的乘积。
实际应用中更常用的是离散傅立叶变换DFT和快速傅立叶变换FFT。同样的,对于离散系统,被抽样后的时间函数与周期性的频谱函数相对应,被抽样后的频谱函数与周期性的时间函数相对应。
数字信号处理的时域处理方法
1. 叠加平均 – 用来消除测量信号中存在的平稳随机噪声,改善信噪比。
2. 插值
3. 相关分析 – 能从噪声背景中找出同一信号两部分之间或两个信号之间的相互关系,以判别其相似性,并从中提取有关信号的特征。
自相关 – 能显示信号本身的某些特征,如信号的周期性、信号中噪声的带宽等。经常用自相关函数识别一个数据流内部的周期性,并利用相关性从随机噪声背景中提取周期信号。
— τ- 延时时间
互相关 – 能表征两个信号之间的相似性,或者在多个信号间确定哪两个信号关系更密切。
数字滤波
按单位冲激响应的时间特性分为:IIR FIR
按构成方式分为:递归式 非递归式
IIR只能用递归式结构实现,FIR一般用非递归式结构实现。
功率谱(谱密度)
对于确定性信号可以用频谱来描述信号的频域特性,对于随机信号,通常用功率谱来描述信号的频域特征。
功率谱密度函数(功率谱)与信号的自相关函数是一对傅立叶变换。(维纳-辛钦定理 Wiener-Khinchin theorem)
Sx(ω)反映的是信号功率在频域的分布情况,不包含相位信息。
关于 关键字 restrict
about 4 years ago - 6 comments
为了帮助编译器确定存储器相关性,可以使用关键字restrict来限定指针、引用或数组。关键字restrict是对指针、引用或数组的一种限定。使用restrict关键字是为了确保其限定的指针在声明的范围内,是指向一个特定对象的唯一指针,及这个指针不会和其它指针指向存储器的同一地址。这使编译器更容易确定是否有别名信息,从而更好地优化代码。
下例中,关键字restrict的使用告知编译器func1中指针a和b所指向的存储器范围不会交叠,这表明通过指针变量a和b对存储器的访问不会冲突,即对一个指针变量的写操作不会影响另一个指针变量的读操作。
void func1(int * restrict a, int * restrict b)
{
/* func1’s code here */
}
To help the compiler determine memory dependencies, you can qualify a pointer, reference, or array with the restrict keyword. The restrict keyword is a type qualifier that may be applied to pointers, references, and arrays. Its use represents a guarantee by the programmer More >
关于MAP文件的一点认识
about 4 years ago - 1 comment
转载自 hellodsp 论坛,作者: huttu
MAP文件是CCS软件编译后产生的有关DSP用到所有程序、数据及IO空间的一种映射文件。
一、生成方法
MAP文件主要有两种生成方法,一种是由系统自动生成,默认文件名为所建立的项目名(如XXX为项目名)加上.map后缀xxx.map,另一种在CMD文件中指定生成MAP文件,操作方法为在MEMORY指令前面加上“-m abc.map”,文件名可以任意。
二、文件格式
MAP文件大概分为文件头、内存配置、段映射、全局符号四部分。内存配置与CMD文件中的MEMORY指令关联,在CMD文件中定义的程序与数据区间定 义,在该部分均可以找到对应,与CMD文件不同的时,在MAP文件中加入了一个实际使用的区间,即在程序中实际用到的空间长度。段映射部分与CMD文件中 的SECTION指令关联,在该部分程序中所有的段实际映射的起始地址与实际长度均有详细说明。可以具体到程序中PROGMA指定的段和各个单独文件产生 的OBJ文件。全局符号可以是程序使用的每一个函数、程序中定义的全局变量均可以在此找到对应的起始地址。MAP文件中采用两种方式列举,一种为按相应地 址排列,另一种按全局符号字母排列。
三、存储地址
MAP文件默认保存在所在项目下面,由CMD文件产生的MAP文件保存在该项目的DEBUG目录下面。
关于C6000DSP的堆(heap)和栈(stack)
about 4 years ago - No comments
stack -
又称系统栈(system stack),用于:
保存函数调用后的返回地址;
给局部变量分配存储空间;
传递函数参数;
保存临时结果;
heap -
编译器提供的运行时支持库的一些函数(如malloc/calloc/realloc),允许运行时为变量动态分配存储器。这些存储器就放置在.system段的全局池(global pool)或堆(heap)中。这个动态存储池的大小仅仅受限与系统中实际的存储容量。
这2个选项都可以在project-build options的连接器选项中设置
《TMS320C6000系列DSP编程工具与指南》P126