IIR滤波器的浮点到定点转换
这个例子展示了如何使用定点转换器App将IIR过滤器从浮点转换为定点实现。当使用定点算法时,二阶截面(也称为双二次)结构比直接实现传递函数的结构工作得更好。我们将展示成功实现“浮动到固定”转换的最可靠路径包括以下步骤:
选择一个二阶截面(SOS)结构,即
dsp。BiquadFilter
对滤波器的每个节点进行动态范围分析,即使用带有模拟最小和模拟最大仪表的测试台架方法
使用'来比较不同的双二次伸缩实现和视图量化效果
fvtool
和年代pectrumAnalyzer
用于分析和验证。
简介
实现IIR滤波器的一种有效方法是使用二阶截面(SOS)双方滤波器结构。例如,假设我们需要从系统中删除一个干扰高频音信号。实现这一目标的一种方法是使用低通滤波器设计。
设计一个低通椭圆滤波器
为本例的目的,使用最小次低通椭圆直接形式I设计。该过滤器的设计规格为:
通带频率边缘:
阻带频率边缘:
通带纹波:
阻带衰减:
使用过滤器可视化工具可视化所有二阶截面的累积过滤器响应。
biquad =设计(fdesign.lowpass (“Fp,置,美联社,Ast”, 0.4, 0.45, 0.5, 80),...“ellip”FilterStructure =“df1sos”SystemObject = true, UseLegacyBiquadFilter = true);fvt = fvtool(biquad, Legend= .“上”);fvt.SosviewSettings.View =“累积”;
获取浮动与固定比较的滤波系数(SOS, B, A)
注意,SOS滤波系数值会导致几乎相同的滤波响应(无论它们是双位还是16位定点值)。
sosMatrix = biquad.SOSMatrix;sclValues = biquad.ScaleValues;fvt_comp = fvtool (sosMatrix fi (sosMatrix 1 16));传奇(fvt_comp“浮点(double) SOS”,“定点(16位)SOS”);
b = repmat (sclValues (1: (end-1)), 1, 3)。* sosMatrix (:, (1:3));= sosMatrix (:, (6));num = b”;分子截面的%矩阵穴= ';%矩阵的分母部分
关闭(fvt);%清理关闭(fvt_comp);%清理
默认的浮点操作
通过将一些数据流通过过滤器并查看其输入输出响应来验证过滤器操作。首先尝试滤波一个(浮点)伪随机噪声信号(300hz采样)与干扰加性高频音调,看看该音调是否被删除。这也将在以后作为我们测试台架的参考信号。
我们= 75 / (300/2);% 75 Hz音调;系统运行在300hzinp_len = 4000;%输入样本数(信号长度)inp_itf = 0.5。* sin((π*我们)。* (0:(inp_len-1)));%的语气影响范围=简介(SampleRate = 300,...PlotAsTwoSidedSpectrum = false,...ShowLegend = true, YLimits = 25 [-85],...Title =浮点输入信号和滤波器输出信号,...ChannelNames = {“浮点输入”,滤波器输出的});rng (12345);%种子RNG可重复的结果biquadLPFiltFloat = dsp。BiquadFilter(SOSMatrixSource=输入端口的,...ScaleValuesInputPort = false);为K = 1:10 inp_sig = rand(inp_len,1) - 0.5;%随机值范围(-0.5,0.5)Input = inp_sig + inp_itf;%组合输入信号,范围(-1.0,1.0)out_1 = biquadLPFiltFloat(输入、num穴);%过滤器范围([输入,out_1])可视化输入和过滤输出结束
清晰的范围biquadLPFiltFloat;%清理
默认的定点操作
现在,使用对象默认设置,通过过滤器运行一些定点数据。注意,默认的定点行为会导致不正确的结果。
范围=简介(SampleRate = 300,...PlotAsTwoSidedSpectrum = false,...ShowLegend = true, YLimits = 25 [-85],...Title =“定点输入信号和滤波输出信号”,...ChannelNames = {“定点输入”,“默认(错误)定点输出”});rng (12345);%种子RNG可重复的结果bqLPFiltFixpt = dsp。BiquadFilter(SOSMatrixSource=输入端口的,...ScaleValuesInputPort = false);为K = 1:10 inp_sig = rand(inp_len,1) - 0.5;%随机值范围(-0.5,0.5)inputFi = fi(inp_sig + inp_itf, 1,16,15);%信号范围(-1.0,1.0)out_2 = bqLPFiltFixpt (inputFi fi (num 1 16), fi(窝,1,16));范围([inputFi out_2])%可视化结束
清晰的范围bqLPFiltFixpt;%清理
将浮点的四边形IIR滤波器函数转换为定点
与其依赖对象的默认不动点设置,不如使用不动点转换器App将对象转换为不动点。这种方法在过滤器实现中产生了对单个不动点类型的更多可见性和控制,并导致更正确的不动点操作。
首先为使用定点转换器App做准备,创建一个要转换的函数,将所有过滤器数据类型选择设置为" Custom ":
类型myIIRLowpassBiquad;
函数输出= myIIRLowpassBiquad(inp,num,den) %myIIRNotchBiquad Biquad低通滤波器实现%用作MATLAB定点转换器应用程序的一部分。The MathWorks, Inc. persistent bqLPFilter;if isempty(bqLPFilter) bqLPFilter = dsp。BiquadFilter(…“SOSMatrixSource”、“输入端口”,…“ScaleValuesInputPort”,假的,…“SectionInputDataType”,“自定义”,…“SectionOutputDataType”,“自定义”,…“NumeratorProductDataType”,“自定义”,…“DenominatorProductDataType”,“自定义”,…“NumeratorAccumulatorDataType”,“自定义”,… 'DenominatorAccumulatorDataType', 'Custom', ... 'StateDataType', 'Custom', ... 'OutputDataType', 'Custom'); end output = bqLPFilter(inp, num, den); end
创建测试工作台脚本
创建一个测试台架来模拟和收集所有数据类型控制信号路径的仪器模拟最小值和模拟最大值。这将允许该工具稍后提出自动缩放定点设置。使用上面的部分代码作为测试台架脚本,从浮点输入开始,在模拟和收集最小和最大数据之前验证测试台架。然后,使用定点转换器App将浮点函数实现转换为定点函数实现。
类型myIIRLowpassBiquad_tb.m;
myIIRLowpassBiquad的测试台架。The MathWorks, Inc. %%预设计滤波器(系数存储在MAT文件中):% f = design(fdesign.lowpass('Fp,Fst,Ap,Ast',0.4,0.45,0.5,80),…%的ellip FilterStructure = df1sos, SystemObject = true);% sosMatrix = f.SOSMatrix;% sclValues = f.ScaleValues;% b = repmat (sclValues (1: (end-1)), 1, 3)。* sosMatrix (:, (1:3));% a = sosMatrix(:,(5:6));% num = b';% den = a';% (myIIRLowpassBiquadDesign攒钱。Mat ', 'b', 'a', 'num', 'den'); load('myIIRLowpassBiquadDesign.mat'); %% Interference signal, using values in range (-0.5, 0.5) Wo = 75/(300/2); % 75 Hz tone; system running at 300 Hz inp_len = 4000; sinTvec = (0:(inp_len-1))'; inp_itf = 0.5 .* sin((pi*Wo) .* sinTvec); %% Filtering and visualization % Filter an input signal, including an interference % tone, to see if the tone is successfully removed. rng(12345); % seed the rng for repeatable results scope = spectrumAnalyzer(SampleRate=300,... PlotAsTwoSidedSpectrum=false,ShowLegend=true,YLimits=[-125 25],... Title='Input Signal and Filter Output Signal', ... ChannelNames={'Input', 'Filter Output'}); for k = 1:10 inp_sig = rand(inp_len,1) - 0.5; % random values in range (-0.5, 0.5) inp = inp_sig + inp_itf; out_1 = myIIRLowpassBiquad(inp,num,den); % filter scope([inp,out_1]); % visualize end
使用定点转换器应用程序转换为定点
启动定点转换器App。有两种方式来启动该工具:通过MATLAB®APPS菜单或通过命令'fixedPointConverter'。
在入口点函数字段中输入要转换的函数。
通过输入测试工作台脚本名称来定义输入。
单击“Analyze”,通过模拟测试台架来收集范围。
观察收集到的“模拟最小值”、“模拟最大值”和“建议类型”值。
根据需要对“建议类型”字段进行调整。
单击“Convert”以生成定点代码并查看报告。
结果定点MATLAB实现
生成的定点函数实现如下:
类型myIIRLowpassBiquad_fixpt;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % 由MATLAB 9.3和6.0定点设计师 % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %# codegen函数输出= myIIRLowpassBiquad_fixpt (inp, num窝)% myIIRNotchBiquad Biquad使用低通滤波器实现%的MATLAB定点转换器的应用例子。%版权所有2016 The MathWorks, Inc. fm = get_fimath();持久bqLPFilter;if isempty(bqLPFilter) bqLPFilter = dsp。BiquadFilter(…'SOSMatrixSource', '输入端口',…“ScaleValuesInputPort”,假的,…“SectionInputDataType”,“自定义”,…“SectionOutputDataType”,“自定义”,…“NumeratorProductDataType”,“自定义”,…“DenominatorProductDataType”,“自定义”,… 'NumeratorAccumulatorDataType', 'Custom', ... 'DenominatorAccumulatorDataType', 'Custom', ... 'StateDataType', 'Custom', ... 'OutputDataType', 'Custom' , ... 'CustomSectionInputDataType', numerictype([], 16, 8), ... 'CustomSectionOutputDataType', numerictype([], 16, 8), ... 'CustomNumeratorProductDataType', numerictype([], 32, 26), ... 'CustomDenominatorProductDataType', numerictype([], 32, 23), ... 'CustomNumeratorAccumulatorDataType', numerictype([], 32, 24), ... 'CustomDenominatorAccumulatorDataType', numerictype([], 32, 23), ... 'CustomStateDataType', numerictype([], 16, 8), ... 'CustomOutputDataType', numerictype([], 16, 15)); end output = fi(bqLPFilter(inp, num, den), 1, 16, 15, fm); end function fm = get_fimath() fm = fimath('RoundingMethod', 'Floor',... 'OverflowAction', 'Wrap',... 'ProductMode','FullPrecision',... 'MaxProductWordLength', 128,... 'SumMode','FullPrecision',... 'MaxSumWordLength', 128); end
使用命令行API实现定点转换的自动化
或者,定点转换可以使用命令行API实现自动化:
类型myIIRLowpassF2F_prj_script;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 从项目”myIIRLowpassBiquad脚本生成。撮合下2014年- 10月16日。%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 创建配置对象的类“coder.FixPtConfig”。%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% cfg = coder.config(“fixpt”);cfg。TestBenchName = {sprintf('S:\\Work\\15aFeatureExamples\\biquad_notch_f2f\\myIIRLowpassBiquad_tb.m')};cfg。DefaultWordLength = 16;cfg。LogIOForComparisonPlotting = true;cfg。TestNumerics = true; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Define argument types for entry-point 'myIIRLowpassBiquad'. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ARGS = cell(1,1); ARGS{1} = cell(3,1); ARGS{1}{1} = coder.typeof(0,[4000 1]); ARGS{1}{2} = coder.typeof(0,[3 5]); ARGS{1}{3} = coder.typeof(0,[2 5]); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Invoke MATLAB Coder. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% codegen -float2fixed cfg myIIRLowpassBiquad -args ARGS{1}
测试转换后的MATLAB定点实现
运行转换后的定点函数,查看输入输出结果。
范围=简介(SampleRate = 300,...PlotAsTwoSidedSpectrum = false,...ShowLegend = true, YLimits = 25 [-85],...Title =“定点输入信号和滤波输出信号”,...ChannelNames = {“定点输入”,“定点滤波器输出”});rng (12345);%种子RNG可重复的结果为K = 1:10 inp_sig = rand(inp_len,1) - 0.5;%随机值范围(-0.5,0.5)inputFi = fi(inp_sig + inp_itf, 1,16,15);%信号范围(-1.0,1.0)out_3 = myIIRLowpassBiquad_fixpt (inputFi fi (num 1 16), fi(窝,1,16));范围([inputFi out_3])%可视化结束
清晰的范围;%清理
下一个图显示了浮点和定点输出之间的误差。误差似乎相当大。产生这些输出值差异的原因主要是二阶截面的缩放和排序的选择。在下一节中,我们将演示在实现中更早地减少这种错误的方法。
无花果=图;次要情节(1,1);情节(out_1);标题(“浮点滤波器输出”);次要情节(3、1、2);情节(out_3);标题(“定点滤波器输出”);次要情节(3,1,3);情节(out_1 -双(out_3));轴([0 4000 -4e-2 7e-2]);标题(“错误”);
关闭(图);%清理
利用无限范数缩放重新设计椭圆滤波器
椭圆滤波器设计在使用“Linf”二阶截面缩放(即无穷范数)时具有相对良好缩放的特性。使用这种方法通常会导致较小的量化误差。
biquad_Linf =设计(fdesign.lowpass (“Fp,置,美联社,Ast”, 0.4, 0.45, 0.5, 80),...“ellip”FilterStructure =“df1sos”,...SOSScaleNorm =“Linf”SystemObject = true, UseLegacyBiquadFilter = true);fvt_Linf = fvtool (biquad_Linf传奇=“上”);fvt_Linf.SosviewSettings。视图=“累积”;
注意,从输入到滤波器到每个部分的不同状态的累积内部频率响应没有一个超过0 dB。因此,这种设计很适合定点实现。
获得浮动与固定比较的linf范数滤波器系数
注意,SOS滤波系数值会导致几乎相同的滤波响应(无论它们是双位还是16位定点值)。
sosMtrLinf = biquad_Linf.SOSMatrix;sclValLinf = biquad_Linf.ScaleValues;fvt_comp_Linf = fvtool (sosMtrLinf fi (sosMtrLinf 1 16));传奇(fvt_comp_Linf浮点(双)SOS, Linf缩放,...“定点(16位)SOS, Linf缩放”);
bLinf = repmat (sclValLinf (1: (end-1)), 1, 3)。* sosMtrLinf (:, (1:3));aLinf = sosMtrLinf (:, (6));numLinf = bLinf ';分子截面的%矩阵denLinf = aLinf ';%矩阵的分母部分
关闭(fvt_Linf);%清理关闭(fvt_comp_Linf);%清理
测试转换后的MATLAB定点linf -范数双方滤波器
再次执行定点转换器程序之后,如前所述,但使用linf范数缩放滤波器系数值,运行新的转换定点函数并查看输入输出结果。
范围=简介(SampleRate = 300,...PlotAsTwoSidedSpectrum = false, ShowLegend = true,...YLimits = 25 [-85],...Title =“定点输入信号和linf范数滤波输出信号”,...ChannelNames = {“定点输入”,“定点线性范数滤波器输出”});rng (12345);%种子RNG可重复的结果为K = 1:10 inp_sig = rand(inp_len,1) - 0.5;%随机值范围(-0.5,0.5)inputFi = fi(inp_sig + inp_itf, 1,16,15);%信号范围(-1.0,1.0)out_4 = myIIRLinfBiquad_fixpt (...inputFi, fi (numLinf 1 16), fi (denLinf 1 16));范围([inputFi out_4])%可视化结束
清晰的范围;%清理
利用linf范数SOS缩放减少定点实现误差
无限范数SOS缩放通常产生较低误差的输出。
图一=图;次要情节(1,1);情节(out_1);标题(“浮点滤波器输出”);次要情节(3、1、2);情节(out_4);标题(“定点(linf范数SOS)滤波器输出”);次要情节(3,1,3);情节(out_1 -双(out_4));轴([0 4000 0 1e-3]);标题(“错误”);
图=图;次要情节(2,1,1);情节(out_1 -双(out_3));轴([0 4000 -4e-2 7e-2]);标题(“定点误差(默认SOS滤波器缩放)”);次要情节(2,1,2);情节(out_1 -双(out_4));轴([0 4000 0 1e-3]);标题(“定点误差(“Linf”SOS滤波器缩放)”);
关闭(图一);%清理关闭(图);%清理
总结
我们概述了将浮点IIR过滤器转换为定点实现的过程。的dsp。BiquadFilter
DSP系统工具箱™的对象配备了模拟最小和最大仪表功能,帮助定点转换器App自动和动态缩放内部滤波信号。此外,各种“fvtool”和光谱分析仪分析为用户提供工具,在流程的每个步骤执行验证。