HDL可编程FIR滤波器

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

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

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

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

设计的过滤器

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

Fpass=0.45;%通带频率Fstop = 0.55;%阻带频率apas = 1;通带衰减百分比(dB)Astop = 60;阻带衰减(dB)f = fdesign.lowpass (“Fp,置,美联社,Ast”、成就、Fstop apas Astop);lpFilter =设计(f,“equiripple”“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阻带衰减:55.3452 dB过渡宽度:0.1

验证过滤器输出

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

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

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

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

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

对于量化低通滤波器,我们将通过设置属性‘coefficients source’为‘ProcessorInterface’来生成带有处理器接口的VHDL代码。这将导致生成的代码具有用于write_address、write_enable、coeffs_in和write_done信号的额外端口。该接口可用于将系数从主机处理器加载到内部寄存器文件中。HDL有一个额外的阴影寄存器,当'write_done'信号高时,从寄存器文件更新它。这使得过滤器实体能够同时加载和处理数据。

为了验证过滤器实体可以连续加载两组不同的过滤系数,我们将生成一个VHDL测试台。首先,测试台加载低通系数并对输入样本进行处理。然后测试台加载高通滤波器响应对应的系数,对输入样本进行重新处理。

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

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

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

%当对称结构被选中时,字段“TestbenchCoeffStimulus”%必须是过滤器长度的一半。workingdir = tempname;generatehdl (lpFilter“名字”“FilterProgrammable”...“InputDataType”13)、numerictype(1、14日,...“开发”硬件描述语言(VHDL)的...“TargetDirectory”workingdir,...“CoefficientSource”“ProcessorInterface”...“GenerateHDLTestbench”“上”...“TestBenchUserStimulus”, 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文件脚本后的ModelSim HDL模拟器。将ModelSim结果与之前绘制的MATLAB结果进行比较。

结论

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