微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > IIR滤波器设计和fpga实现

IIR滤波器设计和fpga实现

时间:10-02 整理:3721RD 点击:
IIR滤波器的Z域模型:

在时域内

发送信号:x由3个信号x1,x2,x3叠加而成,3个信号频率分别f1=50Hz,f2=100Hz,f3=150Hz
要求:滤除f2,f3信号
滤波器: IIR低通滤波器,滤除x2,x3信号,滤波器选择
滤波器参数:通带80Hz,阻带120Hz,通带增益1dB,阻带增益-80dB
滤波器设计工具:matlab fdatool工具箱
产生原测试数据
clear all;
clc;
fs=1000;
f1=50;
f2=150;
f3=200;
t0=1;
t=0:1/fs:(t0*fs-1)/fs;
x1=sin(2*pi*f1*t);
x2=sin(2*pi*f2*t);
x3=sin(2*pi*f3*t);
x=x1+x2+x3;
原测试数据时域波形
原测试信号频域波形
利用matlab的fdatool设计滤波器
导出IIR系数
G =
    0.4927
    0.4141
    0.3144
    0.2052
    0.1140
    0.2783
1.0000
SOS =
1.0000   -1.4483    1.0000    1.0000   -1.6279    0.8997
1.0000   -1.3629    1.0000    1.0000   -1.4519    0.7157
1.0000   -1.1386    1.0000    1.0000   -1.2691    0.5399
1.0000   -0.6036    1.0000    1.0000   -1.0880    0.3746
1.0000    0.6554    1.0000    1.0000   -0.9437    0.2465
1.0000    1.0000         0       1.0000   -0.4435         0
SOS每一行代表一级,分别是[bi,ai],前三个是bi,后三个是ai.
由此设计一个级联型iir滤波器

设计一个6级流水线去实现。
浮点仿真:
主函数实现代码:
clear all;
clc;
fs=1000;
f1=50;
f2=150;
f3=200;
t0=1;
t=0:1/fs:(t0*fs-1)/fs;
x1=sin(2*pi*f1*t);
x2=sin(2*pi*f2*t);
x3=sin(2*pi*f3*t);
x=x1+x2+x3;
y1=iir_first_step(x);
y2=iir_second_step(y1);
y3=iir_third_step(y2);
y4=iir_fourth_step(y3);
y5=iir_fifth_step(y4);
y=iir_sixth_step(y5);
subplot(3,1,1);
plot(x);
subplot(3,1,2);
plot(x1);
subplot(3,1,3);
plot(y);
第一级流水线实现代码:
function y=iir_first_step(x)
x_len=length(x);
y(1)=0;
y(2)=0;
for i=3:x_len
        x_temp=x(i)-1.4483*x(i-1)+x(i-2);
        y_temp=-1.6279*y(i-1)+0.8997*y(i-2);
        y(n)=x_temp-y_temp;
        y(n)=y(n)/0.4927;
end
第二级:
function y=iir_second_step(x)
x_len=length(x);
y(1)=0;
y(2)=0;
for i=3:x_len
        x_temp=x(i)-1.3629*x(i-1)+x(i-2);
        y_temp=-1.4519*y(i-1)+0.7157*y(i-2);
        y(i)=x_temp-y_temp;
        y(i)=y(i)*0.4141;
end
第三级:
function y=iir_third_step(x)
x_len=length(x);
y(1)=0;
y(2)=0;
for i=3:x_len
        x_temp=x(i)-1.1386*x(i-1)+x(i-2);
        y_temp=-1.1291*y(i-1)+0.5399*y(i-2);
        y(i)=x_temp-y_temp;
        y(i)=y(i)*0.3144;
end
第四级:
function y=iir_fourth_step(x)
x_len=length(x);
y(1)=0;
y(2)=0;
for i=3:x_len
        x_temp=x(i)-0.6036*x(i-1)+x(i-2);
        y_temp=-1.088*y(i-1)+0.3746*y(i-2);
        y(i)=x_temp-y_temp;
        y(i)=y(i)*0.2052;
end
第五级:
function y=iir_fifth_step(x)
x_len=length(x);
y(1)=0;
y(2)=0;
for i=3:x_len
        x_temp=x(i)-0.6554*x(i-1)+x(i-2);
        y_temp=-0.9437*y(i-1)+0.2465*y(i-2);
        y(i)=x_temp-y_temp;
        y(i)=y(i)*0.114;
end
第六级:
function y=iir_sixth_step(x)
x_len=length(x);
y(1)=0;
y(2)=0;
for i=3:x_len
        x_temp=x(i)+x(i-1);
        y_temp=-0.4435*y(i-1);
        y(i)=x_temp-y_temp;
        y(i)=y(i)*0.2783;
end
滤波后从上往下依次是待滤波信号,希望得到信号,滤波后信号
时域波形
频域波形
上述只是理论上的iir算法,要改成实际在verilog上实现,还要改matlab代码的结构
改为:
clear all;
clc;
fs=1000;
f1=50;
f2=150;
f3=200;
t0=1;
t=0:1/fs:(t0*fs-1)/fs;
x1=sin(2*pi*f1*t);
x2=sin(2*pi*f2*t);
x3=sin(2*pi*f3*t);
x=x1+x2+x3;
b_x=[ 0.4927   -0.7136    0.4927];
a_x=[ 0   -0.8021    0.4433];
b_y1=[0.4141   -0.5644    0.4141];
a_y1=[0   -0.6012    0.2964];
b_y2=[0.3144   -0.3580    0.3144];
a_y2=[0   -0.3550    0.1697];
b_y3=[0.2052   -0.1239    0.2052];
a_y3=[0   -0.2233    0.0769];
b_y4=[0.1140   -0.0747    0.1140];
a_y4=[0   -0.1076    0.0281];
b_y5=[0.2783    0.2783         0];
a_y5=[0   -0.1234         0];
for i=1:x_len
        %first step
        if i>2
                x_reg0=x(i-1);
                x_reg1=x(i-2);
                y_reg0=y1(i-1);
                y_reg1=y1(i-2);
        elseif i>1
                x_reg0=x(i-1);
                x_reg1=0;
       
                y_reg0=y1(i-1);
                y_reg1=0;
        else
                x_reg0=0;
                x_reg1=0;
                y_reg0=0;
                y_reg1=0;
        end
        x_mul1=b_x(1)*x(i);
        x_mul2=b_x(2)*x_reg0;
        x_mul3=b_x(3)*x_reg1;
        x_temp=x_mul1+x_mul2+x_mul3;
        y_mul1=a_x(2)*y_reg0;
        y_mul2=a_x(3)*y_reg1;       
        y_temp=y_mul1+y_mul2;
        y1(i)=x_temp-y_temp;
        %second step
        if i>2
                x_reg0=y1(i-1);
                x_reg1=y1(i-2);
                y_reg0=y2(i-1);
                y_reg1=y2(i-2);
        elseif i>1
                x_reg0=y1(i-1);
                x_reg1=0;
       
                y_reg0=y2(i-1);
                y_reg1=0;
        else
                x_reg0=0;
                x_reg1=0;
                y_reg0=0;
                y_reg1=0;
        end
        x_mul1=b_y1(1)*y1(i);
        x_mul2=b_y1(2)*x_reg0;
        x_mul3=b_y1(3)*x_reg1;
        x_temp=x_mul1+x_mul2+x_mul3;
        y_mul1=a_y1(2)*y_reg0;
        y_mul2=a_y1(3)*y_reg1;       
        y_temp=y_mul1+y_mul2;
        y2(i)=x_temp-y_temp;
        %third step
        if i>2
                x_reg0=y2(i-1);
                x_reg1=y2(i-2);
                y_reg0=y3(i-1);
                y_reg1=y3(i-2);
        elseif i>1
                x_reg0=y2(i-1);
                x_reg1=0;
       
                y_reg0=y3(i-1);
                y_reg1=0;
        else
                x_reg0=0;
                x_reg1=0;
                y_reg0=0;
                y_reg1=0;
        end
        x_mul1=b_y2(1)*y2(i);
        x_mul2=b_y2(2)*x_reg0;
        x_mul3=b_y2(3)*x_reg1;
        x_temp=x_mul1+x_mul2+x_mul3;
        y_mul1=a_y2(2)*y_reg0;
        y_mul2=a_y2(3)*y_reg1;       
        y_temp=y_mul1+y_mul2;
        y3(i)=x_temp-y_temp;       
        %fourth step       
        if i>2
                x_reg0=y3(i-1);
                x_reg1=y3(i-2);
                y_reg0=y4(i-1);
                y_reg1=y4(i-2);
        elseif i>1
                x_reg0=y3(i-1);
                x_reg1=0;
       
                y_reg0=y4(i-1);
                y_reg1=0;
        else
                x_reg0=0;
                x_reg1=0;
                y_reg0=0;
                y_reg1=0;
        end
        x_mul1=b_y3(1)*y3(i);
        x_mul2=b_y3(2)*x_reg0;
        x_mul3=b_y3(3)*x_reg1;
        x_temp=x_mul1+x_mul2+x_mul3;
        y_mul1=a_y3(2)*y_reg0;
        y_mul2=a_y3(3)*y_reg1;       
        y_temp=y_mul1+y_mul2;
        y4(i)=x_temp-y_temp;
        %fifth step
        if i>2
                x_reg0=y4(i-1);
                x_reg1=y4(i-2);
                y_reg0=y5(i-1);
                y_reg1=y5(i-2);
        elseif i>1
                x_reg0=y4(i-1);
                x_reg1=0;
       
                y_reg0=y5(i-1);
                y_reg1=0;
        else
                x_reg0=0;
                x_reg1=0;
                y_reg0=0;
                y_reg1=0;
        end
        x_mul1=b_y4(1)*y4(i);
        x_mul2=b_y4(2)*x_reg0;
        x_mul3=b_y4(3)*x_reg1;
        x_temp=x_mul1+x_mul2+x_mul3;
        y_mul1=a_y4(2)*y_reg0;
        y_mul2=a_y4(3)*y_reg1;       
        y_temp=y_mul1+y_mul2;
        y5(i)=x_temp-y_temp;
        %sixth step
        if i>2
                x_reg0=y5(i-1);
                x_reg1=y5(i-2);
                y_reg0=y(i-1);
                y_reg1=y(i-2);
        elseif i>1
                x_reg0=y5(i-1);
                x_reg1=0;
       
                y_reg0=y(i-1);
                y_reg1=0;
        else
                x_reg0=0;
                x_reg1=0;
                y_reg0=0;
                y_reg1=0;
        end
        x_mul1=b_y5(1)*y5(i);
        x_mul2=b_y5(2)*x_reg0;
        x_mul3=b_y5(3)*x_reg1;
        x_temp=x_mul1+x_mul2+x_mul3;
        y_mul1=a_y5(2)*y_reg0;
        y_mul2=a_y5(3)*y_reg1;       
        y_temp=y_mul1+y_mul2;
        y(i)=x_temp-y_temp;
end
y_fft=abs(fft(y));
subplot(2,1,1);
plot(y);
subplot(2,1,2);
plot(y_fft(1:end/2));
仿真结果:
在硬件上实现,通常需要做定点仿真。
clear all;
clc;
fs=1000;
f1=50;
f2=150;
f3=200;
t0=1;
t=0:1/fs:(t0*fs-1)/fs;
x1=sin(2*pi*f1*t);
x2=sin(2*pi*f2*t);
x3=sin(2*pi*f3*t);
x=x1+x2+x3;
BitWidth=16;
quanti_coef=2^(BitWidth-1);
IntWidth=[1,1,1,1,1,1];
for i=1:length(IntWidth)
    FractionWidth(i)=16-IntWidth(i);
end
x1=x/max(abs(x));
x_len=length(x);
for i=1:x_len
        x_int(i)=round(x1(i)*quanti_coef);
        if x_int(i)==32768
                x_int(i)=32767;
        end
end
b_x=[16145      -23383       16145];
a_x=[ 0      -26283       14526];
b_y1=[13569      -18494       13569];
a_y1=[0      -19700        9712];
b_y2=[10302      -11731       10302];
a_y2=[0      -11633        5561];
b_y3=[6724       -4060        6724];
a_y3=[0       -7317        2520];
b_y4=[3736       -2448        3736];
a_y4=[0       -3526         921];
b_y5=[9119        9119           0];
a_y5=[0       -4044           0];
for i=1:x_len
        %first step
        if i>2
                x_reg0=x_int(i-1);
                x_reg1=x_int(i-2);
                y_reg0=y1(i-1);
                y_reg1=y1(i-2);
        elseif i>1
                x_reg0=x(i-1);
                x_reg1=0;
       
                y_reg0=y1(i-1);
                y_reg1=0;
        else
                x_reg0=0;
                x_reg1=0;
                y_reg0=0;
                y_reg1=0;
           end
        x1_mul1(i)=floor(b_x(1)*x_int(i)/quanti_coef);
        x1_mul2(i)=floor(b_x(2)*x_reg0/quanti_coef);
        x1_mul3(i)=floor(b_x(3)*x_reg1/quanti_coef);
        x1_temp(i)=x1_mul1(i)+x1_mul2(i)+x1_mul3(i);
        y1_mul1(i)=floor(a_x(2)*y_reg0/quanti_coef);
        y1_mul2(i)=floor(a_x(3)*y_reg1/quanti_coef);       
        y1_temp(i)=y1_mul1(i)+y1_mul2(i);
        y1_sum(i)=x1_temp(i)-y1_temp(i);
        y1(i)=y1_sum(i);
        %second step
        if i>2
                x_reg0=y1(i-1);
                x_reg1=y1(i-2);
                y_reg0=y2(i-1);
                y_reg1=y2(i-2);
        elseif i>1
                x_reg0=y1(i-1);
                x_reg1=0;
       
                y_reg0=y2(i-1);
                y_reg1=0;
        else
                x_reg0=0;
                x_reg1=0;
                y_reg0=0;
                y_reg1=0;
            end
        x2_mul1(i)=floor(b_y1(1)*y1(i)/quanti_coef);
        x2_mul2(i)=floor(b_y1(2)*x_reg0/quanti_coef);
        x2_mul3(i)=floor(b_y1(3)*x_reg1/quanti_coef);
        x2_temp(i)=x2_mul1(i)+x2_mul2(i)+x2_mul3(i);
        y2_mul1(i)=floor(a_y1(2)*y_reg0/quanti_coef);
        y2_mul2(i)=floor(a_y1(3)*y_reg1/quanti_coef);
        y2_temp(i)=y2_mul1(i)+y2_mul2(i);
        y2_sum(i)=x2_temp(i)-y2_temp(i);
        y2(i)=y2_sum(i);
        %third step
        if i>2
                x_reg0=y2(i-1);
                x_reg1=y2(i-2);
                y_reg0=y3(i-1);
                y_reg1=y3(i-2);
        elseif i>1
                x_reg0=y2(i-1);
                x_reg1=0;
       
                y_reg0=y3(i-1);
                y_reg1=0;
        else
                x_reg0=0;
                x_reg1=0;
                y_reg0=0;
                y_reg1=0;
        end
        x3_mul1(i)=floor(b_y2(1)*y2(i)/quanti_coef);
        x3_mul2(i)=floor(b_y2(2)*x_reg0/quanti_coef);
        x3_mul3(i)=floor(b_y2(3)*x_reg1/quanti_coef);
        x3_temp(i)=x3_mul1(i)+x3_mul2(i)+x3_mul3(i);
        y3_mul1(i)=floor(a_y2(2)*y_reg0/quanti_coef);
        y3_mul2(i)=floor(a_y2(3)*y_reg1/quanti_coef);       
       
            y3_temp(i)=y3_mul1(i)+y3_mul2(i);
       
            y3_sum(i)=x3_temp(i)-y3_temp(i);
       
            y3(i)=y3_sum(i);
        %fourth step       
        if i>2
                x_reg0=y3(i-1);
                x_reg1=y3(i-2);
                y_reg0=y4(i-1);
                y_reg1=y4(i-2);
        elseif i>1
                x_reg0=y3(i-1);
                x_reg1=0;
       
                y_reg0=y4(i-1);
                y_reg1=0;
        else
                x_reg0=0;
                x_reg1=0;
                y_reg0=0;
                y_reg1=0;
        end
        x4_mul1(i)=floor(b_y3(1)*y3(i)/quanti_coef);
        x4_mul2(i)=floor(b_y3(2)*x_reg0/quanti_coef);
        x4_mul3(i)=floor(b_y3(3)*x_reg1/quanti_coef);
        x4_temp(i)=x4_mul1(i)+x4_mul2(i)+x4_mul3(i);
        y4_mul1(i)=floor(a_y3(2)*y_reg0/quanti_coef);
        y4_mul2(i)=floor(a_y3(3)*y_reg1/quanti_coef);       
        y4_temp(i)=y4_mul1(i)+y4_mul2(i);
        y4_sum(i)=x4_temp(i)-y4_temp(i);
        y4(i)=y4_sum(i);
        %fifth step
        if i>2
                x_reg0=y4(i-1);
                x_reg1=y4(i-2);
                y_reg0=y5(i-1);
                y_reg1=y5(i-2);
        elseif i>1
                x_reg0=y4(i-1);
                x_reg1=0;
       
                y_reg0=y5(i-1);
                y_reg1=0;
        else
                x_reg0=0;
                x_reg1=0;
                y_reg0=0;
                y_reg1=0;
        end
        x5_mul1(i)=floor(b_y4(1)*y4(i)/quanti_coef);
        x5_mul2(i)=floor(b_y4(2)*x_reg0/quanti_coef);
        x5_mul3(i)=floor(b_y4(3)*x_reg1/quanti_coef);
        x5_temp(i)=x5_mul1(i)+x5_mul2(i)+x5_mul3(i);
        y5_mul1(i)=floor(a_y4(2)*y_reg0/quanti_coef);
        y5_mul2(i)=floor(a_y4(3)*y_reg1/quanti_coef);
        y5_temp(i)=y5_mul1(i)+y5_mul2(i);
        y5_sum(i)=x5_temp(i)-y5_temp(i);
        y5(i)=y5_sum(i);
        %sixth step
        if i>2
                x_reg0=y5(i-1);
                x_reg1=y5(i-2);
                y_reg0=y(i-1);
                y_reg1=y(i-2);
        elseif i>1
                x_reg0=y5(i-1);
                x_reg1=0;
       
                y_reg0=y(i-1);
                y_reg1=0;
        else
                x_reg0=0;
                x_reg1=0;
                y_reg0=0;
                y_reg1=0;
        end
        x6_mul1(i)=floor(b_y5(1)*y5(i)/quanti_coef);
        x6_mul2(i)=floor(b_y5(2)*x_reg0/quanti_coef);
        x6_mul3(i)=floor(b_y5(3)*x_reg1/quanti_coef);
        x6_temp(i)=x6_mul1(i)+x6_mul2(i)+x6_mul3(i);
            y6_mul1(i)=floor(a_y5(2)*y_reg0/quanti_coef);
        y6_mul2(i)=floor(a_y5(3)*y_reg1/quanti_coef);       
       
            y6_temp(i)=y6_mul1(i)+y6_mul2(i);
       
            y6_sum(i)=x6_temp(i)-y6_temp(i);
       
            y(i)=y6_sum(i);
end
y_fft=abs(fft(y));
subplot(2,1,1);
plot(y);
subplot(2,1,2);
plot(y_fft(1:end/2));
这里对加减法的处理比较简单,只是做了溢出保护,默认没有进位。
testbeach:
`timescale 1ns/1ns
module myiir_tb;
reg rst;
reg clk;
reg signed[15:0] din;
wire signed[15:0] dout;
reg din_valid;
wire dout_valid;
wire dout_prevalid;
reg[15:0] cnt1,cnt2;
integer fp1,fp2;
myiir U(
.rst(rst),
.clk(clk),
.din(din),
.dout(dout),
.din_valid(din_valid),
.dout_valid(dout_valid),
.dout_prevalid(dout_prevalid)
);
initial begin
        rst=1;
        #40
        rst=0;
        #2
        rst=1;
end
initial begin
        clk=0;
        fp1=$fopen("data\\data.txt","r");
end
always #5 clk=~clk;
always @(negedge rst,posedge clk) begin
        if(!rst) begin
                din<=16'h0;
                cnt1<=16'd1;
                din_valid<=1'b1;
        end
        else begin
                if(dout_prevalid) begin
                        cnt1<=cnt1+16'd1;       
                        din_valid<=1'b1;
                end
                else begin
                        din_valid<=1'b0;
                        cnt1<=cnt1;
                end
        end
end
always @(*) begin
        if(din_valid) begin
                $fscanf(fp1,"%d",din);
        end
end
always @(*) begin
        if(cnt1==16'd1000) begin
                din_valid<=1'b0;
                $fclose(fp1);
        end
end
initial begin
        cnt2<=16'd0;
        fp2=$fopen("data\\data_out.txt","w");
end
always @(posedge clk) begin
        if(dout_valid) begin
                cnt2<=cnt2+16'd1;
                $fwrite(fp2,"%d\n",dout);
        end
        else begin
                cnt2<=cnt2;
        end
end
always @(*) begin
        if(cnt2==16'd300) begin
                $fclose(fp2);
                $stop;
        end
end
endmodule
myiir.v
module myiir(
rst,
clk,
din,
dout,
din_valid,
dout_valid,
dout_prevalid
);
input rst;
input clk;
input signed[15:0] din;
input din_valid;
output reg signed[15:0] dout;
output reg dout_valid;
output dout_prevalid;
wire signed[15:0] dout1;
wire signed[15:0] dout2;
wire signed[15:0] dout3;
wire signed[15:0] dout4;
wire signed[15:0] dout5;
wire signed[15:0] dout_reg;
wire din_valid1;
wire dout_valid1;
wire din_valid2;
wire dout_valid2;
wire din_valid3;
wire dout_valid3;
wire din_valid4;
wire dout_valid4;
wire din_valid5;
wire dout_valid5;
wire din_valid6;
wire dout_valid6;
assign din_valid1=din_valid;
assign din_valid2=dout_valid1;
assign din_valid3=dout_valid2;
assign din_valid4=dout_valid3;
assign din_valid5=dout_valid4;
assign din_valid6=dout_valid5;
assign dout_prevalid=dout_valid1;
myiir_first_step U1(
.rst(rst),
.clk(clk),
.din(din),
.dout(dout1),
.din_valid(din_valid1),
.dout_valid(dout_valid1)
);
myiir_second_step U2(
.rst(rst),
.clk(clk),
.din(dout1),
.dout(dout2),
.din_valid(din_valid2),
.dout_valid(dout_valid2)
);
myiir_third_step U3(
.rst(rst),
.clk(clk),
.din(dout2),
.dout(dout3),
.din_valid(din_valid3),
.dout_valid(dout_valid3)
);
myiir_fourth_step U4(
.rst(rst),
.clk(clk),
.din(dout3),
.dout(dout4),
.din_valid(din_valid4),
.dout_valid(dout_valid4)
);
myiir_fifth_step U5(
.rst(rst),
.clk(clk),
.din(dout4),
.dout(dout5),
.din_valid(din_valid5),
.dout_valid(dout_valid5)
);
myiir_sixth_step U6(
.rst(rst),
.clk(clk),
.din(dout5),
.dout(dout_reg),
.din_valid(din_valid6),
.dout_valid(dout_valid6)
);
always @(negedge rst,posedge clk) begin
        if(!rst) begin
                dout<=16'd0;
                dout_valid=1'b0;
        end
        else if(dout_valid6) begin
                dout_valid=1'b1;
                dout<=dout_reg;       
        end
        else begin
                dout<=dout;
                dout_valid=1'b0;
        end
end
endmodule
myiir_first_step.v
module myiir_first_step(
rst,
clk,
din,
dout,
din_valid,
dout_valid
);
parameter b0=16145;
parameter b1=-23383;
parameter b2=16145;
parameter a1=-26283;
parameter a2=14526;
input rst;
input clk;
input signed[15:0] din;
input din_valid;
output signed[15:0] dout;
output dout_valid;
reg[4:0] cState,nState;
reg signed[15:0] x_reg0;
reg signed[15:0] x_reg1;
reg signed[31:0] x_mul1;
reg signed[31:0] x_mul2;
reg signed[31:0] x_mul3;
wire signed[15:0] x_int_mul1;
wire signed[15:0] x_int_mul2;
wire signed[15:0] x_int_mul3;
reg signed[17:0] x_sum;
wire signed[15:0] x_temp;
reg signed[15:0] y_reg0;
reg signed[15:0] y_reg1;
reg signed[31:0] y_mul1;
reg signed[31:0] y_mul2;
wire signed[15:0] y_int_mul1;
wire signed[15:0] y_int_mul2;
reg signed[16:0] y_sum;
wire signed[15:0] y_temp;
reg signed[16:0] dout_sum;
wire signed[15:0] dout_temp;
always @(negedge rst,posedge clk) begin
        if(!rst) begin
                cState<=0;
        end
        else begin
                cState<=nState;               
        end
end
always @(*) begin
        case(cState)
                0:if(din_valid) begin
                        nState<=1;
                  end
                  else begin
                        nState<=0;
                  end
                1:nState<=2;
                2:nState<=3;
                3:nState<=4;
                4:nState<=5;
                5:nState<=6;
                6:nState<=0;
                default:nState<=nState;
        endcase
end
always @(*) begin
        if(rst) begin
                case(cState)
                        1:x_mul1=b0*din;
                        2:begin
                                x_mul2=b1*x_reg0;
                                y_mul1=a1*y_reg0;
                        end
                        3:begin
                                x_mul3=b2*x_reg1;
                                y_mul2=a2*y_reg1;
                        end
                        4:begin
                                x_sum=x_int_mul1+x_int_mul2+x_int_mul3;
                                y_sum=y_int_mul1+y_int_mul2;
                        end
                        5:dout_sum=x_temp-y_temp;
                        default:;
                endcase
        end
end
always @(cState) begin
        if(rst) begin
                if(cState==4) begin
                        x_reg0<=din;
                        x_reg1<=x_reg0;
                end
                else begin
                        x_reg0<=x_reg0;
                        x_reg1<=x_reg1;
                end
        end
        else begin
                x_reg0<=16'd0;
                x_reg1<=16'd0;
        end
end
always @(cState) begin
        if(rst) begin
                if(cState==6) begin
                        y_reg0<=dout;
                        y_reg1<=y_reg0;
                end
                else begin
                        y_reg0<=y_reg0;
                        y_reg1<=y_reg1;
                end
        end
        else begin
                y_reg0<=16'd0;
                y_reg1<=16'd0;
        end
end
assign x_int_mul1=(x_mul1[31]^x_mul1[30])?x_mul1[31:16]:x_mul1[30:15];
assign x_int_mul2=(x_mul2[31]^x_mul2[30])?x_mul2[31:16]:x_mul2[30:15];
assign x_int_mul3=(x_mul3[31]^x_mul3[30])?x_mul3[31:16]:x_mul3[30:15];
assign x_temp=(x_sum[17:15]==3'b000||x_sum[17:15]==3'b111)?x_sum[15:0]:(x_sum[17])?16'h8000:16'h7fff;
assign y_int_mul1=(y_mul1[31]^y_mul1[30])?y_mul1[31:16]:y_mul1[30:15];
assign y_int_mul2=(y_mul2[31]^y_mul2[30])?y_mul2[31:16]:y_mul2[30:15];
assign y_temp=(y_sum[16:15]==2'b00||y_sum[16:15]==2'b11)?y_sum[15:0]:(y_sum[16])?16'h8000:16'h7fff;
assign dout_temp=(dout_sum[16:15]==2'b00||dout_sum[16:15]==2'b11)?dout_sum[15:0]:(dout_sum[16])?16'h8000:16'h7fff;
assign dout=(!rst)?16'd0:dout_temp;
assign dout_valid=(cState==6 && nState==0)?1'b1:1'b0;
endmodule
myiir_second_step.v
module myiir_second_step(
rst,
clk,
din,
dout,
din_valid,
dout_valid
);
parameter b0=13569;
parameter b1=-18494;
parameter b2=13569;
parameter a1=-19700;
parameter a2=9712;
input rst;
input clk;
input signed[15:0] din;
input din_valid;
output signed[15:0] dout;
output dout_valid;
reg[4:0] cState,nState;
reg signed[15:0] x_reg0;
reg signed[15:0] x_reg1;
reg signed[31:0] x_mul1;
reg signed[31:0] x_mul2;
reg signed[31:0] x_mul3;
wire signed[15:0] x_int_mul1;
wire signed[15:0] x_int_mul2;
wire signed[15:0] x_int_mul3;
reg signed[17:0] x_sum;
wire signed[15:0] x_temp;
reg signed[15:0] y_reg0;
reg signed[15:0] y_reg1;
reg signed[31:0] y_mul1;
reg signed[31:0] y_mul2;
wire signed[15:0] y_int_mul1;
wire signed[15:0] y_int_mul2;
reg signed[16:0] y_sum;
wire signed[15:0] y_temp;
reg signed[16:0] dout_sum;
wire signed[15:0] dout_temp;
always @(negedge rst,posedge clk) begin
        if(!rst) begin
                cState<=0;
        end
        else begin
                cState<=nState;
        end
end
always @(*) begin
        case(cState)
                0:if(din_valid) begin
                        nState<=1;
                  end
                  else begin
                        nState<=0;
                  end
                1:nState<=2;
                2:nState<=3;
                3:nState<=4;
                4:nState<=5;
                5:nState<=6;
                6:nState<=0;
                default:nState<=nState;
        endcase
end
always @(*) begin
        if(rst) begin
                case(cState)
                        1:x_mul1=b0*din;
                        2:begin
                                x_mul2=b1*x_reg0;
                                y_mul1=a1*y_reg0;
                        end
                        3:begin
                                x_mul3=b2*x_reg1;
                                y_mul2=a2*y_reg1;
                        end
                        4:begin
                                x_sum=x_int_mul1+x_int_mul2+x_int_mul3;
                                y_sum=y_int_mul1+y_int_mul2;
                        end
                        5: dout_sum=x_temp-y_temp;
                        default:;
                endcase
        end
end
assign x_int_mul1=(x_mul1[31]^x_mul1[30])?x_mul1[31:16]:x_mul1[30:15];
assign x_int_mul2=(x_mul2[31]^x_mul2[30])?x_mul2[31:16]:x_mul2[30:15];
assign x_int_mul3=(x_mul3[31]^x_mul3[30])?x_mul3[31:16]:x_mul3[30:15];
assign x_temp=(x_sum[17:15]==3'b000||x_sum[17:15]==3'b111)?x_sum[15:0]:(x_sum[17])?16'h8000:16'h7fff;
assign y_int_mul1=(y_mul1[31]^y_mul1[30])?y_mul1[31:16]:y_mul1[30:15];
assign y_int_mul2=(y_mul2[31]^y_mul2[30])?y_mul2[31:16]:y_mul2[30:15];
assign y_temp=(y_sum[16:15]==2'b00||y_sum[16:15]==2'b11)?y_sum[15:0]:(y_sum[16])?16'h8000:16'h7fff;
assign dout_temp=(dout_sum[16:15]==2'b00||dout_sum[16:15]==2'b11)?dout_sum[15:0]:(dout_sum[16])?16'h8000:16'h7fff;
assign dout=(!rst)?16'd0:dout_temp;
always @(cState) begin
        if(rst) begin
                if(cState==4) begin
                        x_reg0<=din;
                        x_reg1<=x_reg0;
                end
                else begin
                        x_reg0<=x_reg0;
                        x_reg1<=x_reg1;
                end
        end
        else begin
                x_reg0<=16'd0;
                x_reg1<=16'd0;
        end
end
always @(cState) begin
        if(rst) begin
                if(cState==6) begin
                        y_reg0<=dout;
                        y_reg1<=y_reg0;
                end
                else begin
                        y_reg0<=y_reg0;
                        y_reg1<=y_reg1;
                end
        end
        else begin
                y_reg0<=16'd0;
                y_reg1<=16'd0;
        end
end
assign dout_valid=(cState==6 && nState==0)?1'b1:1'b0;
endmodule
myiir_third_step.v
module myiir_third_step(
rst,
clk,
din,
dout,
din_valid,
dout_valid
);
parameter b0=10302;
parameter b1=-11731;
parameter b2=10302;
parameter a1=-11633;
parameter a2=5561;
input rst;
input clk;
input signed[15:0] din;
input din_valid;
output signed[15:0] dout;
output dout_valid;
reg[4:0] cState,nState;
reg signed[15:0] x_reg0;
reg signed[15:0] x_reg1;
reg signed[31:0] x_mul1;
reg signed[31:0] x_mul2;
reg signed[31:0] x_mul3;
wire signed[15:0] x_int_mul1;
wire signed[15:0] x_int_mul2;
wire signed[15:0] x_int_mul3;
reg signed[17:0] x_sum;
wire signed[15:0] x_temp;
reg signed[15:0] y_reg0;
reg signed[15:0] y_reg1;
reg signed[31:0] y_mul1;
reg signed[31:0] y_mul2;
wire signed[15:0] y_int_mul1;
wire signed[15:0] y_int_mul2;
reg signed[16:0] y_sum;
wire signed[15:0] y_temp;
reg signed[16:0] dout_sum;
wire signed[15:0] dout_temp;
always @(negedge rst,posedge clk) begin
        if(!rst) begin
                cState<=0;
        end
        else begin
                cState<=nState;
        end
end
always @(*) begin
        case(cState)
                0:if(din_valid) begin
                        nState<=1;
                  end
                  else begin
                        nState<=0;
                  end
                1:nState<=2;
                2:nState<=3;
                3:nState<=4;
                4:nState<=5;
                5:nState<=6;
                6:nState<=0;
                default:nState<=nState;
        endcase
end
always @(*) begin
        if(rst) begin
                case(cState)
                        1:x_mul1=b0*din;
                        2:begin
                                x_mul2=b1*x_reg0;
                                y_mul1=a1*y_reg0;
                        end
                        3:begin
                                x_mul3=b2*x_reg1;
                                y_mul2=a2*y_reg1;
                        end
                        4:begin
                                x_sum=x_int_mul1+x_int_mul2+x_int_mul3;
                                y_sum=y_int_mul1+y_int_mul2;
                        end
                        5: dout_sum=x_temp-y_temp;
                        default:;
                endcase
        end
end
assign x_int_mul1=(x_mul1[31]^x_mul1[30])?x_mul1[31:16]:x_mul1[30:15];
assign x_int_mul2=(x_mul2[31]^x_mul2[30])?x_mul2[31:16]:x_mul2[30:15];
assign x_int_mul3=(x_mul3[31]^x_mul3[30])?x_mul3[31:16]:x_mul3[30:15];
assign x_temp=(x_sum[17:15]==3'b000||x_sum[17:15]==3'b111)?x_sum[15:0]:(x_sum[17])?16'h8000:16'h7fff;
assign y_int_mul1=(y_mul1[31]^y_mul1[30])?y_mul1[31:16]:y_mul1[30:15];
assign y_int_mul2=(y_mul2[31]^y_mul2[30])?y_mul2[31:16]:y_mul2[30:15];
assign y_temp=(y_sum[16:15]==2'b00||y_sum[16:15]==2'b11)?y_sum[15:0]:(y_sum[16])?16'h8000:16'h7fff;
assign dout_temp=(dout_sum[16:15]==2'b00||dout_sum[16:15]==2'b11)?dout_sum[15:0]:(dout_sum[16])?16'h8000:16'h7fff;
assign dout=(!rst)?16'd0:dout_temp;
always @(cState) begin
        if(rst) begin
                if(cState==4) begin
                                x_reg0<=din;
                                x_reg1<=x_reg0;
                end
                else begin
                                x_reg0<=x_reg0;
                                x_reg1<=x_reg1;               
                end
        end
        else begin
                x_reg0<=16'd0;
                x_reg1<=16'd0;
        end
end
always @(cState) begin
        if(rst) begin
                if(cState==6) begin
                        y_reg0<=dout;
                        y_reg1<=y_reg0;
                end
                else begin
                        y_reg0<=y_reg0;
                        y_reg1<=y_reg1;
                end
        end
        else begin
                y_reg0<=16'd0;
                y_reg1<=16'd0;
        end
end
assign dout_valid=(cState==6 && nState==0)?1'b1:1'b0;
endmodule
myiir_fourth_step.v
module myiir_fourth_step(
rst,
clk,
din,
dout,
din_valid,
dout_valid
);
parameter b0=6724;
parameter b1=-4060;
parameter b2=6724;
parameter a1=-7317;
parameter a2=2520;
input rst;
input clk;
input signed[15:0] din;
input din_valid;
output signed[15:0] dout;
output dout_valid;
reg[4:0] cState,nState;
reg signed[15:0] x_reg0;
reg signed[15:0] x_reg1;
reg signed[31:0] x_mul1;
reg signed[31:0] x_mul2;
reg signed[31:0] x_mul3;
wire signed[15:0] x_int_mul1;
wire signed[15:0] x_int_mul2;
wire signed[15:0] x_int_mul3;
reg signed[17:0] x_sum;
wire signed[15:0] x_temp;
reg signed[15:0] y_reg0;
reg signed[15:0] y_reg1;
reg signed[31:0] y_mul1;
reg signed[31:0] y_mul2;
wire signed[15:0] y_int_mul1;
wire signed[15:0] y_int_mul2;
reg signed[16:0] y_sum;
wire signed[15:0] y_temp;
reg signed[16:0] dout_sum;
wire signed[15:0] dout_temp;
always @(negedge rst,posedge clk) begin
        if(!rst) begin
                cState<=0;
        end
        else begin
                cState<=nState;
        end
end
always @(*) begin
        case(cState)
                0:if(din_valid) begin
                        nState<=1;
                  end
                  else begin
                        nState<=0;
                  end
                1:nState<=2;
                2:nState<=3;
                3:nState<=4;
                4:nState<=5;
                5:nState<=6;
                6:nState<=0;
                default:nState<=nState;
        endcase
end
always @(*) begin
        if(rst) begin
                case(cState)
                        1:x_mul1=b0*din;
                        2:begin
                                x_mul2=b1*x_reg0;
                                y_mul1=a1*y_reg0;
                        end
                        3:begin
                                x_mul3=b2*x_reg1;
                                y_mul2=a2*y_reg1;
                        end
                        4:begin
                                x_sum=x_int_mul1+x_int_mul2+x_int_mul3;
                                y_sum=y_int_mul1+y_int_mul2;
                        end
                        5: dout_sum=x_temp-y_temp;
                        default:;
                endcase
        end
end
assign x_int_mul1=(x_mul1[31]^x_mul1[30])?x_mul1[31:16]:x_mul1[30:15];
assign x_int_mul2=(x_mul2[31]^x_mul2[30])?x_mul2[31:16]:x_mul2[30:15];
assign x_int_mul3=(x_mul3[31]^x_mul3[30])?x_mul3[31:16]:x_mul3[30:15];
assign x_temp=(x_sum[17:15]==3'b000||x_sum[17:15]==3'b111)?x_sum[15:0]:(x_sum[17])?16'h8000:16'h7fff;
assign y_int_mul1=(y_mul1[31]^y_mul1[30])?y_mul1[31:16]:y_mul1[30:15];
assign y_int_mul2=(y_mul2[31]^y_mul2[30])?y_mul2[31:16]:y_mul2[30:15];
assign y_temp=(y_sum[16:15]==2'b00||y_sum[16:15]==2'b11)?y_sum[15:0]:(y_sum[16])?16'h8000:16'h7fff;
assign dout_temp=(dout_sum[16:15]==2'b00||dout_sum[16:15]==2'b11)?dout_sum[15:0]:(dout_sum[16])?16'h8000:16'h7fff;
assign dout=(!rst)?16'd0:dout_temp;
always @(cState) begin
        if(rst) begin
                case(cState)
                        4: begin
                                x_reg0<=din;
                                x_reg1<=x_reg0;
                        end
                        default:begin
                                x_reg0<=x_reg0;
                                x_reg1<=x_reg1;
                        end
                endcase
        end
        else begin
                x_reg0<=16'd0;
                x_reg1<=16'd0;
        end
end
always @(cState) begin
        if(rst) begin
                if(cState==6) begin
                        y_reg0<=dout;
                        y_reg1<=y_reg0;
                end
                else begin
                        y_reg0<=y_reg0;
                        y_reg1<=y_reg1;
                end
        end
     

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top