2011-07-12 by zony
定点仿真方法的学习笔记(一)
在用MATLAB工具对算法进行仿真时,数据的流动是以浮点形式进行的,浮点型又分单精度浮点型和双精度浮点型。浮点型数据的存储方式为 符号位 指数位 尾数位 单精度浮点型数据用32 bit 来存储数据,其中符号位1 bit,指数位8 bit,尾数位23 bit。双精度浮点型数据则用 bit 来存储数据,其中符号位1 bit,指数位11 bit,尾数位52 bit。
这样的数据存储方式能够保证一个数的精度。但是在考虑硬件实现的时候(如FPGA,定点DSP),数据的流动是以固定长度的二进制序列进行,因此,为了进一步的反映硬件实现中算法性能,我们需要对数据的类型做重新的定义,使得所表示的数据更符合硬件平台上的处理方式。
做定点仿真实际就是对算法中的每一个数据进行量化,用规定字长的二进制序列表示一个数,使它接近实际值。为了方便对数据类型做定点转换,MATLAB提供了强大的Fixed-Point Toolbox 来帮助我们做这项工作。以下的所用内容只是个人对Fixed-Point Toolbox 学习的总结,如有任何疑问,请查找HELP 中的相关内容,理解上如有错误,恳请斧正。
先介绍几个对象给大家认识,也就是Object,个人认为定点的过程就是让数据在 fi这个对象下进行工作。
fi 对象
当你用 fi 这个函数对一个数据进行定点处理时,你就构造了一个fi 对象(说白了也是一个数,你规定了这个数的数据类型)。你可以对这个对象进行运算。与一个数不同的是这个对象有很多的属性,在这里先把它们中常用的列出来,并对它们做一些简要说明,后面会用实例告诉大家怎么去理解这些属性。
Data 属性
该属性可以让你了解一个fi对象在不同的数据形式下的具体值,如二进制(bin),八进制(oct),十进制(dec),十六进制(hex),双精度(double)等等。 fimath 属性
该属性规定了fi 对象在进行数据运算时,处理数据的习惯(数算,截位方式,溢出方式)。它是一个比较抽象意义上的属性,你可以用另一个对象对它进行定义。当你要定义fi对象的fimath属性时,你需要先定义一个fimath的对象,再用fimath对象定义fi对象的fimath属性。将在fimath对象中介绍。 numerictype 属性
该属性包含了fi对象的所有数据类型信息。它是一个比较抽象意义上的属性,你可以用另一个对象对它进行定义。当你要定义fi对象的numerictype属性时,你需要先定义一个numerictype对象,再用numerictype对象定义fi对象的fimath属性。将在numerictype对象中介绍。
fimath 对象
该对象的常用属性如下:
CastBeforeSum 属性
在两个操作数进行加法之前,是否将操作数影射成“和”的数据类型。“0”表示“否”,“1”表示“是”。例如,若两个操作数(对象)是18 bit,定义“和”为12 bit,若该属性为“0”,则两个操作数先进行“加”操作,然后对“和”截位得到12 bit输出,若该属性为“1”,则两个操作数先截位成12 bit,然后再进行“加”操作。
2011-07-12 by zony
OverflowMode 属性
若有溢出,溢出值按两种方式处理。
saturate 方式:若数据发生上溢出,则该数据用能表示的最大数替代, 发生下溢出,则该数据用能表示的最小值替代。例如两个4 bit有符号数,5和4,二进制分别表示为0101和0100,5+4=9,而4bit 能表示的有符号数的范围为 -8到7,所以发生上溢出,此时5+4所得结果为7。
wrap 方式:若有符号数据发生溢出,则进位将取代符号位,所表示的数据将以二进制补码表示,若无符号数据发生溢出,则进位将被舍弃。例如两个4 bit有符号数5和4,二进制分别表示为0101和0100,5+4=9,而4bit 能表示的有符号数的范围为 -8到7,所以发生上溢出。wrap方式下处理溢出,0101和0100做加法,次高位的进位加到符号位,得到结果为1001,表示为-7。若两个3bit无符号数5和4,二进制分别表示为101和100,做加法后出现溢出,则进位舍弃,得到001,表示为1。 RoundMode 属性
对数据进行截位的方式,硬件实现时是直接截断,不考虑四舍五入,通常为 fix。 MaxProductWordLength 属性
当ProductMode 属性为FullPrecision 时,此属性有效,如果计算的积超过此属性定义的值,会出错。
MaxSumWordLength 属性
当ProductMode 属性为FullPrecision 时,此属性有效,如果计算的和超过此属性定义的值,会出错。
ProductMode 属性
做定点时,我们需要指定积的运算结果的字长,以及小数位的字长,此项通常为 SpecifyPrecision,此时,ProductWordLength 和ProductFractionLength 有效。 ProductWordLength 属性
指定积的运算结果的字长。 ProductFractionLength 属性
指定积的小数位的字长。 SumMode 属性
做定点时,我们需要指定和的运算结果的字长,以及小数位的字长,此项通常为 SpecifyPrecision,此时,SumWordLength 和SumFractionLength 有效。 SumWordLength 属性
指定和的运算结果的字长。 SumFractionLength 属性
指定和的运算结果的字长。 numerictype 对象
常用属性有 Scaling 属性
默认为:Fixed-point: binary point scaling。定点数据类型,量化由 WordLength 和 FractionLength 规定。 WordLength 属性
规定二进制序列的长度,用来表示指定数。 FractionLength 属性
规定二进制序列小数部分的长度,用来表示指定数的小数位。
2011-07-12 by zony
Singed 属性
是否为有符号数。默认为有符号。
实例:
首先用numerictype 和fimath两个构造函数生成两个对象。
对一个指定的数据进行定点操作:
生成一个 fi 对象。可以看到a的值经过fi量化以后与实际值0.6有细微的偏差,这是因为用12bit的字长,其中11bit表示小数的二进制数,所能表示的值是尽可能的贴近实际值。
可以显示出a的二进制形式,还可以显示十六进制(a.hex),双精度(a.double)等等。这就体现了fi对象的Data属性。
再定义另一个fi对象
2011-07-12 by zony
当对a,b两个对象执行加法操作时:
最后的输出c字长为10bit,其中9bit 表示小数位。这就体现了fimath属性中的乘法操作的子属性。
当对a,b两个对象执行乘法操作时:
2011-07-12 by zony
最后的输出d字长为15bit,其中14bit表示小数位。这就体现了fimath属性中的加法操作的子属性。
定点的过程就是利用fi对运算过程中的每一个环节的数据进行定点处理,使得数据的流动更加符合实际硬中的处理方式。
定点仿真方法的学习笔记(二)
算法中经常会遇到FIR数字滤波器,浮点仿真时,已知滤波器的系数即可对数据进行滤波。定点仿真则非那么简单,需要对滤波器进行浮点到定点的转化。首先我们来看一个定点滤波器的结构。
2011-07-12 by zony
上图是一个转置直接型结构的FIR滤波器,数据流动的如图所示。从图中可以看出各个点的数据格式都需要进行规定以符合硬件习惯,当滤波器的抽头系数很多时,人为地规定每个点的数据格式,是一个复杂而繁重的工作。我们可以定义一个滤波器对象(filter object),通过配置此对象的属性来完成滤波器的浮点到定点的转化。
我们以上图所示的转置直接型FIR滤波器为例。
首先得到一个FIR滤波器的系数(具体用法参见 help Filter Design Toolbox) 以微分器为例
得到一个微分器。
做滤波器定点转化首先要构造一个滤波器对象(filter object)
浮点到定点的转化就是配置这个滤波器对象dfilt.dffirt的属性,下面列出它常用的一些属性:
Arithmetic
设置为 fixed,表示你有权限修改其他滤波器的属性来定制你需要的定点滤波器。 CoeffAutoScale
默认为 ture,当设置为 false 时,你可以通过设置NumFracLength属性来指定滤波器系数的小数部分的字长。 CoeffWordLength
指定滤波器系数的字长。 NumFracLength
指定滤波器系数小数部分的字长。
2011-07-12 by zony
InputWordLength
指定滤波器输入数据的字长。
InputFracLength
指定滤波器输入数据小数部分的字长。 FilterInternals
默认为 FullPrecision,表示该滤波器的输出以及滤波过程中内部乘法器、累加器的输出字长、小数部分字长都保持最好精度;SpecifyPrecision,表示该滤波器的输出以及滤波过程中乘法器、累加器的输出字长、小数位字长都以指定属性为依据。 ProductWordLength
指定内部乘法器输出字长。 ProductFracLength
指定内部乘法器输出小数部分字长。 AccumWordLength
指定内部累加器输出字长。 AccumFracLength
指定内部累加器输出小数部分字长。 OutputWordLength
指定滤波器输出字长。 OutputWordLength
指定滤波器输出小数部分字长。 RoundMode
同 fimath 属性。 OverflowMode
同 fimath 属性。
配置定点滤波器的属性需要做两个工作:1)量化滤波器系数。2)分析滤波器的动态范围,防止滤波过程中发生溢出。
滤波器系数的量化直接通过分析滤波器系数的范围,配置合适的【字长,小数部分字长】。
通过fvtool可以看到量化以后的滤波器幅频响应与浮点的比较
2011-07-12 by zony
Magnitude Response (dB)10Filter #1: QuantizedFilter #1: Reference0 -10Magnitude (dB)-20-30-40-50 00.10.20.30.40.50.6Normalized Frequency (×π rad/sample)0.70.80.9
可以看出系数量化后的滤波器幅频响应与浮点相差很大,所以应该适当提高系数的字长
10Filter #1: QuantizedFilter #1: Reference0
Magnitude Response (dB) -10Magnitude (dB)-20-30-40-50 00.10.20.30.60.50.4Normalized Frequency (×π rad/sample)0.70.80.9
对细节进行放大
2011-07-12 by zony
Magnitude Response (dB)Filter #1: Quantized0.442Filter #1: Reference 0.4410.440.439Magnitude (dB)0.4380.4370.4360.4350.434 0.33480.33480.33480.3348Normalized Frequency (×π rad/sample)0.33480.3348
观察量化后的滤波器和浮点滤波器的幅频响应相差很小,已经可以符合要求。在实际中,可以根据工程经验对字长进行设置。
最后可以查看滤波器对象的其他属性
动态范围的分析则首先需要确定滤波器的输入数据的范围,固定内部各点的乘法器、累加器的输出字长,然后设计一个最差情况下的输入数据,并针对该最差输入数据,检查滤波器是否发生溢出。
若滤波器输入数据的范围为[-1.9,1.9],则设计的最差情况下的输入数据为
打开数据记录模式
对数据进行滤波
关闭数据记录模式
2011-07-12 by zony
输出报告
得到报告如下:
从报告中可以看出,Input项发生了溢出,这是因为输入数据字长与小数部分字长的比例不合适,需要做调整,若内部发生溢出,则需要对滤波器内部各点的乘法器、累加器输出的小数部分字长长度做调整。
自动调整内部各点的字长比例(字长与小数字长的比例)
重新生成报告,打开数据记录模式
对数据进行滤波
关闭数据记录模式
输出报告
得到报告如下:
显示滤波器的属性配置
2011-07-12 by zony
以上过程就是对滤波器动态分析的过程,在这里我们只对滤波器系数指定了字长,其他属性为默认的,在此只是介绍滤波器动态范围分析的过程,在定点过程中需要根据实际情况对滤波器的各个属性进行设定。