主要内容

HDL可编程FIR过滤器

此示例说明了如何使用处理器接口的FIR滤波器生成HDL代码,以加载系数。可以通过使用处理器接口将系数加载到内部系数内存中,将过滤器编程为任何所需的响应。

让我们假设我们需要在芯片上实施具有不同响应的过滤器。如果所有过滤器都具有直接形式的FIR结构和相同的长度,则可以在需要时使用处理器接口加载每个响应的系数。

该设计将在输入样品使用加载系数处理之前增加几个周期的延迟。但是,它具有一个优点,即可以使用新系数对相同的过滤器硬件进行编程以获得不同的滤镜响应。这样可以节省芯片区域,否则每个过滤器将在芯片上分别实现。

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

设计过滤器

创建低通滤波器设计对象,然后创建FIR滤波器系统对象(HLP)。然后,将其转换为使用高通响应(HHP)创建FIR滤波器系统对象。

fpass = 0.45;%通过频率频率FSTOP = 0.55;%停止带频率apass = 1;%通带衰减(DB)astop = 60;%停止带衰减(DB)f = fdesign.lowpass('fp,fst,ap,ast',FPASS,FST​​OP,APASS,ASTOP);lpfilter =设计(f,'equiripple',,,,“过滤”,,,,'dfsymfir',,,,“系统对象”,真的);% 低通hpCoeffs = firlp2hp(lpfilter.numerator);hpfilter = dsp.firfilter('分子',hpceeffs);%高通

量化过滤器

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

lpfilter.fullprecisionoverride = false;lpfilter.coefficientsDatatype ='风俗';lpfilter.customcoeffientsdatatepe = numerictype(1,14,13);lpfilter.outputdatatype =“和累加器相同”;lpfilter.productDatatype =“完整的精确度”;lpfilter.AccumulatOdatate =“完整的精确度”;hpfilter.fullprecisionoverride = false;hpfilter.coefficientsDatatype ='风俗';hpfilter.customcoeffientsdatatepe = numerictype(1,14,13);hpfilter.outputdatatype =“和累加器相同”;hpfilter.productDatatype =“完整的精确度”;hpfilter.AccumulatOdatate =“完整的精确度”;

应用固定点设置后,重要的是要验证系统对象过滤器仍然符合规格。我们将使用“度量”函数来检查这是否正确。

测量(lpfilter,'算术',,,,'固定的'
ANS =样本率:N/A(归一化频率)通带边缘:0.45 3-DB点:0.46957 6-DB点:0.48314停止边缘:0.55 Passband Band Ripple:0.89243 db stopband atten。:55.3452 DB过渡宽度:0.1

验证过滤器输出

使用Chirp生成线性扫描频率刺激信号。首先使用此输入刺激通过低通FIR滤波器进行过滤。然后更改过滤器的系数以获得高通响应,并使用相同的输入样品再次过滤。

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

绘制输入样品,并且过滤后的输出显示了低通和高通行为。

x = chirp(0:199,0,199,0.4);lpCoeffs = lpfilter.numerator;%存储原始低通系数y1 = lpfilter(fi(x,1,14,13)。');%过滤信号lpfilter.numerator = hpfilter.numerator;%加载高通滤波器系数y2 = lpfilter(fi(x,1,14,13)。');%过滤信号y = [y1;y2];%联合输出信号lpfilter.numerator = lpCoeffs;%还原原始低通系数子图(2,1,1);图([x,x]);Xlabel('时间[样品]'); ylabel('振幅');标题(“输入刺激”);子图(2,1,2);图(y);Xlabel('时间[样品]'); ylabel('振幅');标题(“过滤输出”);

图包含2个轴对象。带有标题输入刺激的轴对象1包含类型线的对象。带有标题过滤输出的Axes Object 2包含类型线的对象。

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

对于量化的低通滤波器,我们将通过将属性“ CofficientSource”设置为“ ProcessorInterface”来生成带有处理器接口的VHDL代码。这将导致生成的代码具有write_address,write_enable,coeffs_in和write_done信号的其他端口。该接口可用于将主机处理器的系数加载到内部寄存器文件中。HDL有一个附加的影子寄存器,当“ Write_done”信号较高时,该寄存器将从寄存器文件中更新。这可以通过过滤器实体同时加载和处理数据。

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

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

为了生成所需的测试工作台,我们将属性“ generateHdlTestBench”设置为“ on”,并在呼叫togerateHDL命令中将testBenchCoeffstimulus'设置为“ testbenchcoeffstimulus”。“ TestBenchCoeffStimulus”传递的值是系数的向量,用于后续处理输入样品。此示例通过与高通滤波器相对应的系数的向量传递。

由于输入ADC的固定数据路径要求,因此需要14位签名的固定点输入,具有13位分数精度。

%选择对称结构,“ TestBenchcoeffstimulus”字段%必须是过滤器长度的一半。workingDir = tempname;generateHDL(lpfilter,'姓名',,,,“ Filter Programable”,,,,...'inputDatatype',数字型(1,14,13),...'目标语言',,,,'vhdl',,,,...“ TargetDirectory”,WorkingDir,...“系数库”,,,,“加工界面”,,,,...'generateHdlTestBench',,,,'在',,,,...“ TestBenchuserstimulus”,X,...“ testbenchcoeffstimulus”,hpfilter.numerator(1 :(长度(hpfilter.numerator)+1)/2);
###启动VHDL代码生成过程:FilterProgrammable ###生成:/TMP/BDOC22A_1891349_40428/TPC3339D25A_214D_4D_4D3F_4D3F_81EF_81EF_BAB381EEF_AB3851A3851A3EDF8/FILTERPRATER.VHDENTILLUNTILY QUENTIRTY.VHD ##VHDL代码生成的过滤器:Filter Progrogmable ### HDL延迟是2个样本### VHDL测试工作台的起始生成。###生成输入刺激###完成输入刺激;长度200个样品。###生成测试台面:/TMP/BDOC22A_1891349_40428/TPC339D25A_214D_214D_4D3F_4D3F_81EF_AB3851A3851A3EDF8/FILTERTERPROGRMABLECMABLPROGRABLECOMMABLEDOGRAGY_TB.VHD #vhd test test test test test test Interulus vectors ...

ModelsIm®仿真结果

以下显示显示了在运行用于测试工作台的生成的.DO文件脚本后的Modelim HDL模拟器。将模型结果与以前绘制的MATLAB结果进行比较。

结论

我们设计了高通和低通向通道过滤器来满足给定的规格。然后,我们使用一个接口来量化过滤器并生成VHDL代码,以加载处理器的系数。然后,我们生成了一个VHDL测试台,该测试台显示了加载低通系数后输入样品的处理,并用高通系数重复操作。我们展示了如何生成实现过滤硬件的VHDL代码,这些硬件可重复使用,当通过主机处理器的端口接口加载不同的系数集时,可以重复使用不同的响应。