HDL可编程FIR滤波器

这个示例演示了如何为带有加载系数的处理器接口的FIR滤波器生成HDL代码。通过使用处理器接口将系数加载到内部系数存储器中,过滤器可以被编程为任何想要的响应。

让我们假设我们需要在芯片上实现一组具有不同响应的过滤器。如果所有的过滤器都具有直接形式的FIR结构,并且长度相同,那么我们可以使用处理器接口在需要时从RAM或寄存器文件加载每个响应的系数。

在输入样本可以用加载的系数处理输入样本之前,这种设计将增加几个周期的延迟。然而,它具有以下优点:可以用新系数编程相同的滤波器硬件以获得不同的滤波器响应。这可以节省芯片区域,否则每个过滤器将在芯片上单独实现。

在此示例中,我们将考虑两个FIR滤波器,一个具有高通响应的FIR滤波器,另一个具有低通响应。我们将通过加载相应的系数集来展示如何为每个响应进行编程相同的过滤器硬件。我们将为过滤器生成VHDL代码,并使用生成的VHDL测试台显示两个响应。

设计过滤器

创建低通滤波器设计对象,然后创建FIR滤波器系统对象(Hlp)。然后,转换它以创建一个具有高通响应(Hhp)的FIR滤波器系统对象。

成就= 0.45;%通带频率fstop = 0.55;%阻带频率Apass = 1;%通带衰减(DB)astop = 60;阻带衰减(dB)f = fdesign.lowpass(“Fp,置,美联社,Ast”、成就、Fstop apas Astop);lpFilter =设计(f,'平静''filterstructure'“dfsymfir”'systemobject',真的);% 低通hpcoeffs = firlp2hp(lpfilter.numerator);hpfilter = dsp.firfilter('分子', hpcoeffs);%高通

量化过滤器

假设系数需要存储在位宽为14的存储器中。使用此信息,将固定点设置应用到系统对象过滤器。

lpFilter.FullPrecisionOverride = false;lpFilter。CoefficientsDataType =“自定义”;lpFilter.CustomCoefficientsDataType = numerictype(1、14、13);lpFilter。OutputDataType =“蓄电池一样”;lpfilter.productDatatype =“充分精确”;lpfilter.accumulatordataType =“充分精确”;hpFilter.FullPrecisionOverride = false;hpFilter。CoefficientsDataType =“自定义”;hpFilter.CustomCoefficientsDataType = numerictype(1、14、13);hpFilter。OutputDataType =“蓄电池一样”;hpFilter。ProductDataType =“充分精确”;hpfilter.accumulatordataType =“充分精确”

在应用固定点设置之后,验证System对象过滤器仍然满足规范是很重要的。我们将使用'measure'函数来检验这是否为真。

衡量(LPFilter,'算术'“固定”
ans =采样率:N/A(归一化频率)通带边缘:0.45 3-dB点:0.46957 6-dB点:0.48314阻带边缘:0.55通带纹波:0.89243 dB阻带Atten转换宽度:0.1

验证过滤器输出

使用啁啾产生线性扫频刺激信号。使用这个输入刺激首先通过低通FIR滤波器滤波。然后改变滤波器的系数得到高通响应,并使用相同的输入样本再次滤波。

对于上述两级过滤操作,我们的目标是将从MATLAB®的滤波器输出与来自生成的HDL码进行比较。

绘图输入样本和过滤输出显示低通和高通行为。

x =唧唧喳喳(0199年0:199,0.4);lpcoeffs = lpFilter.Numerator;%存储原始低通系数日元= lpFilter (fi (x, 1, 14日,13)。');%滤波信号lpfilter.numerator = hpfilter.numerator;%加载高通滤波系数y2 = lpfilter(fi(x,1,14,13)。');%滤波信号y =[日元;y2);%连接输出信号lpfilter.numerator = lpcoeffs;%恢复原始低通系数子图(2,1,1);图([x,x]);Xlabel('时间[样本]'); ylabel (“振幅”);标题('输入刺激');子图(2,1,2);情节(y);Xlabel('时间[样本]'); ylabel (“振幅”);标题(“过滤输出”);

使用处理器接口生成VHDL代码和测试台

对于经量化的低通滤波器,我们将通过设置属性“CoefficientSource”到“ProcessorInterface”产生与处理器接口的VHDL代码。这将导致生成的代码具有Write_address,Write_enable,Coeffs_in和Write_done信号的附加端口。该接口可用于将来自主处理器的系数加载到内部寄存器文件中。HDL有一个额外的阴影寄存器,当“Write_done”信号很高时,从寄存器文件更新。这使得能够通过滤波器实体同时加载和处理数据。

为了验证滤波器实体可以连续加载两组不同的滤波器系数,我们将生成VHDL测试台。首先,测试台面负载低通系数并处理输入样本。然后,测试台加载与高通滤波器响应相对应的系数,并再次处理输入样本。

可以使用ModelSIM®等HDL模拟器编译和模拟所生成的VHDL代码和VHDL测试台。请注意,同时执行第二组系数的加载和最后几种输入样本的处理。

为了生成所需的测试工作台,我们将属性'GenerateHDLTestbench'设置为'on',并在调用generatehdl命令时传递'TestbenchCoeffStimulus'。传递给“TestbenchCoeffStimulus”的值是一个系数向量,将用于输入样本的后续处理。这个例子传递了一个与高通滤波器相对应的系数向量。

由于输入ADC的固定数据路径要求,需要假设具有13位分数精度的14位符号定点输入。

选择对称结构的%,该字段'testbenchcoeffstimulus'%必须是过滤器长度的一半。workingdir = tempname;generatehdl (lpFilter'姓名''过滤可编程'......“InputDataType”13)、numerictype(1、14日,......'目标语言'硬件描述语言(VHDL)的......'targetdirectory',练习呢,......“CoefficientSource”“ProcessorInterface”......'generatehdltestbench''在'......'testbenchusertumulus', x,......“TestbenchCoeffStimulus”,hpfilter.numerator(1 :(长度(hpfilter.numerator)+1)/ 2));
### /tmp/Bdoc20a_1326390_11805/tpbc54c5f7_8d0e_4668_89a3_bc48d01696ec/FilterProgrammable. ### /tmp/Bdoc20a_1326390_11805/tpbc54c5f7_8d0e_4668_89a3_bc48d01696ec###开始生成FilterProgrammable VHDL实体###开始生成FilterProgrammable VHDL架构### #成功完成VHDL filter代码生成过程:FilterProgrammable ### # HDL latency是2个样本### #开始生成VHDL测试台。###生成输入刺激200个样本长度。###生成测试台:/tmp/Bdoc20a_1326390_11805/tpbc54c5f7_8d0e_4668_89a3_bc48d01696ec/ filterprogramable_tb。vhd ###创建刺激向量…###完成VHDL测试平台的生成

Modelsim®仿真结果

以下显示显示了在运行生成的.Do文件脚本以进行测试台的Modelim HDL模拟器。将ModelIM结果与如之前绘制的MATLAB结果进行比较。

结论

我们设计了高通和低通FIR滤波器,以满足给定的规格。然后我们对滤波器进行量化,并为滤波器生成VHDL代码,该代码带有从处理器加载系数的接口。然后我们生成了一个VHDL测试台,显示了在加载低通系数后对输入样本的处理,用高通系数重复操作。我们演示了如何生成实现过滤器硬件的VHDL代码,当从主机处理器通过端口接口加载不同的系数集时,该硬件可用于不同的响应。