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
在时域内
发送信号: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