利用MATLAB的FDATOOL工具生成IIR滤波器的verilog代码

IIR滤波器因为其非线性相位,不稳定,设计复杂等缺点往往很少应用,但是在FPGA资源紧张或者需要一些特殊应用时,使用IIR滤波器就显得有必要了。但是网上除了杜勇老师的IIR滤波器教程之外,很少再有关于IIR滤波器的详细教程,杜勇老师的教程使用MATLAB的滤波器设计函数来设计IIR滤波器,然后自行编写HDL来实现IIR滤波器,这样虽然能清晰的了解IIR滤波器的具体实现方法和结构,但是却不便于快速设计,并且在面对阶数稍高的IIR滤波器时,设计就显得十分复杂。

因此本文总结了使用MATLAB的fdatool滤波器设计工具直接生成IIR滤波器的verilog模块代码的操作流程,演示了生成低通滤波器,去直流滤波器,峰值滤波器的操作过程,生成的代码无需任何修改可以直接综合,经过仿真和上板实测可以正常使用。

IIR滤波器的特点:
特点1 :非线性相位

令一个理想方波通过一个IIR和FIR低通滤波器后:

上方是IIR滤波器滤波后的方波,可见明显的振铃效应,是方波的各个频率成分在通过滤波器后相位不一致导致的。

下方是FIR(滑动平均滤波器),可见方波的形状保持完好,只是边缘变缓。
特点2 :不稳定,可能自激或者在某个频率不稳定
特点3:资源消耗少,同等滤波要求下,同样的全并行架构,IIR滤波器消耗的资源可能比FIR少10倍以上。

接下来以低通滤波器为例,讲解如何使用MATLAB的FDATOOL设计一个输入和输出都为12bit定点数的IIR滤波器,并且直接生成该滤波器的HDL(verilog)
第一步 :设置基本滤波器参数

此处滤波器结构选择chevbyshev II型,这种结构的滤波器具有较快的转折速度(迅速截止),同时保证了通带内平缓,特点是阻带不平缓。

匹配方法选择完全匹配通带

频率选择归一化,通带边缘为0.05,阻带边缘为0.07,阻带抑制设置为50dB,对于一般的应用来说,50dB的抑制已经足够了,增加抑制比会增加滤波器阶数,增加资源消耗。

点击设计滤波器后,设计出一个9阶5节的IIR滤波器,其架构默认为直接II型架构。这里要选择转换为直接I型架构:

原因是在测试过程中,虽然直接II型消耗的硬件资源更少,但是直接II型对量化精度更加敏感,在同等量化精度下的滤波效果总是不如直接I型,所以此处选择直接I型。
第二步 :量化滤波器

滤波器算法选择定点,系数字长选择13bit,这个13bit是逐渐尝试出来的,如果使用12bit及更低的量化位数,可以发现量化后的滤波器和原滤波器有较大差别,而如果选择更高的量化位数,对滤波器的精度没有明显改善,还会增加硬件资源消耗。

下一步选择输入输出的字长,此处也选择13bit,原因是在测试过程中,如果选择12bit,由于IIR滤波器的增益可能会大于1,导致在外部12bit满幅度数据输入时,滤波器输出范围就会大于12bit,此时滤波器一定会溢出,使滤波器输出结果完全错误,因此要把滤波器输入输出都设置为比外部输入的数据多1bit,这样即使外部输入12bit满幅度信号,对于滤波器来说也只是自身满幅度的一半,就避免了溢出的发生。

同时也要注意:"避免溢出"这个选项要取消勾选,然后设置输入输出的小数长度也和字长一样,也就是13bit,如果采用fdatool的默认设置,滤波器输出的位宽会不正确,可能会导致幅度过大或者过小,所以此处必须要全部手动设置。

对于滤波器内部选项的设置,这里也要全部进行手动修改而不能使用默认值,

对于舍入模式的设置,此处选择"向下"

乘积和累加模式默认为全精度,但是全精度太消耗硬件资源,此处选择保留MSB,乘积和累加字长设置为系数字长+输入字长=13bit+13bit=26bit,经过测试,这样设置在实际使用中不会发生溢出。

勾选在累加前转换信号

Num. state字长设置为和系数字长13bit相同即可

Den. state字长要比系数字长更长,此处设置为14bit即可(部分滤波器需要更长,例如椭圆滤波器此处要设置为比系数字长多3到6bit)

分子和分母小数长度都设置为系数长度13bit即可

设计完成后点击应用,然后查看滤波器是否稳定,幅频响应曲线是否和原滤波器相差太大,如果无误可以进行下一步。

溢出模式选择绕回,选择绕回模式不会额外消耗硬件资源,但是如果滤波器内发生溢出,输出滤波结果会完全错误,如果选择饱和,则会额外消耗硬件资源,但是可以保证在有少量溢出时输出结果不会受到大的影响。
第三步 :生成滤波器HDL

点击目标(R)选择生成HDL

弹出窗口后,选择语言为verilog,设置滤波器模块名称和生成路径

Coefficient multipliers(乘法方法)有三个方法:

1:Factored-CSD 因子化移位乘加法,通过在系数的质因数上进行移位和加法运算来替代乘法运算,这种方法不消耗dsp资源,消耗的组合逻辑资源比CSD方法还要少,但是运行速度最慢。

2:CSD 普通的移位乘加法,不消耗dsp资源,消耗较多组合逻辑资源,运行速度较慢。

3:Multiplier 乘法器,在代码中直接使用*号来计算乘法,可能会被综合器直接综合为dsp块,会消耗dsp资源,消耗的组合逻辑资源最少,运行速度最快。
与FIR滤波器的对比:

采用同样的设计要求:使用等波纹法设计一个FIR滤波器如下:

可以看到在同样的设计要求下,FIR滤波器至少需要170阶才能达到与IIR滤波器同样的效果,而170阶滤波器在使用全并行架构实现时,至少需要170/2+1=86个DSP块才行。

实例2:生成去直流滤波器(高通滤波器)

需要滤除直流时,往往使用滑动平均高通滤波器(原始值减去滑动平均低通后的值就是高通滤波器结果),但是滑动平均滤波器虽然相比其它fir滤波器已经十分节省资源,但是在阶数较高时还是要消耗较多的ram资源用于缓存窗口数据,因此在不需要线性相位时,可以采用IIR滤波器来简单的达到滤除直流的效果,fdatool设置如下:

响应类型选择陷波,设计方法选择IIR梳状,指定阶数为2,这样刚好会在0频率和Nyquist频率处有零点,可以达到滤除直流的效果。

频率设定选择归一化,设置Q值为50,幅值设定里,设置Apass为0.1。Q值和Apass这两个参数影响的是滤波器的高通转折频率,可根据实际情况自行调整。

其余设置与上文的低通滤波器均相同。

设置完后生成滤波器,生成滤波器为2阶IIR滤波器,而观察其-3dB点,可得其归一化截止频率为0.0016,也就是说如果使用该滤波器进行音频去直流滤波,在44.1kHz采样率下,其截止频率为44.1kHz/2*0.0016=35Hz,已经完全足够使用。

而如果使用滑动平均高通滤波器,大约需要1024阶才能达到这个性能(滑动平均滤波器的截止频率为第一个零点频率的一半):

1024阶滑动平均高通滤波器的幅频响应曲线,可见-3dB点在0.014归一化频率左右。

实例3:生成单峰值滤波器

与陷波滤波器相对的就是峰值滤波器,而单峰值滤波器往往用于在频谱中筛选点频信号,也就是只取出一个频率分量,而抑制其它所有频率分量,可以视为带通滤波器的简化版本。

例如TI杯电赛2023年H题信号分离装置,想要无漂移的结果,最简单的方法就是滤波法:需要分别提取出两个叠加在一起的点频信号,此处使用单峰值滤波器再合适不过,因为单峰值滤波器很容易做到极其狭窄的频率响应,并且消耗的硬件资源极少,而其峰值点的频率和其工作的时钟频率有固定比例关系(这也是所有数字滤波器的特点),也就是说只要改变峰值滤波器的时钟频率,就能改变其峰值频率,从而能自由选择在频谱上筛选哪个频率。

Fdatool设置如下:

响应类型选择峰值,设计方法选择IIR单峰值。

频率设定选择归一化,设置峰值频率为0.1,设置Q值为150,幅值设定里,设置Apass为1。Q值和Apass这两个参数影响的是滤波器的"尖锐程度",也就是选择性,可根据实际情况自行调整。

其余设置与上文相同,但是注意单峰值滤波器需要更高的量化精度,此处设置为16位如下。

设置完后生成滤波器,生成滤波器为2阶IIR滤波器,可以看到在0.1归一化频率处有峰值,在对数坐标下可能不太明显,设置为线性坐标并观察相位:

可见幅频响应非常尖锐,而相位响应在小于0.1归一化频率时为180deg,大于0.1归一化频率时为-180deg。

峰值滤波器和陷波滤波器一样只能由IIR滤波器实现,如果使用FIR滤波器搭建一个性能相近的带通滤波器,阶数需要达到几千,所需的硬件资源是不可承受的。

仿真结果:

对本文的三个IIR滤波器进行仿真,滤波器输入信号由dds产生频率递增的正弦波并且叠加一个直流分量。

Iir_lpf_o为低通滤波器输出,可见滤除了高频分量并且保留了直流分量

iir_remove_dc_o为去直流滤波器输出,滤除了直流,保留了高频分量

iir_signle_peak_o为单峰值滤波器输出,在一个频率点上的输出幅值最大

可见三个滤波器均工作良好。

综合后结果:

使用vivado2025.1,综合与实现策略均使用默认策略,在xc7z020上实现后的资源消耗如下:

其余未列出的资源消耗为0

可见滤波器均没有使用dsp资源,而是使用了较多的LUT资源。

提示:

滤波器级数太大并不会带来很高的收益,反而可能更加不稳定,所以如果生成的滤波器在测试的时候不稳定,可以尝试一下把阻带转折平缓一点,降低阻带抑制,或者提升Den. state字长(在滤波器量化面板的滤波器内部选项),可能会得到更好的效果。

Matlab生成的HDL代码中,组合逻辑链路很长,而且勾选了添加流水线也优化不了多少,所以运行频率很低,建议使用时不要超过50MHz时钟速率

上述三个IIR滤波器的代码:
点击查看代码

复制代码
module template_iir_lpf
               (
                clk,
                clk_enable,
                reset,
                filter_in,
                filter_out
                );

  input   clk; 
  input   clk_enable; 
  input   reset; 
  input   signed [12:0] filter_in; //sfix13_En13
  output  signed [12:0] filter_out; //sfix13_En13

////////////////////////////////////////////////////////////////
//Module Architecture: template_iir_lpf
////////////////////////////////////////////////////////////////
  // Local Functions
  // Type Definitions
  // Constants
  parameter signed [12:0] scaleconst1 = 13'b0100011000100; //sfix13_En12
  parameter signed [12:0] coeff_b1_section1 = 13'b0100000000000; //sfix13_En11
  parameter signed [12:0] coeff_b2_section1 = 13'b1000001100110; //sfix13_En11
  parameter signed [12:0] coeff_b3_section1 = 13'b0100000000000; //sfix13_En11
  parameter signed [12:0] coeff_a2_section1 = 13'b1000010000101; //sfix13_En11
  parameter signed [12:0] coeff_a3_section1 = 13'b0011110110011; //sfix13_En11
  parameter signed [12:0] scaleconst2 = 13'b0011101110100; //sfix13_En12
  parameter signed [12:0] coeff_b1_section2 = 13'b0100000000000; //sfix13_En11
  parameter signed [12:0] coeff_b2_section2 = 13'b1000010000011; //sfix13_En11
  parameter signed [12:0] coeff_b3_section2 = 13'b0100000000000; //sfix13_En11
  parameter signed [12:0] coeff_a2_section2 = 13'b1000100110001; //sfix13_En11
  parameter signed [12:0] coeff_a3_section2 = 13'b0011100001100; //sfix13_En11
  parameter signed [12:0] scaleconst3 = 13'b0010100001010; //sfix13_En12
  parameter signed [12:0] coeff_b1_section3 = 13'b0100000000000; //sfix13_En11
  parameter signed [12:0] coeff_b2_section3 = 13'b1000011101011; //sfix13_En11
  parameter signed [12:0] coeff_b3_section3 = 13'b0100000000000; //sfix13_En11
  parameter signed [12:0] coeff_a2_section3 = 13'b1001000001110; //sfix13_En11
  parameter signed [12:0] coeff_a3_section3 = 13'b0011000111100; //sfix13_En11
  parameter signed [12:0] scaleconst4 = 13'b0000111100110; //sfix13_En12
  parameter signed [12:0] coeff_b1_section4 = 13'b0100000000000; //sfix13_En11
  parameter signed [12:0] coeff_b2_section4 = 13'b1001100000101; //sfix13_En11
  parameter signed [12:0] coeff_b3_section4 = 13'b0100000000000; //sfix13_En11
  parameter signed [12:0] coeff_a2_section4 = 13'b1001100001100; //sfix13_En11
  parameter signed [12:0] coeff_a3_section4 = 13'b0010101010000; //sfix13_En11
  parameter signed [12:0] scaleconst5 = 13'b0000111001000; //sfix13_En12
  parameter signed [12:0] coeff_b1_section5 = 13'b0100000000000; //sfix13_En11
  parameter signed [12:0] coeff_b2_section5 = 13'b0100000000000; //sfix13_En11
  parameter signed [12:0] coeff_b3_section5 = 13'b0000000000000; //sfix13_En11
  parameter signed [12:0] coeff_a2_section5 = 13'b1100111001000; //sfix13_En11
  parameter signed [12:0] coeff_a3_section5 = 13'b0000000000000; //sfix13_En11
  // Signals
  reg  signed [12:0] input_register; // sfix13_En13
  wire signed [26:0] scale1; // sfix27_En25
  wire signed [18:0] factoredcsd_temp; // sfix19_En19
  wire signed [18:0] mulcsd_temp; // sfix19_En19
  wire signed [23:0] factoredcsd_temp_1; // sfix24_En24
  wire signed [23:0] mulcsd_temp_1; // sfix24_En24
  wire signed [24:0] factoredcsd_temp_2; // sfix25_En25
  // Section 1 Signals 
  wire signed [12:0] numtypeconvert1; // sfix13_En13
  wire signed [25:0] a1sum1; // sfix26_En21
  wire signed [13:0] dentypeconvert1; // sfix14_En13
  reg  signed [12:0] numdelay_section1 [0:1] ; // sfix13_En13
  reg  signed [13:0] dendelay_section1 [0:1] ; // sfix14_En13
  wire signed [25:0] a2mul1; // sfix26_En23
  wire signed [25:0] a3mul1; // sfix26_En23
  wire signed [25:0] b2mul1; // sfix26_En23
  wire signed [26:0] mulcsd_temp_2; // sfix27_En24
  wire signed [25:0] mulcsd_temp_3; // sfix26_En24
  wire signed [25:0] mulcsd_temp_4; // sfix26_En24
  wire signed [25:0] b1sum1; // sfix26_En21
  wire signed [25:0] b2sum1; // sfix26_En21
  wire signed [25:0] b1multypeconvert1; // sfix26_En21
  wire signed [25:0] add_cast; // sfix26_En21
  wire signed [25:0] add_cast_1; // sfix26_En21
  wire signed [26:0] add_temp; // sfix27_En21
  wire signed [25:0] add_cast_2; // sfix26_En21
  wire signed [25:0] add_cast_3; // sfix26_En21
  wire signed [26:0] add_temp_1; // sfix27_En21
  wire signed [25:0] a2sum1; // sfix26_En21
  wire signed [25:0] sub_cast; // sfix26_En21
  wire signed [25:0] sub_cast_1; // sfix26_En21
  wire signed [26:0] sub_temp; // sfix27_En21
  wire signed [25:0] sub_cast_2; // sfix26_En21
  wire signed [25:0] sub_cast_3; // sfix26_En21
  wire signed [26:0] sub_temp_1; // sfix27_En21
  reg  signed [13:0] sos_pipeline1; // sfix14_En13
  wire signed [26:0] scale2; // sfix27_En25
  wire signed [25:0] mulcsd_temp_5; // sfix26_En25
  // Section 2 Signals 
  wire signed [12:0] numtypeconvert2; // sfix13_En13
  wire signed [25:0] a1sum2; // sfix26_En21
  wire signed [13:0] dentypeconvert2; // sfix14_En13
  reg  signed [12:0] numdelay_section2 [0:1] ; // sfix13_En13
  reg  signed [13:0] dendelay_section2 [0:1] ; // sfix14_En13
  wire signed [25:0] a2mul2; // sfix26_En23
  wire signed [25:0] a3mul2; // sfix26_En23
  wire signed [25:0] b2mul2; // sfix26_En23
  wire signed [21:0] factoredcsd_temp_3; // sfix22_En21
  wire signed [22:0] mulcsd_temp_6; // sfix23_En21
  wire signed [25:0] factoredcsd_temp_4; // sfix26_En26
  wire signed [26:0] mulcsd_temp_7; // sfix27_En26
  wire signed [25:0] factoredcsd_temp_5; // sfix26_En24
  wire signed [26:0] unaryminus_temp; // sfix27_En24
  wire signed [25:0] mulcsd_temp_8; // sfix26_En24
  wire signed [25:0] mulcsd_temp_9; // sfix26_En24
  wire signed [25:0] b1sum2; // sfix26_En21
  wire signed [25:0] b2sum2; // sfix26_En21
  wire signed [25:0] b1multypeconvert2; // sfix26_En21
  wire signed [25:0] add_cast_4; // sfix26_En21
  wire signed [25:0] add_cast_5; // sfix26_En21
  wire signed [26:0] add_temp_2; // sfix27_En21
  wire signed [25:0] add_cast_6; // sfix26_En21
  wire signed [25:0] add_cast_7; // sfix26_En21
  wire signed [26:0] add_temp_3; // sfix27_En21
  wire signed [25:0] a2sum2; // sfix26_En21
  wire signed [25:0] sub_cast_4; // sfix26_En21
  wire signed [25:0] sub_cast_5; // sfix26_En21
  wire signed [26:0] sub_temp_2; // sfix27_En21
  wire signed [25:0] sub_cast_6; // sfix26_En21
  wire signed [25:0] sub_cast_7; // sfix26_En21
  wire signed [26:0] sub_temp_3; // sfix27_En21
  reg  signed [13:0] sos_pipeline2; // sfix14_En13
  wire signed [26:0] scale3; // sfix27_En25
  wire signed [21:0] factoredcsd_temp_6; // sfix22_En21
  wire signed [21:0] mulcsd_temp_10; // sfix22_En21
  wire signed [24:0] factoredcsd_temp_7; // sfix25_En24
  wire signed [24:0] mulcsd_temp_11; // sfix25_En24
  wire signed [24:0] factoredcsd_temp_8; // sfix25_En25
  // Section 3 Signals 
  wire signed [12:0] numtypeconvert3; // sfix13_En13
  wire signed [25:0] a1sum3; // sfix26_En21
  wire signed [13:0] dentypeconvert3; // sfix14_En13
  reg  signed [12:0] numdelay_section3 [0:1] ; // sfix13_En13
  reg  signed [13:0] dendelay_section3 [0:1] ; // sfix14_En13
  wire signed [25:0] a2mul3; // sfix26_En23
  wire signed [25:0] a3mul3; // sfix26_En23
  wire signed [25:0] b2mul3; // sfix26_En23
  wire signed [21:0] factoredcsd_temp_9; // sfix22_En21
  wire signed [22:0] mulcsd_temp_12; // sfix23_En21
  wire signed [24:0] factoredcsd_temp_10; // sfix25_En24
  wire signed [25:0] mulcsd_temp_13; // sfix26_En24
  wire signed [25:0] factoredcsd_temp_11; // sfix26_En24
  wire signed [26:0] unaryminus_temp_1; // sfix27_En24
  wire signed [25:0] mulcsd_temp_14; // sfix26_En24
  wire signed [25:0] mulcsd_temp_15; // sfix26_En24
  wire signed [25:0] b1sum3; // sfix26_En21
  wire signed [25:0] b2sum3; // sfix26_En21
  wire signed [25:0] b1multypeconvert3; // sfix26_En21
  wire signed [25:0] add_cast_8; // sfix26_En21
  wire signed [25:0] add_cast_9; // sfix26_En21
  wire signed [26:0] add_temp_4; // sfix27_En21
  wire signed [25:0] add_cast_10; // sfix26_En21
  wire signed [25:0] add_cast_11; // sfix26_En21
  wire signed [26:0] add_temp_5; // sfix27_En21
  wire signed [25:0] a2sum3; // sfix26_En21
  wire signed [25:0] sub_cast_8; // sfix26_En21
  wire signed [25:0] sub_cast_9; // sfix26_En21
  wire signed [26:0] sub_temp_4; // sfix27_En21
  wire signed [25:0] sub_cast_10; // sfix26_En21
  wire signed [25:0] sub_cast_11; // sfix26_En21
  wire signed [26:0] sub_temp_5; // sfix27_En21
  reg  signed [13:0] sos_pipeline3; // sfix14_En13
  wire signed [26:0] scale4; // sfix27_En25
  wire signed [23:0] mulcsd_temp_16; // sfix24_En25
  // Section 4 Signals 
  wire signed [12:0] numtypeconvert4; // sfix13_En13
  wire signed [25:0] a1sum4; // sfix26_En21
  wire signed [13:0] dentypeconvert4; // sfix14_En13
  reg  signed [12:0] numdelay_section4 [0:1] ; // sfix13_En13
  reg  signed [13:0] dendelay_section4 [0:1] ; // sfix14_En13
  wire signed [25:0] a2mul4; // sfix26_En23
  wire signed [25:0] a3mul4; // sfix26_En23
  wire signed [25:0] b2mul4; // sfix26_En23
  wire signed [26:0] mulcsd_temp_17; // sfix27_En24
  wire signed [18:0] factoredcsd_temp_12; // sfix19_En18
  wire signed [18:0] mulcsd_temp_18; // sfix19_En18
  wire signed [21:0] factoredcsd_temp_13; // sfix22_En21
  wire signed [21:0] mulcsd_temp_19; // sfix22_En21
  wire signed [24:0] factoredcsd_temp_14; // sfix25_En24
  wire signed [25:0] mulcsd_temp_20; // sfix26_En24
  wire signed [25:0] b1sum4; // sfix26_En21
  wire signed [25:0] b2sum4; // sfix26_En21
  wire signed [25:0] b1multypeconvert4; // sfix26_En21
  wire signed [25:0] add_cast_12; // sfix26_En21
  wire signed [25:0] add_cast_13; // sfix26_En21
  wire signed [26:0] add_temp_6; // sfix27_En21
  wire signed [25:0] add_cast_14; // sfix26_En21
  wire signed [25:0] add_cast_15; // sfix26_En21
  wire signed [26:0] add_temp_7; // sfix27_En21
  wire signed [25:0] a2sum4; // sfix26_En21
  wire signed [25:0] sub_cast_12; // sfix26_En21
  wire signed [25:0] sub_cast_13; // sfix26_En21
  wire signed [26:0] sub_temp_6; // sfix27_En21
  wire signed [25:0] sub_cast_14; // sfix26_En21
  wire signed [25:0] sub_cast_15; // sfix26_En21
  wire signed [26:0] sub_temp_7; // sfix27_En21
  reg  signed [13:0] sos_pipeline4; // sfix14_En13
  wire signed [26:0] scale5; // sfix27_En25
  wire signed [23:0] mulcsd_temp_21; // sfix24_En25
  // Section 5 Signals 
  wire signed [12:0] numtypeconvert5; // sfix13_En13
  wire signed [25:0] a1sum5; // sfix26_En21
  wire signed [25:0] b1sum5; // sfix26_En21
  wire signed [13:0] dentypeconvert5; // sfix14_En13
  reg  signed [12:0] numdelay_section5; // sfix13_En13
  reg  signed [13:0] dendelay_section5; // sfix14_En13
  wire signed [25:0] a2mul5; // sfix26_En23
  wire signed [25:0] mulcsd_temp_22; // sfix26_En24
  wire signed [25:0] b1multypeconvert5; // sfix26_En21
  wire signed [25:0] add_cast_16; // sfix26_En21
  wire signed [25:0] add_cast_17; // sfix26_En21
  wire signed [26:0] add_temp_8; // sfix27_En21
  wire signed [25:0] sub_cast_16; // sfix26_En21
  wire signed [25:0] sub_cast_17; // sfix26_En21
  wire signed [26:0] sub_temp_8; // sfix27_En21
  wire signed [12:0] output_typeconvert; // sfix13_En13
  reg  signed [12:0] output_register; // sfix13_En13

  // Block Statements
  always @ (posedge clk or posedge reset)
    begin: input_reg_process
      if (reset == 1'b1) begin
        input_register <= 0;
      end
      else begin
        if (clk_enable == 1'b1) begin
          input_register <= filter_in;
        end
      end
    end // input_reg_process

// For FCSD of 2244, using factorization: 33 17 2 2 
// 
  assign mulcsd_temp = 
        $signed({input_register, 5'b00000}) +
        input_register;
  assign factoredcsd_temp = mulcsd_temp;

  assign mulcsd_temp_1 = 
        $signed({factoredcsd_temp, 4'b0000}) +
        factoredcsd_temp;
  assign factoredcsd_temp_1 = mulcsd_temp_1;

  assign factoredcsd_temp_2 = $signed({factoredcsd_temp_1[22:0], 2'b00});

  assign scale1 = $signed({{2{factoredcsd_temp_2[24]}}, factoredcsd_temp_2});

  // ------------------ Section 1 ------------------

  assign numtypeconvert1 = (scale1[24:0] + {~scale1[26], {11{scale1[26]}}})>>>12;

  assign dentypeconvert1 = (a1sum1[21:0] + {~a1sum1[25], {7{a1sum1[25]}}})>>>8;

  always @ (posedge clk or posedge reset)
    begin: numdelay_process_section1
      if (reset == 1'b1) begin
        numdelay_section1[0] <= 13'b0000000000000;
        numdelay_section1[1] <= 13'b0000000000000;
      end
      else begin
        if (clk_enable == 1'b1) begin
          numdelay_section1[1] <= numdelay_section1[0];
          numdelay_section1[0] <= numtypeconvert1;
        end
      end
    end // numdelay_process_section1

  always @ (posedge clk or posedge reset)
    begin: dendelay_process_section1
      if (reset == 1'b1) begin
        dendelay_section1[0] <= 14'b00000000000000;
        dendelay_section1[1] <= 14'b00000000000000;
      end
      else begin
        if (clk_enable == 1'b1) begin
          dendelay_section1[1] <= dendelay_section1[0];
          dendelay_section1[0] <= dentypeconvert1;
        end
      end
    end // dendelay_process_section1

// For FCSD of -3963, optimizing to CSD due to lower cost
  assign mulcsd_temp_2 = - (
        $signed({dendelay_section1[0], 12'b000000000000}) -
        $signed({dendelay_section1[0], 8'b00000000}) +
        $signed({dendelay_section1[0], 7'b0000000}) -
        $signed({dendelay_section1[0], 3'b000}) +
        $signed({dendelay_section1[0], 2'b00}) -
        dendelay_section1[0]);
  assign a2mul1 = (mulcsd_temp_2[26:0] + {1'b0, ~mulcsd_temp_2[26]})>>>1;

// For FCSD of 1971, optimizing to CSD due to lower cost
  assign mulcsd_temp_3 = 
        $signed({dendelay_section1[1], 11'b00000000000}) -
        $signed({dendelay_section1[1], 7'b0000000}) +
        $signed({dendelay_section1[1], 6'b000000}) -
        $signed({dendelay_section1[1], 4'b0000}) +
        $signed({dendelay_section1[1], 2'b00}) -
        dendelay_section1[1];
  assign a3mul1 = ({{1{mulcsd_temp_3[25]}}, mulcsd_temp_3[25:0]} + {1'b0, ~mulcsd_temp_3[25]})>>>1;

// For FCSD of -3994, optimizing to CSD due to lower cost
  assign mulcsd_temp_4 = - (
        $signed({numdelay_section1[0], 12'b000000000000}) -
        $signed({numdelay_section1[0], 7'b0000000}) +
        $signed({numdelay_section1[0], 5'b00000}) -
        $signed({numdelay_section1[0], 3'b000}) +
        $signed({numdelay_section1[0], 1'b0}));
  assign b2mul1 = ({{1{mulcsd_temp_4[25]}}, mulcsd_temp_4[25:0]} + {1'b0, ~mulcsd_temp_4[25]})>>>1;

  assign b1multypeconvert1 = $signed({numtypeconvert1[12:0], 8'b00000000});

  assign add_cast = b1multypeconvert1;
  assign add_cast_1 = ({{2{b2mul1[25]}}, b2mul1[25:0]} + {~b2mul1[25], {1{b2mul1[25]}}})>>>2;
  assign add_temp = add_cast + add_cast_1;
  assign b1sum1 = add_temp[25:0];

  assign add_cast_2 = b1sum1;
  assign add_cast_3 = $signed({numdelay_section1[1][12:0], 8'b00000000});
  assign add_temp_1 = add_cast_2 + add_cast_3;
  assign b2sum1 = add_temp_1[25:0];

  assign sub_cast = b2sum1;
  assign sub_cast_1 = ({{2{a2mul1[25]}}, a2mul1[25:0]} + {~a2mul1[25], {1{a2mul1[25]}}})>>>2;
  assign sub_temp = sub_cast - sub_cast_1;
  assign a2sum1 = sub_temp[25:0];

  assign sub_cast_2 = a2sum1;
  assign sub_cast_3 = ({{2{a3mul1[25]}}, a3mul1[25:0]} + {~a3mul1[25], {1{a3mul1[25]}}})>>>2;
  assign sub_temp_1 = sub_cast_2 - sub_cast_3;
  assign a1sum1 = sub_temp_1[25:0];

  always @ (posedge clk or posedge reset)
    begin: sos_pipeline_process_section1
      if (reset == 1'b1) begin
        sos_pipeline1 <= 0;
      end
      else begin
        if (clk_enable == 1'b1) begin
          sos_pipeline1 <= dentypeconvert1;
        end
      end
    end // sos_pipeline_process_section1

// For FCSD of 1908, optimizing to CSD due to lower cost
  assign mulcsd_temp_5 = 
        $signed({sos_pipeline1, 11'b00000000000}) -
        $signed({sos_pipeline1, 8'b00000000}) +
        $signed({sos_pipeline1, 7'b0000000}) -
        $signed({sos_pipeline1, 4'b0000}) +
        $signed({sos_pipeline1, 2'b00});
  assign scale2 = $signed({{1{mulcsd_temp_5[25]}}, mulcsd_temp_5});
                               
  // ------------------ Section 2 ------------------

  assign numtypeconvert2 = (scale2[24:0] + {~scale2[26], {11{scale2[26]}}})>>>12;

  assign dentypeconvert2 = (a1sum2[21:0] + {~a1sum2[25], {7{a1sum2[25]}}})>>>8;

  always @ (posedge clk or posedge reset)
    begin: numdelay_process_section2
      if (reset == 1'b1) begin
        numdelay_section2[0] <= 13'b0000000000000;
        numdelay_section2[1] <= 13'b0000000000000;
      end
      else begin
        if (clk_enable == 1'b1) begin
          numdelay_section2[1] <= numdelay_section2[0];
          numdelay_section2[0] <= numtypeconvert2;
        end
      end
    end // numdelay_process_section2

  always @ (posedge clk or posedge reset)
    begin: dendelay_process_section2
      if (reset == 1'b1) begin
        dendelay_section2[0] <= 14'b00000000000000;
        dendelay_section2[1] <= 14'b00000000000000;
      end
      else begin
        if (clk_enable == 1'b1) begin
          dendelay_section2[1] <= dendelay_section2[0];
          dendelay_section2[0] <= dentypeconvert2;
        end
      end
    end // dendelay_process_section2

// For FCSD of -3791, using factorization: 223 17 
// 
  assign mulcsd_temp_6 = 
        $signed({dendelay_section2[0], 8'b00000000}) -
        $signed({dendelay_section2[0], 6'b000000}) +
        $signed({dendelay_section2[0], 5'b00000}) -
        dendelay_section2[0];
  assign factoredcsd_temp_3 = mulcsd_temp_6[21:0];

  assign mulcsd_temp_7 = 
        $signed({factoredcsd_temp_3, 4'b0000}) +
        factoredcsd_temp_3;
  assign factoredcsd_temp_4 = mulcsd_temp_7[25:0];

  assign factoredcsd_temp_5 = factoredcsd_temp_4;

  assign unaryminus_temp = (factoredcsd_temp_5==26'b10000000000000000000000000) ? $signed({1'b0, factoredcsd_temp_5}) : -factoredcsd_temp_5;
  assign a2mul2 = (unaryminus_temp[26:0] + {1'b0, ~unaryminus_temp[26]})>>>1;

// For FCSD of 1804, optimizing to CSD due to lower cost
  assign mulcsd_temp_8 = 
        $signed({dendelay_section2[1], 11'b00000000000}) -
        $signed({dendelay_section2[1], 8'b00000000}) +
        $signed({dendelay_section2[1], 4'b0000}) -
        $signed({dendelay_section2[1], 2'b00});
  assign a3mul2 = ({{1{mulcsd_temp_8[25]}}, mulcsd_temp_8[25:0]} + {1'b0, ~mulcsd_temp_8[25]})>>>1;

// For FCSD of -3965, optimizing to CSD due to lower cost
  assign mulcsd_temp_9 = - (
        $signed({numdelay_section2[0], 12'b000000000000}) -
        $signed({numdelay_section2[0], 8'b00000000}) +
        $signed({numdelay_section2[0], 7'b0000000}) -
        $signed({numdelay_section2[0], 2'b00}) +
        numdelay_section2[0]);
  assign b2mul2 = ({{1{mulcsd_temp_9[25]}}, mulcsd_temp_9[25:0]} + {1'b0, ~mulcsd_temp_9[25]})>>>1;

  assign b1multypeconvert2 = $signed({numtypeconvert2[12:0], 8'b00000000});

  assign add_cast_4 = b1multypeconvert2;
  assign add_cast_5 = ({{2{b2mul2[25]}}, b2mul2[25:0]} + {~b2mul2[25], {1{b2mul2[25]}}})>>>2;
  assign add_temp_2 = add_cast_4 + add_cast_5;
  assign b1sum2 = add_temp_2[25:0];

  assign add_cast_6 = b1sum2;
  assign add_cast_7 = $signed({numdelay_section2[1][12:0], 8'b00000000});
  assign add_temp_3 = add_cast_6 + add_cast_7;
  assign b2sum2 = add_temp_3[25:0];

  assign sub_cast_4 = b2sum2;
  assign sub_cast_5 = ({{2{a2mul2[25]}}, a2mul2[25:0]} + {~a2mul2[25], {1{a2mul2[25]}}})>>>2;
  assign sub_temp_2 = sub_cast_4 - sub_cast_5;
  assign a2sum2 = sub_temp_2[25:0];

  assign sub_cast_6 = a2sum2;
  assign sub_cast_7 = ({{2{a3mul2[25]}}, a3mul2[25:0]} + {~a3mul2[25], {1{a3mul2[25]}}})>>>2;
  assign sub_temp_3 = sub_cast_6 - sub_cast_7;
  assign a1sum2 = sub_temp_3[25:0];

  always @ (posedge clk or posedge reset)
    begin: sos_pipeline_process_section2
      if (reset == 1'b1) begin
        sos_pipeline2 <= 0;
      end
      else begin
        if (clk_enable == 1'b1) begin
          sos_pipeline2 <= dentypeconvert2;
        end
      end
    end // sos_pipeline_process_section2

// For FCSD of 1290, using factorization: 129 5 2 
// 
  assign mulcsd_temp_10 = 
        $signed({sos_pipeline2, 7'b0000000}) +
        sos_pipeline2;
  assign factoredcsd_temp_6 = mulcsd_temp_10;

  assign mulcsd_temp_11 = 
        $signed({factoredcsd_temp_6, 2'b00}) +
        factoredcsd_temp_6;
  assign factoredcsd_temp_7 = mulcsd_temp_11;

  assign factoredcsd_temp_8 = $signed({factoredcsd_temp_7[23:0], 1'b0});

  assign scale3 = $signed({{2{factoredcsd_temp_8[24]}}, factoredcsd_temp_8});

  // ------------------ Section 3 ------------------

  assign numtypeconvert3 = (scale3[24:0] + {~scale3[26], {11{scale3[26]}}})>>>12;

  assign dentypeconvert3 = (a1sum3[21:0] + {~a1sum3[25], {7{a1sum3[25]}}})>>>8;

  always @ (posedge clk or posedge reset)
    begin: numdelay_process_section3
      if (reset == 1'b1) begin
        numdelay_section3[0] <= 13'b0000000000000;
        numdelay_section3[1] <= 13'b0000000000000;
      end
      else begin
        if (clk_enable == 1'b1) begin
          numdelay_section3[1] <= numdelay_section3[0];
          numdelay_section3[0] <= numtypeconvert3;
        end
      end
    end // numdelay_process_section3

  always @ (posedge clk or posedge reset)
    begin: dendelay_process_section3
      if (reset == 1'b1) begin
        dendelay_section3[0] <= 14'b00000000000000;
        dendelay_section3[1] <= 14'b00000000000000;
      end
      else begin
        if (clk_enable == 1'b1) begin
          dendelay_section3[1] <= dendelay_section3[0];
          dendelay_section3[0] <= dentypeconvert3;
        end
      end
    end // dendelay_process_section3

// For FCSD of -3570, using factorization: 255 7 2 
// 
  assign mulcsd_temp_12 = 
        $signed({dendelay_section3[0], 8'b00000000}) -
        dendelay_section3[0];
  assign factoredcsd_temp_9 = mulcsd_temp_12[21:0];

  assign mulcsd_temp_13 = 
        $signed({factoredcsd_temp_9, 3'b000}) -
        factoredcsd_temp_9;
  assign factoredcsd_temp_10 = mulcsd_temp_13[24:0];

  assign factoredcsd_temp_11 = $signed({factoredcsd_temp_10[24:0], 1'b0});

  assign unaryminus_temp_1 = (factoredcsd_temp_11==26'b10000000000000000000000000) ? $signed({1'b0, factoredcsd_temp_11}) : -factoredcsd_temp_11;
  assign a2mul3 = (unaryminus_temp_1[26:0] + {1'b0, ~unaryminus_temp_1[26]})>>>1;

// For FCSD of 1596, optimizing to CSD due to lower cost
  assign mulcsd_temp_14 = 
        $signed({dendelay_section3[1], 11'b00000000000}) -
        $signed({dendelay_section3[1], 9'b000000000}) +
        $signed({dendelay_section3[1], 6'b000000}) -
        $signed({dendelay_section3[1], 2'b00});
  assign a3mul3 = ({{1{mulcsd_temp_14[25]}}, mulcsd_temp_14[25:0]} + {1'b0, ~mulcsd_temp_14[25]})>>>1;

// For FCSD of -3861, optimizing to CSD due to lower cost
  assign mulcsd_temp_15 = - (
        $signed({numdelay_section3[0], 12'b000000000000}) -
        $signed({numdelay_section3[0], 8'b00000000}) +
        $signed({numdelay_section3[0], 4'b0000}) +
        $signed({numdelay_section3[0], 2'b00}) +
        numdelay_section3[0]);
  assign b2mul3 = ({{1{mulcsd_temp_15[25]}}, mulcsd_temp_15[25:0]} + {1'b0, ~mulcsd_temp_15[25]})>>>1;

  assign b1multypeconvert3 = $signed({numtypeconvert3[12:0], 8'b00000000});

  assign add_cast_8 = b1multypeconvert3;
  assign add_cast_9 = ({{2{b2mul3[25]}}, b2mul3[25:0]} + {~b2mul3[25], {1{b2mul3[25]}}})>>>2;
  assign add_temp_4 = add_cast_8 + add_cast_9;
  assign b1sum3 = add_temp_4[25:0];

  assign add_cast_10 = b1sum3;
  assign add_cast_11 = $signed({numdelay_section3[1][12:0], 8'b00000000});
  assign add_temp_5 = add_cast_10 + add_cast_11;
  assign b2sum3 = add_temp_5[25:0];

  assign sub_cast_8 = b2sum3;
  assign sub_cast_9 = ({{2{a2mul3[25]}}, a2mul3[25:0]} + {~a2mul3[25], {1{a2mul3[25]}}})>>>2;
  assign sub_temp_4 = sub_cast_8 - sub_cast_9;
  assign a2sum3 = sub_temp_4[25:0];

  assign sub_cast_10 = a2sum3;
  assign sub_cast_11 = ({{2{a3mul3[25]}}, a3mul3[25:0]} + {~a3mul3[25], {1{a3mul3[25]}}})>>>2;
  assign sub_temp_5 = sub_cast_10 - sub_cast_11;
  assign a1sum3 = sub_temp_5[25:0];

  always @ (posedge clk or posedge reset)
    begin: sos_pipeline_process_section3
      if (reset == 1'b1) begin
        sos_pipeline3 <= 0;
      end
      else begin
        if (clk_enable == 1'b1) begin
          sos_pipeline3 <= dentypeconvert3;
        end
      end
    end // sos_pipeline_process_section3

// For FCSD of 486, optimizing to CSD due to lower cost
  assign mulcsd_temp_16 = 
        $signed({sos_pipeline3, 9'b000000000}) -
        $signed({sos_pipeline3, 5'b00000}) +
        $signed({sos_pipeline3, 3'b000}) -
        $signed({sos_pipeline3, 1'b0});
  assign scale4 = $signed({{3{mulcsd_temp_16[23]}}, mulcsd_temp_16});

  // ------------------ Section 4 ------------------

  assign numtypeconvert4 = (scale4[24:0] + {~scale4[26], {11{scale4[26]}}})>>>12;

  assign dentypeconvert4 = (a1sum4[21:0] + {~a1sum4[25], {7{a1sum4[25]}}})>>>8;

  always @ (posedge clk or posedge reset)
    begin: numdelay_process_section4
      if (reset == 1'b1) begin
        numdelay_section4[0] <= 13'b0000000000000;
        numdelay_section4[1] <= 13'b0000000000000;
      end
      else begin
        if (clk_enable == 1'b1) begin
          numdelay_section4[1] <= numdelay_section4[0];
          numdelay_section4[0] <= numtypeconvert4;
        end
      end
    end // numdelay_process_section4

  always @ (posedge clk or posedge reset)
    begin: dendelay_process_section4
      if (reset == 1'b1) begin
        dendelay_section4[0] <= 14'b00000000000000;
        dendelay_section4[1] <= 14'b00000000000000;
      end
      else begin
        if (clk_enable == 1'b1) begin
          dendelay_section4[1] <= dendelay_section4[0];
          dendelay_section4[0] <= dentypeconvert4;
        end
      end
    end // dendelay_process_section4

// For FCSD of -3316, optimizing to CSD due to lower cost
  assign mulcsd_temp_17 = - (
        $signed({dendelay_section4[0], 12'b000000000000}) -
        $signed({dendelay_section4[0], 10'b0000000000}) +
        $signed({dendelay_section4[0], 8'b00000000}) -
        $signed({dendelay_section4[0], 4'b0000}) +
        $signed({dendelay_section4[0], 2'b00}));
  assign a2mul4 = (mulcsd_temp_17[26:0] + {1'b0, ~mulcsd_temp_17[26]})>>>1;

// For FCSD of 1360, using factorization: 17 5 2 2 2 2 
// 
  assign mulcsd_temp_18 = 
        $signed({dendelay_section4[1], 4'b0000}) +
        dendelay_section4[1];
  assign factoredcsd_temp_12 = mulcsd_temp_18;

  assign mulcsd_temp_19 = 
        $signed({factoredcsd_temp_12, 2'b00}) +
        factoredcsd_temp_12;
  assign factoredcsd_temp_13 = mulcsd_temp_19;

  assign factoredcsd_temp_14 = $signed({factoredcsd_temp_13[20:0], 4'b0000});

  assign a3mul4 = ({{2{factoredcsd_temp_14[24]}}, factoredcsd_temp_14[24:0]} + {1'b0, ~factoredcsd_temp_14[24]})>>>1;

// For FCSD of -3323, optimizing to CSD due to lower cost
  assign mulcsd_temp_20 = - (
        $signed({numdelay_section4[0], 12'b000000000000}) -
        $signed({numdelay_section4[0], 10'b0000000000}) +
        $signed({numdelay_section4[0], 8'b00000000}) -
        $signed({numdelay_section4[0], 3'b000}) +
        $signed({numdelay_section4[0], 2'b00}) -
        numdelay_section4[0]);
  assign b2mul4 = ({{1{mulcsd_temp_20[25]}}, mulcsd_temp_20[25:0]} + {1'b0, ~mulcsd_temp_20[25]})>>>1;

  assign b1multypeconvert4 = $signed({numtypeconvert4[12:0], 8'b00000000});

  assign add_cast_12 = b1multypeconvert4;
  assign add_cast_13 = ({{2{b2mul4[25]}}, b2mul4[25:0]} + {~b2mul4[25], {1{b2mul4[25]}}})>>>2;
  assign add_temp_6 = add_cast_12 + add_cast_13;
  assign b1sum4 = add_temp_6[25:0];

  assign add_cast_14 = b1sum4;
  assign add_cast_15 = $signed({numdelay_section4[1][12:0], 8'b00000000});
  assign add_temp_7 = add_cast_14 + add_cast_15;
  assign b2sum4 = add_temp_7[25:0];

  assign sub_cast_12 = b2sum4;
  assign sub_cast_13 = ({{2{a2mul4[25]}}, a2mul4[25:0]} + {~a2mul4[25], {1{a2mul4[25]}}})>>>2;
  assign sub_temp_6 = sub_cast_12 - sub_cast_13;
  assign a2sum4 = sub_temp_6[25:0];

  assign sub_cast_14 = a2sum4;
  assign sub_cast_15 = ({{2{a3mul4[25]}}, a3mul4[25:0]} + {~a3mul4[25], {1{a3mul4[25]}}})>>>2;
  assign sub_temp_7 = sub_cast_14 - sub_cast_15;
  assign a1sum4 = sub_temp_7[25:0];

  always @ (posedge clk or posedge reset)
    begin: sos_pipeline_process_section4
      if (reset == 1'b1) begin
        sos_pipeline4 <= 0;
      end
      else begin
        if (clk_enable == 1'b1) begin
          sos_pipeline4 <= dentypeconvert4;
        end
      end
    end // sos_pipeline_process_section4

// For FCSD of 456, optimizing to CSD due to lower cost
  assign mulcsd_temp_21 = 
        $signed({sos_pipeline4, 9'b000000000}) -
        $signed({sos_pipeline4, 6'b000000}) +
        $signed({sos_pipeline4, 3'b000});
  assign scale5 = $signed({{3{mulcsd_temp_21[23]}}, mulcsd_temp_21});

  // ------------------ Section 5 (First Order) ------------------

  assign numtypeconvert5 = (scale5[24:0] + {~scale5[26], {11{scale5[26]}}})>>>12;

  assign dentypeconvert5 = (a1sum5[21:0] + {~a1sum5[25], {7{a1sum5[25]}}})>>>8;

  always @ (posedge clk or posedge reset)
    begin: numdelay_process_section5
      if (reset == 1'b1) begin
        numdelay_section5 <= 0;
      end
      else begin
        if (clk_enable == 1'b1) begin
          numdelay_section5 <= numtypeconvert5;
        end
      end
    end // numdelay_process_section5

  always @ (posedge clk or posedge reset)
    begin: dendelay_process_section5
      if (reset == 1'b1) begin
        dendelay_section5 <= 0;
      end
      else begin
        if (clk_enable == 1'b1) begin
          dendelay_section5 <= dentypeconvert5;
        end
      end
    end // dendelay_process_section5

// For FCSD of -1592, optimizing to CSD due to lower cost
  assign mulcsd_temp_22 = - (
        $signed({dendelay_section5, 11'b00000000000}) -
        $signed({dendelay_section5, 9'b000000000}) +
        $signed({dendelay_section5, 6'b000000}) -
        $signed({dendelay_section5, 3'b000}));
  assign a2mul5 = ({{1{mulcsd_temp_22[25]}}, mulcsd_temp_22[25:0]} + {1'b0, ~mulcsd_temp_22[25]})>>>1;

  assign b1multypeconvert5 = $signed({numtypeconvert5[12:0], 8'b00000000});

  assign add_cast_16 = b1multypeconvert5;
  assign add_cast_17 = $signed({numdelay_section5[12:0], 8'b00000000});
  assign add_temp_8 = add_cast_16 + add_cast_17;
  assign b1sum5 = add_temp_8[25:0];

  assign sub_cast_16 = b1sum5;
  assign sub_cast_17 = ({{2{a2mul5[25]}}, a2mul5[25:0]} + {~a2mul5[25], {1{a2mul5[25]}}})>>>2;
  assign sub_temp_8 = sub_cast_16 - sub_cast_17;
  assign a1sum5 = sub_temp_8[25:0];

  assign output_typeconvert = dentypeconvert5[12:0];

  always @ (posedge clk or posedge reset)
    begin: Output_Register_process
      if (reset == 1'b1) begin
        output_register <= 0;
      end
      else begin
        if (clk_enable == 1'b1) begin
          output_register <= output_typeconvert;
        end
      end
    end // Output_Register_process

  // Assignment Statements
  assign filter_out = output_register;
endmodule  // template_iir_lpf

点击查看代码

复制代码
module iir_remove_dc_template
               (
                clk,
                clk_enable,
                reset,
                filter_in,
                filter_out
                );

  input   clk; 
  input   clk_enable; 
  input   reset; 
  input   signed [12:0] filter_in; //sfix13_En13
  output  signed [12:0] filter_out; //sfix13_En13

////////////////////////////////////////////////////////////////
//Module Architecture: iir_remove_dc_template
////////////////////////////////////////////////////////////////
  // Local Functions
  // Type Definitions
  // Constants
  parameter signed [12:0] scaleconst1 = 13'b0111111101100; //sfix13_En12
  parameter signed [12:0] coeff_b1_section1 = 13'b0100000000000; //sfix13_En11
  parameter signed [12:0] coeff_b2_section1 = 13'b0000000000000; //sfix13_En11
  parameter signed [12:0] coeff_b3_section1 = 13'b1100000000000; //sfix13_En11
  parameter signed [12:0] coeff_a2_section1 = 13'b0000000000000; //sfix13_En11
  parameter signed [12:0] coeff_a3_section1 = 13'b1100000010100; //sfix13_En11
  // Signals
  reg  signed [12:0] input_register; // sfix13_En13
  wire signed [26:0] scale1; // sfix27_En25
  wire signed [25:0] mulcsd_temp; // sfix26_En25
  // Section 1 Signals 
  wire signed [12:0] numtypeconvert1; // sfix13_En13
  wire signed [25:0] a1sum1; // sfix26_En21
  wire signed [13:0] dentypeconvert1; // sfix14_En13
  reg  signed [12:0] numdelay_section1 [0:1] ; // sfix13_En13
  reg  signed [13:0] dendelay_section1 [0:1] ; // sfix14_En13
  wire signed [25:0] a3mul1; // sfix26_En23
  wire signed [25:0] b3mul1; // sfix26_En23
  wire signed [25:0] mulcsd_temp_1; // sfix26_En24
  wire signed [13:0] unaryminus_temp; // sfix14_En13
  wire signed [25:0] b1sum1; // sfix26_En21
  wire signed [25:0] b2sum1; // sfix26_En21
  wire signed [25:0] b1multypeconvert1; // sfix26_En21
  wire signed [25:0] add_cast; // sfix26_En21
  wire signed [25:0] add_cast_1; // sfix26_En21
  wire signed [26:0] add_temp; // sfix27_En21
  wire signed [25:0] sub_cast; // sfix26_En21
  wire signed [25:0] sub_cast_1; // sfix26_En21
  wire signed [26:0] sub_temp; // sfix27_En21
  wire signed [12:0] output_typeconvert; // sfix13_En13
  reg  signed [12:0] output_register; // sfix13_En13

  // Block Statements
  always @ (posedge clk or posedge reset)
    begin: input_reg_process
      if (reset == 1'b1) begin
        input_register <= 0;
      end
      else begin
        if (clk_enable == 1'b1) begin
          input_register <= filter_in;
        end
      end
    end // input_reg_process

// For FCSD of 4076, optimizing to CSD due to lower cost
  assign mulcsd_temp = 
        $signed({input_register, 12'b000000000000}) -
        $signed({input_register, 5'b00000}) +
        $signed({input_register, 4'b0000}) -
        $signed({input_register, 2'b00});
  assign scale1 = $signed({{1{mulcsd_temp[25]}}, mulcsd_temp});

  // ------------------ Section 1 ------------------

  assign numtypeconvert1 = (scale1[24:0] + {~scale1[26], {11{scale1[26]}}})>>>12;

  assign dentypeconvert1 = (a1sum1[21:0] + {~a1sum1[25], {7{a1sum1[25]}}})>>>8;

  always @ (posedge clk or posedge reset)
    begin: numdelay_process_section1
      if (reset == 1'b1) begin
        numdelay_section1[0] <= 13'b0000000000000;
        numdelay_section1[1] <= 13'b0000000000000;
      end
      else begin
        if (clk_enable == 1'b1) begin
          numdelay_section1[1] <= numdelay_section1[0];
          numdelay_section1[0] <= numtypeconvert1;
        end
      end
    end // numdelay_process_section1

  always @ (posedge clk or posedge reset)
    begin: dendelay_process_section1
      if (reset == 1'b1) begin
        dendelay_section1[0] <= 14'b00000000000000;
        dendelay_section1[1] <= 14'b00000000000000;
      end
      else begin
        if (clk_enable == 1'b1) begin
          dendelay_section1[1] <= dendelay_section1[0];
          dendelay_section1[0] <= dentypeconvert1;
        end
      end
    end // dendelay_process_section1

// For FCSD of -2028, optimizing to CSD due to lower cost
  assign mulcsd_temp_1 = - (
        $signed({dendelay_section1[1], 11'b00000000000}) -
        $signed({dendelay_section1[1], 5'b00000}) +
        $signed({dendelay_section1[1], 4'b0000}) -
        $signed({dendelay_section1[1], 2'b00}));
  assign a3mul1 = ({{1{mulcsd_temp_1[25]}}, mulcsd_temp_1[25:0]} + {1'b0, ~mulcsd_temp_1[25]})>>>1;

  assign unaryminus_temp = (numdelay_section1[1]==13'b1000000000000) ? $signed({1'b0, numdelay_section1[1]}) : -numdelay_section1[1];
  assign b3mul1 = $signed({unaryminus_temp[13:0], 10'b0000000000});

  assign b1multypeconvert1 = $signed({numtypeconvert1[12:0], 8'b00000000});

  assign b1sum1 = b1multypeconvert1;

  assign add_cast = b1sum1;
  assign add_cast_1 = ({{2{b3mul1[25]}}, b3mul1[25:0]} + {~b3mul1[25], {1{b3mul1[25]}}})>>>2;
  assign add_temp = add_cast + add_cast_1;
  assign b2sum1 = add_temp[25:0];

  assign sub_cast = b2sum1;
  assign sub_cast_1 = ({{2{a3mul1[25]}}, a3mul1[25:0]} + {~a3mul1[25], {1{a3mul1[25]}}})>>>2;
  assign sub_temp = sub_cast - sub_cast_1;
  assign a1sum1 = sub_temp[25:0];

  assign output_typeconvert = dentypeconvert1[12:0];

  always @ (posedge clk or posedge reset)
    begin: Output_Register_process
      if (reset == 1'b1) begin
        output_register <= 0;
      end
      else begin
        if (clk_enable == 1'b1) begin
          output_register <= output_typeconvert;
        end
      end
    end // Output_Register_process

  // Assignment Statements
  assign filter_out = output_register;
endmodule  // iir_remove_dc_template

点击查看代码

复制代码
module template_iir_signle_peak
               (
                clk,
                clk_enable,
                reset,
                filter_in,
                filter_out
                );

  input   clk; 
  input   clk_enable; 
  input   reset; 
  input   signed [12:0] filter_in; //sfix13_En13
  output  signed [12:0] filter_out; //sfix13_En13

////////////////////////////////////////////////////////////////
//Module Architecture: template_iir_signle_peak
////////////////////////////////////////////////////////////////
  // Local Functions
  // Type Definitions
  // Constants
  parameter signed [15:0] scaleconst1 = 16'b0100001101001100; //sfix16_En23
  parameter signed [15:0] coeff_b1_section1 = 16'b0100000000000000; //sfix16_En14
  parameter signed [15:0] coeff_b2_section1 = 16'b0000000000000000; //sfix16_En14
  parameter signed [15:0] coeff_b3_section1 = 16'b1100000000000000; //sfix16_En14
  parameter signed [15:0] coeff_a2_section1 = 16'b1000011010000100; //sfix16_En14
  parameter signed [15:0] coeff_a3_section1 = 16'b0011111110111101; //sfix16_En14
  // Signals
  reg  signed [12:0] input_register; // sfix13_En13
  wire signed [32:0] scale1; // sfix33_En39
  wire signed [19:0] factoredcsd_temp; // sfix20_En20
  wire signed [19:0] mulcsd_temp; // sfix20_En20
  wire signed [25:0] factoredcsd_temp_1; // sfix26_En26
  wire signed [26:0] mulcsd_temp_1; // sfix27_En26
  wire signed [27:0] factoredcsd_temp_2; // sfix28_En36
  // Section 1 Signals 
  wire signed [15:0] numtypeconvert1; // sfix16_En16
  wire signed [28:0] a1sum1; // sfix29_En28
  wire signed [16:0] dentypeconvert1; // sfix17_En16
  reg  signed [15:0] numdelay_section1 [0:1] ; // sfix16_En16
  reg  signed [16:0] dendelay_section1 [0:1] ; // sfix17_En16
  wire signed [28:0] a2mul1; // sfix29_En30
  wire signed [28:0] a3mul1; // sfix29_En30
  wire signed [28:0] b3mul1; // sfix29_En30
  wire signed [32:0] mulcsd_temp_2; // sfix33_En30
  wire signed [31:0] mulcsd_temp_3; // sfix32_En30
  wire signed [16:0] unaryminus_temp; // sfix17_En16
  wire signed [28:0] b1sum1; // sfix29_En28
  wire signed [28:0] b2sum1; // sfix29_En28
  wire signed [28:0] b1multypeconvert1; // sfix29_En28
  wire signed [28:0] add_cast; // sfix29_En28
  wire signed [28:0] add_cast_1; // sfix29_En28
  wire signed [29:0] add_temp; // sfix30_En28
  wire signed [28:0] a2sum1; // sfix29_En28
  wire signed [28:0] sub_cast; // sfix29_En28
  wire signed [28:0] sub_cast_1; // sfix29_En28
  wire signed [29:0] sub_temp; // sfix30_En28
  wire signed [28:0] sub_cast_2; // sfix29_En28
  wire signed [28:0] sub_cast_3; // sfix29_En28
  wire signed [29:0] sub_temp_1; // sfix30_En28
  wire signed [12:0] output_typeconvert; // sfix13_En13
  reg  signed [12:0] output_register; // sfix13_En13

  // Block Statements
  always @ (posedge clk or posedge reset)
    begin: input_reg_process
      if (reset == 1'b1) begin
        input_register <= 0;
      end
      else begin
        if (clk_enable == 1'b1) begin
          input_register <= filter_in;
        end
      end
    end // input_reg_process

// For FCSD of 17228, using factorization: 73 59 2 2 
// 
  assign mulcsd_temp = 
        $signed({input_register, 6'b000000}) +
        $signed({input_register, 3'b000}) +
        input_register;
  assign factoredcsd_temp = mulcsd_temp;

  assign mulcsd_temp_1 = 
        $signed({factoredcsd_temp, 6'b000000}) -
        $signed({factoredcsd_temp, 3'b000}) +
        $signed({factoredcsd_temp, 2'b00}) -
        factoredcsd_temp;
  assign factoredcsd_temp_1 = mulcsd_temp_1[25:0];

  assign factoredcsd_temp_2 = $signed({factoredcsd_temp_1[25:0], 2'b00});

  assign scale1 = $signed({factoredcsd_temp_2[27:0], 3'b000});

  // ------------------ Section 1 ------------------

  assign numtypeconvert1 = ({{6{scale1[32]}}, scale1[32:0]} + {~scale1[32], {22{scale1[32]}}})>>>23;

  assign dentypeconvert1 = (a1sum1[28:0] + {~a1sum1[28], {11{a1sum1[28]}}})>>>12;

  always @ (posedge clk or posedge reset)
    begin: numdelay_process_section1
      if (reset == 1'b1) begin
        numdelay_section1[0] <= 16'b0000000000000000;
        numdelay_section1[1] <= 16'b0000000000000000;
      end
      else begin
        if (clk_enable == 1'b1) begin
          numdelay_section1[1] <= numdelay_section1[0];
          numdelay_section1[0] <= numtypeconvert1;
        end
      end
    end // numdelay_process_section1

  always @ (posedge clk or posedge reset)
    begin: dendelay_process_section1
      if (reset == 1'b1) begin
        dendelay_section1[0] <= 17'b00000000000000000;
        dendelay_section1[1] <= 17'b00000000000000000;
      end
      else begin
        if (clk_enable == 1'b1) begin
          dendelay_section1[1] <= dendelay_section1[0];
          dendelay_section1[0] <= dentypeconvert1;
        end
      end
    end // dendelay_process_section1

// For FCSD of -31100, optimizing to CSD due to lower cost
  assign mulcsd_temp_2 = - (
        $signed({dendelay_section1[0], 15'b000000000000000}) -
        $signed({dendelay_section1[0], 11'b00000000000}) +
        $signed({dendelay_section1[0], 8'b00000000}) +
        $signed({dendelay_section1[0], 7'b0000000}) -
        $signed({dendelay_section1[0], 2'b00}));
  assign a2mul1 = mulcsd_temp_2[28:0];

// For FCSD of 16317, optimizing to CSD due to lower cost
  assign mulcsd_temp_3 = 
        $signed({dendelay_section1[1], 14'b00000000000000}) -
        $signed({dendelay_section1[1], 7'b0000000}) +
        $signed({dendelay_section1[1], 6'b000000}) -
        $signed({dendelay_section1[1], 2'b00}) +
        dendelay_section1[1];
  assign a3mul1 = mulcsd_temp_3[28:0];

  assign unaryminus_temp = (numdelay_section1[1]==16'b1000000000000000) ? $signed({1'b0, numdelay_section1[1]}) : -numdelay_section1[1];
  assign b3mul1 = $signed({unaryminus_temp[14:0], 14'b00000000000000});

  assign b1multypeconvert1 = $signed({numtypeconvert1[15:0], 12'b000000000000});

  assign b1sum1 = b1multypeconvert1;

  assign add_cast = b1sum1;
  assign add_cast_1 = ({{2{b3mul1[28]}}, b3mul1[28:0]} + {~b3mul1[28], {1{b3mul1[28]}}})>>>2;
  assign add_temp = add_cast + add_cast_1;
  assign b2sum1 = add_temp[28:0];

  assign sub_cast = b2sum1;
  assign sub_cast_1 = ({{2{a2mul1[28]}}, a2mul1[28:0]} + {~a2mul1[28], {1{a2mul1[28]}}})>>>2;
  assign sub_temp = sub_cast - sub_cast_1;
  assign a2sum1 = sub_temp[28:0];

  assign sub_cast_2 = a2sum1;
  assign sub_cast_3 = ({{2{a3mul1[28]}}, a3mul1[28:0]} + {~a3mul1[28], {1{a3mul1[28]}}})>>>2;
  assign sub_temp_1 = sub_cast_2 - sub_cast_3;
  assign a1sum1 = sub_temp_1[28:0];

  assign output_typeconvert = (dentypeconvert1[15:0] + {~dentypeconvert1[16], {2{dentypeconvert1[16]}}})>>>3;

  always @ (posedge clk or posedge reset)
    begin: Output_Register_process
      if (reset == 1'b1) begin
        output_register <= 0;
      end
      else begin
        if (clk_enable == 1'b1) begin
          output_register <= output_typeconvert;
        end
      end
    end // Output_Register_process

  // Assignment Statements
  assign filter_out = output_register;
endmodule  // template_iir_signle_peak

写在最后:本文只是记录作者使用FDATOOL工具所总结出来的经验汇总,并没有经过严格的论证和证明,因此必然存在诸多错误和疏漏,还请见谅。