主要内容

FIR滤波器的HDL串行架构

这个示例演示了如何为音频滤波应用程序的低通滤波器生成对称FIR滤波器的HDL代码,该滤波器具有完全并行、完全串行、部分串行和级联串行架构。

设计过滤器

使用44.1 kHz的音频采样率和8.0 kHz的通频带边缘频率。设置允许的峰间通带纹波为1db,阻带衰减为- 90db。然后,使用fdesign设计滤波器。使用“直接形式对称”结构的“equiripple”方法创建FIR滤波器系统对象。

Fs = 44.1 e3;%采样频率,单位为Hz成就= 8 e3;Hz中的%通带频率fstop = 8.8e3;%停止频带频率,单位为HzApass = 1;通频带纹波百分比,单位为dBastop = 90;%阻带衰减,单位为dBfdes = fdesign.lowpass(“Fp,置,美联社,Ast”......Fpass, Fstop, pass, stop, Fs);lpFilter =设计(fd,'平静''filterstructure'“dfsymfir”......'systemobject', 真的);

数字转换过滤器

假设音频滤波器的输入来自12位ADC,输出是12位DAC。

nt_in = numerictype(1,12,11);nt_out = nt_in;lpfilter.fullprecisionoverride = false;lpfilter.coefficientsDatatypate =“自定义”;lpfilter.customcoefficientsdatatype = numerictype(1,16,16);lpfilter.outputdatatype =“自定义”;lpfilter.customoutputdatatype = nt_out;%用fvtool检查响应。fvtool (lpFilter“Fs”Fs,'算术'“固定”);

图过滤器可视化工具-幅度响应(dB)包含一个轴和其他类型的uitoolbar, uimenu对象。标题为“大小响应(dB)”的轴包含3个类型为line的对象。这些对象代表过滤器1:量化,过滤器1:引用。

从量化过滤器生成完全并行的HDL代码

从正确量化的过滤器开始,生成VHDL或Verilog代码。创建临时工作目录。生成HDL代码(在本例中选择VHDL),通过单击命令行显示消息中显示的超链接在编辑器中打开生成的VHDL文件。

这是默认情况,并生成完全并行的体系结构。在直接式FIR滤波器结构中,每个滤波器抽头都有一个专用乘法器,在对称FIR结构中,每两个对称抽头都有一个专用乘法器。这将导致大量芯片面积(在本例中为78个乘数)。您可以在各种串行架构中实现过滤器,以获得所需的速度/区域权衡。这些将在本示例的后续章节中进行说明。

WorkingDir = TempName;%完全并行(默认)generatehdl(lpfilter,'姓名'“fullyparallel”......'目标语言'硬件描述语言(VHDL)的......'targetdirectory'workingdir,......“InputDataType”,nt_in);
###启动VHDL代码过滤器的生成过程过滤器的VHDL代码生成过程:完全平行### HDL延迟是2个样本

从量化过滤器生成一个测试工作台

生成VHDL测试台以确保结果与您在Matlab®中看到的响应匹配。可以使用模拟器编译和模拟所生成的VHDL代码和VHDL测试窗。

生成DTMF音调用作过滤器的测试刺激。DTMF信号由两个正弦波或音调的总和组成 - 从两个相互排斥的群体中取出频率。每对音调含有低组(697Hz,770 Hz,852Hz,941 Hz)的一个频率,以及高组的一个频率(1209Hz,1336 Hz,1477Hz),并表示一个独特的符号。您将生成所有DTMF信号,但使用其中一个(这里的数字1)进行测试刺激。这将使测试刺激的长度保持合理的限制。

符号= {'1''2''3''4'“5”“6”“7”“8”“9”‘*’'0''#'};lfg = [697 770 852 941];%低频组HFG = [1209 1336 1477];高频组生成一个包含所有可能的高和低组合的矩阵%频率,其中每一列代表一个组合。f = 0 (12);为了c = 1:4为了r = 1:3 f(:,3 *(c-1)+ r)= [lfg(c);hfg(r)];结尾结尾

接下来,让我们生成DTMF音调

Fs = 8000;%采样频率8 kHzn = 800;%音调100毫秒t =(0:n-1)/ fs;在fs上%800样本坑= 2 *π* t;音调= 0 (N,大小(f, 2));为了Tonechoice = 1:12%生成的语气音调(:,toneChoice) =总和(罪(f (:, toneChoice) *坑))';结尾%以数字'1'为测试刺激的音调。userstim =音调(:1);generatehdl(lpfilter,'姓名'“fullyparallel”......'generatehdltestbench''在'......“TestBenchUserStimulus”,userstim,......'目标语言'硬件描述语言(VHDL)的......'targetdirectory'workingdir,......“InputDataType”,nt_in);
###启动VHDL代码过滤器的生成过程过滤器的VHDL代码生成过程:完全平行### HDL延迟是2个样本### Starting generation of VHDL Test Bench. ### Generating input stimulus ### Done generating input stimulus; length 800 samples.
警告:覆盖溢出检测到。这起源于“独立文件”建议的行动:•从这个来源抑制这种诊断的未来实例。- 压制
###生成测试台:/tmp/bdoc21a_1606923_129767/tp1b97351c_d53e_4ac4_883e_2d66229bb3fc/flyperallel_tb.vhd ###创建刺激向量... ###完成生成VHDL测试台。

关于串行架构的信息

串行架构呈现各种方法以牺牲相对于采样率增加时钟速率的费用。在FIR过滤器中,我们将在每个串行分区的输入之间共享乘数。这将具有将时钟速率提高时钟率,该因素称为折叠因子。

您可以使用HDLFilterserialInfo函数根据系数的值获取有关各种过滤器长度的信息。此函数还显示有可能选项的详尽表,以指定SerialPartition属性,其中折叠因子的相应值和乘数数量。

hdlfilterserialinfo (lpFilter“InputDataType”,nt_in);
| 0 | |总系数A / Symm |有效  | --------------------------------------------------- | 156 | 0 | 78 | 78 |有效的滤波器长度SerialPartition值是78。给定过滤器的“SerialPartition”值的表,其中包含相应的折叠因子值和乘数。| |折叠因素乘数| SerialPartition  | ------------------------------------------------------ | 1 | 78 |的(78)| | 2 | 39 |的(39)* 2 | | 3 | | 26日的(26)* 3 | | 4 | 20 |[(19)* 4,2]| | 5 | 16 |[(15)* 5,3]| | 6 | 13(13)* 6 | |的| 7 | 12 | [(11)* 7,1]| | 8 | 10 | ((9)* 8,6] | | 9 | 9 |[9 9 9 9 9 9 9 9 6] | | 10 | 8 |((7) * 10、8]| | 11 | | 8 [(7)* 11,1]| | 12 | 7 | [(1,6)* 12,6] | | | 6 | 13(13 13 13 13 13 13) | | | 6 | 14(14 14十四14 14 8)| | 15 | 6 |[15个15个15个15个15个3]| | 16 | 5 |(16 16 16 14)| | 17 | 5 |(17 17 17 17 10)| | | 5 | 18[18 18 18 18 6]| | 19 | 5 |[19日19日19日19日2]| | 20 | 4 |(20 20 20 18)| | | 4 | 21日(21日21日21日15)| | | 4 | 22日(22 22 22 12)| | | 4 | 23日(23日23 23 9)| | | 4 | 24日(24日24 24 6)| | 25 | 4(25 25 25 3) | | | | 3 | 26日(26日26日26日)| | | 3 | 27日(27日27日24)| | | 3 | 28日(28日28日22)| | | 3 | 29日(29日29日20)| | | 3 | 30(30 30 18)| | | 3 | 31日[16]31日31日| | 32 | 3 | (32 32 14)| | | 3 | 33 [33 33 12]| | 34 | 3 | 10 [34]| | 35 | 3 | 35 8 [35]| | 36 | 3 | (36 36 6)| | | 3 | 37 [37 37 4]| | 38 | 3 | [38 38 2]| | 39 | 2 | [39 39]| | 40 | 2 | | (40 38)| 41 | 2 |[41 37] | | 42 | 2 |[42 36] | | 43 | 2 |[43 35] | | 44 | 2 |[44 34] | | 45 | 2 |[45 33] | | 46 | 2 |[46 32] | | 47 | 2 |[47 31] | | 48 | 2 |[48 30] | | 49 | 2 |[49 29] | | 50 | 2 |[50 28] | | 51 | 2 |[51 27] | | 52 | 2 |[52 26] | | 53 | 2 |[53 25] | | 54 | 2 |[54 24] | | 55 | 2 |[55 23] | | 56 | 2 |[56 22] | | 57 | 2 |[57 21] | | 58 | 2 |[58 20] | | 59 | 2 |[59 19] | | 60 | 2 |[60 18] | | 61 | 2 |[61 17] | | 62 | 2 |[62 16] | | 63 | 2 |[63 15] | | 64 | 2 |[64 14] | | 65 | 2 |[65 13] | | 66 | 2 |[66 12] | | 67 | 2 |[67 11] | | 68 | 2 |[68 10] | | 69 | 2 |[69 9] | | 70 | 2 |[70 8] | | 71 | 2 |[71 7] | | 72 | 2 |[72 6] | | 73 | 2 |[73 5] | | 74 | 2 |[74 4] | | 75 | 2 |[75 3] | | 76 | 2 |[76 2] | | 77 | 2 |[77 1] | | 78 | 1 |[78] |

您可以使用可选属性“乘数”和“FoldingFactor”显示特定信息。

hdlfilterserialinfo (lpFilter'乘法器'4......“InputDataType”,nt_in);
串行分区:[20 20 20 18],折叠因子:20,乘数:4
hdlfilterserialinfo (lpFilter“Foldingfactor”6......“InputDataType”,nt_in);
序列划分:1(1,13)*6,折叠因子:6,乘数:13

完全串行架构

在完全串行架构中,代替每个抽头的专用乘法器,串联选择每个抽头的输入样本,并乘以相应的系数。对于对称(和反对称)结构,对应于每组对称抽头的输入样本是预先乘以对应系数之前的(对于对称的)或预先减去(用于反对称的)。使用寄存器顺序累计产品,并且在下一组输入样本到达之前,最终结果存储在寄存器中。此实现需要时钟速率比输入采样率快多倍,因为要计算的产品数量。下载188bet金宝搏这导致减少所需的芯片区域,因为实现涉及一个乘法器,其中包括多路复用器和寄存器等少数附加逻辑元素。对于此示例,时钟速率将是输入采样率(折叠性能仪78)等于3.4398 MHz的78倍。

要实现完全串行架构,请使用HDLFilterserialInfo函数并将其“乘数”属性设置为1.您还可以将其值设置为等于有效滤波器长度的“SerialPartition”属性,在这种情况下是78.该功能也返回用于该串行分区设置的折叠因子和乘法器的数量。

[spart,foldingfact,nmults] = hdlfilterserialinfo(lpfilter,'乘法器',1,......“InputDataType”,nt_in);% #好< ASGLU >generatehdl(lpfilter,'姓名'“fullyserial”......“SerialPartition”,spart,......'目标语言'硬件描述语言(VHDL)的......'targetdirectory'workingdir,......“InputDataType”,nt_in);
/tmp/Bdoc21a_1606923_129767/tp1b97351c_d53e_4ac4_883e_2d66229bb3fc/full - serial. /tmp/Bdoc21a_1606923_129767/tp1b97351c_d53e_4ac4_883e_2d66229bb3fc开始生成全串行VHDL实体###开始生成全串行VHDL架构######成功完成VHDL的代码生成过程:全串行### HDL延迟是3个样本

以相同的方式生成测试台,如在完全并行情况下。对于每个架构实现,再次生成测试窗是重要的。

部分串行结构

完全并行和完全串行表示实现的两个极端。虽然全串行是非常低的领域,它本质上需要一个更快的时钟速率来操作。完全并行占用大量芯片面积,但性能非常好。在一定程度上,串行架构涵盖了介于这两个极端之间的所有情况。

输入抽头分为组。每个集合由由乘法累积和多路复用器组成的串行分区并行处理。这里,一组串行分区处理给定的一组抽头。这些串行分区相对于彼此并联操作,但是处理每个点击顺序地,以累积与服务的抽头相对应的结果。最后,使用加法器将每个串行分区的结果一起添加。

部分串行架构用于资源约束

让我们假设您希望在FPGA上实现此过滤器,该过滤器仅为过滤器提供4个乘法器。您可以使用4个串行分区实现过滤器,每个串行分区使用一个乘法累加电路。

hdlfilterserialinfo (lpFilter'乘法器'4......“InputDataType”,nt_in);
串行分区:[20 20 20 18],折叠因子:20,乘数:4

由这些串行分区处理的输入点击将是[20 20 20 18]。您将使用指示串行分区的点击分解的向量指定SerialPartition。时钟速率是由这个向量的最大元素决定的。在这种情况下,时钟速率将是输入采样速率的20倍,0.882 MHz。

[spart,foldingfact,nmults] = hdlfilterserialinfo(lpfilter,'乘法器'4......“InputDataType”,nt_in);generatehdl(lpfilter,'姓名'“partlyserial1”......“SerialPartition”,spart,......'目标语言'硬件描述语言(VHDL)的......'targetdirectory'workingdir,......“InputDataType”,nt_in);
### /tmp/Bdoc21a_1606923_129767/tp1b97351c_d53e_4ac4_883e_2d66229bb3fc/partlyserial1. exe /tmp/Bdoc21a_1606923_129767/tp1b97351c_d53e_4ac4_883e_2d66229bb3fc/partlyserial1. exe /tmp/Bdoc21a_1606923_129767开始生成部分serial1 VHDL实体###开始生成部分serial1 VHDL体系结构###时钟速率是输入采样率的20倍。###成功完成VHDL的代码生成过程:partlyserial1 ### HDL延迟是3个样本

部分串行结构用于速度约束

假设您对滤波器实现的时钟速率有一个限制,并且最大时钟频率是2mhz。这意味着时钟速率不能超过输入采样速率的45倍。对于这样的设计约束,'SerialPartition'应该用[45 33]指定。注意,这将导致额外的串行分区硬件,这意味着额外的电路将累加33个点。你可以使用hdlfilterserialinfo和它的属性'Foldingfactor'指定SerialPartition,如下所示。

脱离= hdlfilterserialinfo (lpFilter,“Foldingfactor”45岁的......“InputDataType”,nt_in);generatehdl(lpfilter,'姓名'“partlyserial2”......“SerialPartition”,spart,......'目标语言'硬件描述语言(VHDL)的......'targetdirectory'workingdir,......“InputDataType”,nt_in);
### /tmp/Bdoc21a_1606923_129767/tp1b97351c_d53e_4ac4_883e_2d66229bb3fc/partlyserial2. exe /tmp/Bdoc21a_1606923_129767/tp1b97351c_d53e_4ac4_883e_2d66229bb3fc/partlyserial2. exe /tmp/Bdoc21a_1606923_129767开始生成部分serial2 VHDL实体###开始生成部分serial2 VHDL体系结构###时钟速率是该体系结构输入采样率的45倍。###成功完成VHDL的代码生成过程:partlyserial2 ### HDL延迟是3个样本

通常,您可以根据其他约束为串行分区指定任意的点击分解。唯一的要求是向量元素的和应该等于有效滤波器的长度。

Cascade-Serial架构

可以重新使用串行分区中的累加器来添加下一个串行分区的结果。如果由一个串行分区处理的抽头数必须超过串行分区,则这是可能的,这可能是至少1.该技术的优势在于添加所有串行分区结果所需的添加剂集被删除了。然而,这增加了时钟速率1,因为需要额外的时钟周期来完成额外的累积步骤。

级联-串行架构可以使用属性'ReuseAccum'指定。这可以通过两种方式实现。

将“ReuseAccum”添加到GenerateHDL方法,并将其指定为“ON”。请注意,为“SerialPartition”属性指定的值必须使累加器重用是可行的。除了可以相同的最后两个,载体的元素必须处于降序。

如果未指定属性“串行分区”并且“reuseAccum”指定为“开”,则在内部确定串行分区的抽头的分解。这样做是为了最小化时钟速率并重用累加器。对于该音频滤波器,它是[12 11 10 9 8 7 6 5 4 3 3]。请注意,它使用11个串行分区,暗示11乘以累加电路。时钟速率将是输入采样率的13倍,573.3 kHz。

generatehdl(lpfilter,'姓名''cascadeserial1'......“SerialPartition”33 [45],......'reuseaccum''在'......'目标语言'硬件描述语言(VHDL)的......'targetdirectory'workingdir,......“InputDataType”,nt_in);
### # /tmp/Bdoc21a_1606923_129767/tp1b97351c_d53e_4ac4_883e_2d66229bb3fc/cascadeserial1. /tmp/Bdoc21a_1606923_129767/tp1b97351c_d53e_4ac4_883e_2d66229bb3fc开始生成cascadeserial1 VHDL实体###开始生成cascadeserial1 VHDL体系结构###时钟速率是输入采样率的46倍。###成功完成VHDL filter代码生成过程:cascadeserial1

为实现复用累加器所需的最小时钟率,优化分解成尽可能多的串行分区。

generatehdl(lpfilter,'姓名''cascadeserial2'......'reuseaccum''在'......'目标语言'硬件描述语言(VHDL)的......'targetdirectory'workingdir,......“InputDataType”,nt_in);
### /tmp/Bdoc21a_1606923_129767/tp1b97351c_d53e_4ac4_883e_2d66229bb3fc/cascadeserial2. /tmp/Bdoc21a_1606923_129767/tp1b97351c_d53e_4ac4_883e_2d66229bb3fc开始生成cascadeserial2 VHDL实体###开始生成cascadeserial2 VHDL体系结构###时钟速率是这个体系结构的输入采样率的13倍。###串行分区# 1有12个输入。###串行分区# 2有11个输入。###串行分区# 3有10个输入。###串行分区# 4有9个输入。###串行分区# 5有8个输入。###串行分区# 6有7个输入。###串行分区# 7有6个输入。###串行分区# 8有5个输入。 ### Serial partition # 9 has 4 inputs. ### Serial partition # 10 has 3 inputs. ### Serial partition # 11 has 3 inputs. ### Successful completion of VHDL code generation process for filter: cascadeserial2 ### HDL latency is 3 samples

结论

您设计了一个低通直接表格对称FIR滤波器,以满足给定的规范。然后,您量化并检查您的设计。您为完全并行,完全串行,部分串行和级联架构生成VHDL代码。您使用DTMF音色为其中一个架构生成了VHDL测试台。

您可以使用一个HDL Simulator来验证为不同的串行架构生成的HDL代码。您可以使用一个综合工具来比较这些架构的面积和速度。您还可以试验并生成Verilog代码和测试工作台。