基于FPGA的IIR滤波器
基于FPGA的IIR滤波器
by方阳
版权声明:本文为博主原创文章,转载请指明转载地址
http://www.cnblogs.com/fydeblog/p/6748998.html
1.说明
写了那么多数字图像处理的,再写点其他的吧,今天写点FPGA的东西,是之前EDA做的综合大实验,拿出来和大家分享分享!
先说一下,此篇文章是基于你有IIR滤波器的原理和FPGA语言(也就是Verilog HDL)基础上的!至于IIR滤波器的原理和Verilog HDL语言,我这里就不说了,网上有一大堆的资料可以观看,IIR可以看数字信号处理的书或直接百度,Verilog HDL推荐《Hello,FPGA》!
申明一下,这边博客很长,请做好心理准备!!!
要感谢的人:感谢电子发烧网的牛哥哥要炸天的指导,感谢小梅哥的指导,感谢Hello FPGA团队的书籍!!!感谢,感谢,感谢!!!
说明:这个IIR滤波器我是用小梅哥的芯航线FPGA开发板——cyclone IV E EP4CE10F1708实现的,还用了他的ADDA模块——集成TLC1544 ADC采集芯片和TLC5620 DAC 输出芯片,软件平台是quartus13.0,测试用的是信号发生器和示波器。
这个共有一个顶层文件,十一个子文件,子文件其中一个是IIR滤波器的顶层文件。拓扑图如下:

2.参考代码
相应的代码如下
2.1 顶层文件
IIR_FY_TOP.V
module IIR_FY_TOP
(
Clk,
Rst_n, TLC5620_CLK,
TLC5620_DATA,
TLC5620_LOAD,
TLC5620_LDAC, TLV1544_SDO,
TLV1544_SDI,
TLV1544_SCLK,
TLV1544_NCS,
TLV1544_FS,
TLV1544_EOC ); input Clk;
input Rst_n; output TLC5620_CLK;
output TLC5620_DATA;
output TLC5620_LOAD;
output TLC5620_LDAC; input TLV1544_SDO;
output TLV1544_SDI;
output TLV1544_SCLK;
output TLV1544_NCS;
output TLV1544_FS;
input TLV1544_EOC; wire AD_DONE;
wire [:]ADC_DATA;
wire DATA_Valid;
wire [:]CtrlWord;
wire signed[:] din;
wire signed[:] dout; TLV1544_CTRL TLV1544_CTRL0( .Clk(Clk),
.Rst_n(Rst_n), .Do_Conv('b1), //开始转换使能信号
.AD_DONE(AD_DONE), //转换完成信号
.ADC_CHSEL('b0), //通道选择 .ADC_DATA(ADC_DATA), //采样结果
.DATA_Valid(DATA_Valid), .TLV1544_SDO(TLV1544_SDO),
.TLV1544_SDI(TLV1544_SDI),
.TLV1544_SCLK(TLV1544_SCLK),
.TLV1544_NCS(TLV1544_NCS),
.TLV1544_FS(TLV1544_FS),
.TLV1544_EOC(TLV1544_EOC)
); ADC_to_filter ADC_to_filter0( .ADC_DATA(ADC_DATA),
.din(din) ); myiir myiir0(
.rst(Rst_n),
.clk(Clk),
.din(din),
.dout(dout),
.din_valid(DATA_Valid),
.dout_valid()
); filter_to_DAC filter_to_DAC0(
.dout(dout),
.CtrlWord(CtrlWord)
); TLC5620_CTRL TLC5620_CTRL0(
.Clk(Clk),
.Rst_n(Rst_n),
.UpdateReq('b1),
.CtrlWord(CtrlWord), .UpdateDone(),
.TLC5620_CLK(TLC5620_CLK),
.TLC5620_DATA(TLC5620_DATA),
.TLC5620_LOAD(TLC5620_LOAD),
.TLC5620_LDAC(TLC5620_LDAC)
); endmodule
2.2 TLV1544驱动
TLV1544_CTRL.V
module TLV1544_CTRL(
Clk,
Rst_n,
Do_Conv, //开始转换使能信号
AD_DONE, //转换完成信号
ADC_CHSEL, //通道选择
ADC_DATA, //采样结果
DATA_Valid,
TLV1544_SDO,
TLV1544_SDI,
TLV1544_SCLK,
TLV1544_NCS,
TLV1544_FS,
TLV1544_EOC
);
input Clk;
input Rst_n;
input Do_Conv; //开始转换使能信号
input [:]ADC_CHSEL; //通道选择
output reg [:]ADC_DATA; //采样结果
output reg AD_DONE; //转换完成信号
output reg DATA_Valid;
input TLV1544_SDO;
input TLV1544_EOC;
output reg TLV1544_SDI;
output reg TLV1544_SCLK;
output reg TLV1544_NCS;
output wire TLV1544_FS;
assign TLV1544_FS = 'b1;
reg [:] LSM_CNT;//序列计数器
reg [:] rADC_DATA;
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
LSM_CNT <= 'd0;
else if(LSM_CNT < && (TLV1544_EOC == 'b1) && (Do_Conv || LSM_CNT > 8'd0))
LSM_CNT <= LSM_CNT + 'b1;
else if(LSM_CNT < && (TLV1544_EOC == 'b0))
LSM_CNT <= LSM_CNT;
else if(LSM_CNT == && (TLV1544_EOC == 'b1))
LSM_CNT <= 'd0;
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)begin
rADC_DATA <= 'd0;
TLV1544_SDI <= 'b0;
TLV1544_SCLK <= 'b0;
TLV1544_NCS <= 'b1;
AD_DONE <= 'b0;
DATA_Valid <= 'b0;
ADC_DATA <= 'd0;
end
else begin
case(LSM_CNT)
:
begin
rADC_DATA <= 'd0;
TLV1544_SDI <= 'b0;
TLV1544_SCLK <= 'b0;
TLV1544_NCS <= 'b1;
AD_DONE <= 'b0;
end
:
begin
TLV1544_NCS <= 'b0;
TLV1544_SDI <= ADC_CHSEL[];
end
:
begin
TLV1544_SCLK <= 'b1;
rADC_DATA[] <= TLV1544_SDO;
end
:
begin
TLV1544_SDI <= ADC_CHSEL[];
TLV1544_SCLK <= 'b0;
end
:
begin
TLV1544_SCLK <= 'b1;
rADC_DATA[] <= TLV1544_SDO;
end
:
begin
TLV1544_SDI <= ADC_CHSEL[];
TLV1544_SCLK <= 'b0;
end
:
begin
TLV1544_SCLK <= 'b1;
rADC_DATA[] <= TLV1544_SDO;
end
:
begin
TLV1544_SDI <= ADC_CHSEL[];
TLV1544_SCLK <= 'b0;
end
:
begin
TLV1544_SCLK <= 'b1;
rADC_DATA[] <= TLV1544_SDO;
end
:TLV1544_SCLK <= 'b0;
:
begin
TLV1544_SCLK <= 'b1;
rADC_DATA[] <= TLV1544_SDO;
end
:TLV1544_SCLK <= 'b0;
:
begin
TLV1544_SCLK <= 'b1;
rADC_DATA[] <= TLV1544_SDO;
end
:TLV1544_SCLK <= 'b0;
:
begin
TLV1544_SCLK <= 'b1;
rADC_DATA[] <= TLV1544_SDO;
end
:TLV1544_SCLK <= 'b0;
:
begin
TLV1544_SCLK <= 'b1;
rADC_DATA[] <= TLV1544_SDO;
end
:TLV1544_SCLK <= 'b0;
:
begin
TLV1544_SCLK <= 'b1;
rADC_DATA[] <= TLV1544_SDO;
end
:TLV1544_SCLK <= 'b0;
:
begin
TLV1544_SCLK <= 'b1;
//rADC_DATA[0] <= TLV1544_SDO;
if(TLV1544_EOC)
DATA_Valid <= 'b1;
else
DATA_Valid <= 'b0;
ADC_DATA <= {rADC_DATA[:],TLV1544_SDO};
end
:
begin
TLV1544_SCLK <= 'b0;
TLV1544_NCS <= 'b1;
end
:AD_DONE <= 'b1;
default:DATA_Valid <= 'b0;
endcase
end
endmodule
2.3 ADC转filter模块
ADC_to_filter.V
module ADC_to_filter ( ADC_DATA,
din ); input [:]ADC_DATA;
output signed[:]din; assign din = ADC_DATA<<; endmodule
2.4 myiir模块
myiir.V
module myiir(
rst,
clk,
din,
dout,
din_valid,
dout_valid,
);
input rst;
input clk;
input signed[:] din;
input din_valid;
output reg signed[:] dout;
output reg dout_valid; wire signed[:] dout1;
wire signed[:] dout2;
wire signed[:] dout3;
wire signed[:] dout4;
wire signed[:] dout5;
wire signed[:] 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<='d0;
dout_valid='b0;
end
else if(dout_valid6) begin
dout_valid='b1;
dout<=dout_reg;
end
else begin
dout<=dout;
dout_valid='b0;
end
end endmodule
2.5 filter转DAC模块
filter_to_DAC.V
module filter_to_DAC
(
dout,
CtrlWord ); input signed[:] dout;
output [:]CtrlWord; assign CtrlWord[:]=dout[:];
assign CtrlWord[:]='b0; endmodule
2.6 TLC5620驱动
TLC5620_CTRL.V
module TLC5620_CTRL(
Clk,
Rst_n,
UpdateReq,
CtrlWord, UpdateDone,
TLC5620_CLK,
TLC5620_DATA,
TLC5620_LOAD,
TLC5620_LDAC
); input Clk;
input Rst_n;
input UpdateReq;
input [:]CtrlWord; output reg UpdateDone;
output reg TLC5620_CLK;
output reg TLC5620_DATA;
output reg TLC5620_LOAD;
output reg TLC5620_LDAC; reg [:] Cnt; always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
Cnt <= 'd0;
else if(UpdateReq == | (Cnt != 'd0))begin
if(Cnt == 'd820)
Cnt <= 'd0;
else
Cnt <= Cnt + 'd1;
end
else
Cnt <= 'd0; always@(posedge Clk or negedge Rst_n)
if(!Rst_n)begin
TLC5620_CLK <= 'b0;
TLC5620_DATA <= 'b0;
TLC5620_LOAD <= 'b0;
TLC5620_LDAC <= 'b0;
UpdateDone <= 'b0;
end
else begin
case(Cnt)
:
begin
TLC5620_CLK <= 'b0;
TLC5620_DATA <= 'b0;
TLC5620_LOAD <= 'b1;
TLC5620_LDAC <= 'b0;
UpdateDone <= 'b0;
end
:
begin
TLC5620_CLK <= 'b1;
TLC5620_DATA <= CtrlWord[];
end
: TLC5620_CLK <= 'b0; :
begin
TLC5620_CLK <= 'b1;
TLC5620_DATA <= CtrlWord[];
end : TLC5620_CLK <= 'b0;
:
begin
TLC5620_CLK <= 'b1;
TLC5620_DATA <= CtrlWord[];
end
: TLC5620_CLK <= 'b0;
:
begin
TLC5620_CLK <= 'b1;
TLC5620_DATA <= CtrlWord[];
end
: TLC5620_CLK <= 'b0;
:
begin
TLC5620_CLK <= 'b1;
TLC5620_DATA <= CtrlWord[];
end
: TLC5620_CLK <= 'b0;
:
begin
TLC5620_CLK <= 'b1;
TLC5620_DATA <= CtrlWord[];
end
: TLC5620_CLK <= 'b0;
:
begin
TLC5620_CLK <= 'b1;
TLC5620_DATA <= CtrlWord[];
end
: TLC5620_CLK <= 'b0;
:
begin
TLC5620_CLK <= 'b1;
TLC5620_DATA <= CtrlWord[];
end
: TLC5620_CLK <= 'b0;
:
begin
TLC5620_CLK <= 'b1;
TLC5620_DATA <= CtrlWord[];
end
: TLC5620_CLK <= 'b0;
:
begin
TLC5620_CLK <= 'b1;
TLC5620_DATA <= CtrlWord[];
end
: TLC5620_CLK <= 'b0;
:
begin
TLC5620_CLK <= 'b1;
TLC5620_DATA <= CtrlWord[];
end
: TLC5620_CLK <= 'b0;
:TLC5620_LOAD <= 'b0;
:TLC5620_LOAD <= 'b1;
:UpdateDone <= 'b1;
default:;
endcase
end endmodule
2.7 myiir_first_step模块
myiir_first_step.V
module myiir_first_step(
rst,
clk,
din,
dout,
din_valid,
dout_valid
); parameter b0=;
parameter b1=-;
parameter b2=;
parameter a1=-;
parameter a2=; input rst;
input clk;
input signed[:] din;
input din_valid; output signed[:] dout;
output dout_valid; reg[:] cState,nState;
reg signed[:] x_reg0;
reg signed[:] x_reg1; reg signed[:] x_mul1;
reg signed[:] x_mul2;
reg signed[:] x_mul3; wire signed[:] x_int_mul1;
wire signed[:] x_int_mul2;
wire signed[:] x_int_mul3; reg signed[:] x_sum;
wire signed[:] x_temp; reg signed[:] y_reg0;
reg signed[:] y_reg1; reg signed[:] y_mul1;
reg signed[:] y_mul2; wire signed[:] y_int_mul1;
wire signed[:] y_int_mul2; reg signed[:] y_sum;
wire signed[:] y_temp; reg signed[:] dout_sum;
wire signed[:] dout_temp; always @(negedge rst,posedge clk) begin
if(!rst) begin
cState<=;
end
else begin
cState<=nState;
end
end always @(*) begin
case(cState)
:if(din_valid) begin
nState<=;
end
else begin
nState<=;
end
:nState<=;
:nState<=;
:nState<=;
:nState<=;
:nState<=;
:nState<=;
default:nState<=nState;
endcase
end always @(*) begin
if(rst) begin
case(cState)
:x_mul1=b0*din;
:begin
x_mul2=b1*x_reg0;
y_mul1=a1*y_reg0;
end
:begin
x_mul3=b2*x_reg1;
y_mul2=a2*y_reg1;
end
:begin
x_sum=x_int_mul1+x_int_mul2+x_int_mul3;
y_sum=y_int_mul1+y_int_mul2;
end
:dout_sum=x_temp-y_temp;
default:;
endcase
end
end always @(cState) begin
if(rst) begin
if(cState==) 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<='d0;
x_reg1<='d0;
end
end always @(cState) begin
if(rst) begin
if(cState==) 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<='d0;
y_reg1<='d0;
end
end assign x_int_mul1=(x_mul1[]^x_mul1[])?x_mul1[:]:x_mul1[:];
assign x_int_mul2=(x_mul2[]^x_mul2[])?x_mul2[:]:x_mul2[:];
assign x_int_mul3=(x_mul3[]^x_mul3[])?x_mul3[:]:x_mul3[:];
assign x_temp=(x_sum[:]=='b000||x_sum[17:15]==3'b111)?x_sum[:]:(x_sum[])?'h8000:16'h7fff; assign y_int_mul1=(y_mul1[]^y_mul1[])?y_mul1[:]:y_mul1[:];
assign y_int_mul2=(y_mul2[]^y_mul2[])?y_mul2[:]:y_mul2[:];
assign y_temp=(y_sum[:]=='b00||y_sum[16:15]==2'b11)?y_sum[:]:(y_sum[])?'h8000:16'h7fff; assign dout_temp=(dout_sum[:]=='b00||dout_sum[16:15]==2'b11)?dout_sum[:]:(dout_sum[])?'h8000:16'h7fff;
assign dout=(!rst)?'d0:dout_temp; assign dout_valid=(cState== && nState==)?'b1:1'b0; endmodule
2.8 myiir_second_step模块
myiir_second_step.V
module myiir_second_step(
rst,
clk,
din,
dout,
din_valid,
dout_valid
); parameter b0=;
parameter b1=-;
parameter b2=;
parameter a1=-;
parameter a2=; input rst;
input clk;
input signed[:] din;
input din_valid; output signed[:] dout;
output dout_valid; reg[:] cState,nState;
reg signed[:] x_reg0;
reg signed[:] x_reg1; reg signed[:] x_mul1;
reg signed[:] x_mul2;
reg signed[:] x_mul3; wire signed[:] x_int_mul1;
wire signed[:] x_int_mul2;
wire signed[:] x_int_mul3; reg signed[:] x_sum;
wire signed[:] x_temp; reg signed[:] y_reg0;
reg signed[:] y_reg1; reg signed[:] y_mul1;
reg signed[:] y_mul2; wire signed[:] y_int_mul1;
wire signed[:] y_int_mul2; reg signed[:] y_sum;
wire signed[:] y_temp; reg signed[:] dout_sum;
wire signed[:] dout_temp; always @(negedge rst,posedge clk) begin
if(!rst) begin
cState<=;
end
else begin
cState<=nState;
end
end always @(*) begin
case(cState)
:if(din_valid) begin
nState<=;
end
else begin
nState<=;
end
:nState<=;
:nState<=;
:nState<=;
:nState<=;
:nState<=;
:nState<=;
default:nState<=nState;
endcase
end always @(*) begin
if(rst) begin
case(cState)
:x_mul1=b0*din;
:begin
x_mul2=b1*x_reg0;
y_mul1=a1*y_reg0;
end
:begin
x_mul3=b2*x_reg1;
y_mul2=a2*y_reg1;
end
:begin
x_sum=x_int_mul1+x_int_mul2+x_int_mul3;
y_sum=y_int_mul1+y_int_mul2;
end
: dout_sum=x_temp-y_temp;
default:;
endcase
end
end assign x_int_mul1=(x_mul1[]^x_mul1[])?x_mul1[:]:x_mul1[:];
assign x_int_mul2=(x_mul2[]^x_mul2[])?x_mul2[:]:x_mul2[:];
assign x_int_mul3=(x_mul3[]^x_mul3[])?x_mul3[:]:x_mul3[:];
assign x_temp=(x_sum[:]=='b000||x_sum[17:15]==3'b111)?x_sum[:]:(x_sum[])?'h8000:16'h7fff; assign y_int_mul1=(y_mul1[]^y_mul1[])?y_mul1[:]:y_mul1[:];
assign y_int_mul2=(y_mul2[]^y_mul2[])?y_mul2[:]:y_mul2[:];
assign y_temp=(y_sum[:]=='b00||y_sum[16:15]==2'b11)?y_sum[:]:(y_sum[])?'h8000:16'h7fff; assign dout_temp=(dout_sum[:]=='b00||dout_sum[16:15]==2'b11)?dout_sum[:]:(dout_sum[])?'h8000:16'h7fff;
assign dout=(!rst)?'d0:dout_temp; always @(cState) begin
if(rst) begin
if(cState==) 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<='d0;
x_reg1<='d0;
end
end always @(cState) begin
if(rst) begin
if(cState==) 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<='d0;
y_reg1<='d0;
end
end assign dout_valid=(cState== && nState==)?'b1:1'b0; endmodule
2.9 myiir_third_step模块
myiir_third_step.V
module myiir_third_step(
rst,
clk,
din,
dout,
din_valid,
dout_valid
); parameter b0=;
parameter b1=-;
parameter b2=;
parameter a1=-;
parameter a2=; input rst;
input clk;
input signed[:] din;
input din_valid; output signed[:] dout;
output dout_valid; reg[:] cState,nState;
reg signed[:] x_reg0;
reg signed[:] x_reg1; reg signed[:] x_mul1;
reg signed[:] x_mul2;
reg signed[:] x_mul3; wire signed[:] x_int_mul1;
wire signed[:] x_int_mul2;
wire signed[:] x_int_mul3; reg signed[:] x_sum;
wire signed[:] x_temp; reg signed[:] y_reg0;
reg signed[:] y_reg1; reg signed[:] y_mul1;
reg signed[:] y_mul2; wire signed[:] y_int_mul1;
wire signed[:] y_int_mul2; reg signed[:] y_sum;
wire signed[:] y_temp; reg signed[:] dout_sum;
wire signed[:] dout_temp; always @(negedge rst,posedge clk) begin
if(!rst) begin
cState<=;
end
else begin
cState<=nState;
end
end always @(*) begin
case(cState)
:if(din_valid) begin
nState<=;
end
else begin
nState<=;
end
:nState<=;
:nState<=;
:nState<=;
:nState<=;
:nState<=;
:nState<=;
default:nState<=nState;
endcase
end always @(*) begin
if(rst) begin
case(cState)
:x_mul1=b0*din;
:begin
x_mul2=b1*x_reg0;
y_mul1=a1*y_reg0;
end
:begin
x_mul3=b2*x_reg1;
y_mul2=a2*y_reg1;
end
:begin
x_sum=x_int_mul1+x_int_mul2+x_int_mul3;
y_sum=y_int_mul1+y_int_mul2;
end
: dout_sum=x_temp-y_temp;
default:;
endcase
end
end assign x_int_mul1=(x_mul1[]^x_mul1[])?x_mul1[:]:x_mul1[:];
assign x_int_mul2=(x_mul2[]^x_mul2[])?x_mul2[:]:x_mul2[:];
assign x_int_mul3=(x_mul3[]^x_mul3[])?x_mul3[:]:x_mul3[:];
assign x_temp=(x_sum[:]=='b000||x_sum[17:15]==3'b111)?x_sum[:]:(x_sum[])?'h8000:16'h7fff; assign y_int_mul1=(y_mul1[]^y_mul1[])?y_mul1[:]:y_mul1[:];
assign y_int_mul2=(y_mul2[]^y_mul2[])?y_mul2[:]:y_mul2[:];
assign y_temp=(y_sum[:]=='b00||y_sum[16:15]==2'b11)?y_sum[:]:(y_sum[])?'h8000:16'h7fff; assign dout_temp=(dout_sum[:]=='b00||dout_sum[16:15]==2'b11)?dout_sum[:]:(dout_sum[])?'h8000:16'h7fff;
assign dout=(!rst)?'d0:dout_temp; always @(cState) begin
if(rst) begin
if(cState==) 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<='d0;
x_reg1<='d0;
end
end always @(cState) begin
if(rst) begin
if(cState==) 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<='d0;
y_reg1<='d0;
end
end assign dout_valid=(cState== && nState==)?'b1:1'b0; endmodule
2.10 myiir_fourth_step模块
myiir_fourth_step.V
module myiir_fourth_step(
rst,
clk,
din,
dout,
din_valid,
dout_valid
); parameter b0=;
parameter b1=-;
parameter b2=;
parameter a1=-;
parameter a2=; input rst;
input clk;
input signed[:] din;
input din_valid; output signed[:] dout;
output dout_valid; reg[:] cState,nState;
reg signed[:] x_reg0;
reg signed[:] x_reg1; reg signed[:] x_mul1;
reg signed[:] x_mul2;
reg signed[:] x_mul3; wire signed[:] x_int_mul1;
wire signed[:] x_int_mul2;
wire signed[:] x_int_mul3; reg signed[:] x_sum;
wire signed[:] x_temp; reg signed[:] y_reg0;
reg signed[:] y_reg1; reg signed[:] y_mul1;
reg signed[:] y_mul2; wire signed[:] y_int_mul1;
wire signed[:] y_int_mul2; reg signed[:] y_sum;
wire signed[:] y_temp; reg signed[:] dout_sum;
wire signed[:] dout_temp; always @(negedge rst,posedge clk) begin
if(!rst) begin
cState<=;
end
else begin
cState<=nState;
end
end always @(*) begin
case(cState)
:if(din_valid) begin
nState<=;
end
else begin
nState<=;
end
:nState<=;
:nState<=;
:nState<=;
:nState<=;
:nState<=;
:nState<=;
default:nState<=nState;
endcase
end always @(*) begin
if(rst) begin
case(cState)
:x_mul1=b0*din;
:begin
x_mul2=b1*x_reg0;
y_mul1=a1*y_reg0;
end
:begin
x_mul3=b2*x_reg1;
y_mul2=a2*y_reg1;
end
:begin
x_sum=x_int_mul1+x_int_mul2+x_int_mul3;
y_sum=y_int_mul1+y_int_mul2;
end
: dout_sum=x_temp-y_temp;
default:;
endcase
end
end assign x_int_mul1=(x_mul1[]^x_mul1[])?x_mul1[:]:x_mul1[:];
assign x_int_mul2=(x_mul2[]^x_mul2[])?x_mul2[:]:x_mul2[:];
assign x_int_mul3=(x_mul3[]^x_mul3[])?x_mul3[:]:x_mul3[:];
assign x_temp=(x_sum[:]=='b000||x_sum[17:15]==3'b111)?x_sum[:]:(x_sum[])?'h8000:16'h7fff; assign y_int_mul1=(y_mul1[]^y_mul1[])?y_mul1[:]:y_mul1[:];
assign y_int_mul2=(y_mul2[]^y_mul2[])?y_mul2[:]:y_mul2[:];
assign y_temp=(y_sum[:]=='b00||y_sum[16:15]==2'b11)?y_sum[:]:(y_sum[])?'h8000:16'h7fff; assign dout_temp=(dout_sum[:]=='b00||dout_sum[16:15]==2'b11)?dout_sum[:]:(dout_sum[])?'h8000:16'h7fff;
assign dout=(!rst)?'d0:dout_temp; always @(cState) begin
if(rst) begin
case(cState)
: 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<='d0;
x_reg1<='d0;
end
end always @(cState) begin
if(rst) begin
if(cState==) 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<='d0;
y_reg1<='d0;
end
end assign dout_valid=(cState== && nState==)?'b1:1'b0; endmodule
2.11 myiir_fifth_step模块
myiir_fifth_step.V
module myiir_fifth_step(
rst,
clk,
din,
dout,
din_valid,
dout_valid
); parameter b0=;
parameter b1=-;
parameter b2=;
parameter a1=-;
parameter a2=; input rst;
input clk;
input signed[:] din;
input din_valid; output signed[:] dout;
output dout_valid; reg[:] cState,nState;
reg signed[:] x_reg0;
reg signed[:] x_reg1; reg signed[:] x_mul1;
reg signed[:] x_mul2;
reg signed[:] x_mul3; wire signed[:] x_int_mul1;
wire signed[:] x_int_mul2;
wire signed[:] x_int_mul3; reg signed[:] x_sum;
wire signed[:] x_temp; reg signed[:] y_reg0;
reg signed[:] y_reg1; reg signed[:] y_mul1;
reg signed[:] y_mul2; wire signed[:] y_int_mul1;
wire signed[:] y_int_mul2; reg signed[:] y_sum;
wire signed[:] y_temp; reg signed[:] dout_sum;
wire signed[:] dout_temp; always @(negedge rst,posedge clk) begin
if(!rst) begin
cState<=;
end
else begin
cState<=nState;
end
end always @(*) begin
case(cState)
:if(din_valid) begin
nState<=;
end
else begin
nState<=;
end
:nState<=;
:nState<=;
:nState<=;
:nState<=;
:nState<=;
:nState<=;
default:nState<=nState;
endcase
end always @(*) begin
if(rst) begin
case(cState)
:x_mul1=b0*din;
:begin
x_mul2=b1*x_reg0;
y_mul1=a1*y_reg0;
end
:begin
x_mul3=b2*x_reg1;
y_mul2=a2*y_reg1;
end
:begin
x_sum=x_int_mul1+x_int_mul2+x_int_mul3;
y_sum=y_int_mul1+y_int_mul2;
end
: dout_sum=x_temp-y_temp;
default:;
endcase
end
end assign x_int_mul1=(x_mul1[]^x_mul1[])?x_mul1[:]:x_mul1[:];
assign x_int_mul2=(x_mul2[]^x_mul2[])?x_mul2[:]:x_mul2[:];
assign x_int_mul3=(x_mul3[]^x_mul3[])?x_mul3[:]:x_mul3[:];
assign x_temp=(x_sum[:]=='b000||x_sum[17:15]==3'b111)?x_sum[:]:(x_sum[])?'h8000:16'h7fff; assign y_int_mul1=(y_mul1[]^y_mul1[])?y_mul1[:]:y_mul1[:];
assign y_int_mul2=(y_mul2[]^y_mul2[])?y_mul2[:]:y_mul2[:];
assign y_temp=(y_sum[:]=='b00||y_sum[16:15]==2'b11)?y_sum[:]:(y_sum[])?'h8000:16'h7fff; assign dout_temp=(dout_sum[:]=='b00||dout_sum[16:15]==2'b11)?dout_sum[:]:(dout_sum[])?'h8000:16'h7fff;
assign dout=(!rst)?'d0:dout_temp; always @(cState) begin
if(rst) begin
case(cState)
: 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<='d0;
x_reg1<='d0;
end
end always @(cState) begin
if(rst) begin
if(cState==) 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<='d0;
y_reg1<='d0;
end
end assign dout_valid=(cState== && nState==)?'b1:1'b0; endmodule
2.12 myiir_sixth_step模块
myiir_sixth_step.V
module myiir_sixth_step(
rst,
clk,
din,
dout,
din_valid,
dout_valid
); parameter b0=;
parameter b1=;
parameter a1=-; input rst;
input clk;
input signed[:] din;
input din_valid; output signed[:] dout;
output dout_valid; reg[:] cState,nState; reg signed[:] x_reg0; reg signed[:] x_mul1;
reg signed[:] x_mul2; wire signed[:] x_int_mul1;
wire signed[:] x_int_mul2; reg signed[:] x_sum;
wire signed[:] x_temp; reg signed[:] y_reg0; reg signed[:] y_mul1;
wire signed[:] y_int_mul1; reg signed[:] dout_sum;
wire signed[:] dout_temp; always @(negedge rst,posedge clk) begin
if(!rst) begin
cState<=;
end
else begin
cState<=nState;
end
end always @(*) begin
case(cState)
:if(din_valid) begin
nState<=;
end
else begin
nState<=;
end
:nState<=;
:nState<=;
:nState<=;
:nState<=;
:nState<=;
default:nState<=;
endcase
end always @(*) begin
if(rst) begin
case(cState)
:x_mul1=b0*din;
:begin
x_mul2=b1*x_reg0;
y_mul1=a1*y_reg0;
end
:begin
x_sum=x_int_mul1+x_int_mul2;
end
:begin
dout_sum=x_temp-y_int_mul1;
end
default:;
endcase
end
end assign x_int_mul1=(x_mul1[]^x_mul1[])?x_mul1[:]:x_mul1[:];
assign x_int_mul2=(x_mul2[]^x_mul2[])?x_mul2[:]:x_mul2[:];
assign x_temp=(x_sum[:]=='b00||x_sum[16:15]==2'b11)?x_sum[:]:(x_sum[])?'h8000:16'h7fff; assign y_int_mul1=(y_mul1[]^y_mul1[])?y_mul1[:]:y_mul1[:]; assign dout_temp=(dout_sum[:]=='b00||dout_sum[16:15]==2'b11)?dout_sum[:]:(dout_sum[])?'h8000:16'h7fff;
assign dout=(!rst)?'d0:dout_temp; always @(cState) begin
if(rst) begin
if(cState==) begin
x_reg0<=din;
end
else begin
x_reg0<=x_reg0;
end
end
else begin
x_reg0<='d0;
end
end always @(cState) begin
if(rst) begin
if(cState==) begin
y_reg0<=dout;
end
else begin
y_reg0<=y_reg0;
end
end
else begin
y_reg0<='d0;
end
end assign dout_valid=(cState== && nState==)?'b1:1'b0; endmodule
代码到这里终于结束了!辛苦观看。。
3.仿真与引脚分配
3.1 仿真
实验使用modelsim进行仿真,从matlab获得量化后的输入波形文件,经过仿真后得到滤波后的波形。

3.2 引脚分配

4.心得
本次实验好艰辛啊!从最开始的晕头晕脑,到最后有效果,时间挺长的,但确实学到了许多!通过这次实验,不仅更加熟练地学习到了FPGA设计的流程,更加深了数字信号处理滤波器的设计和实现!重要是坚持!!!
5.视频地址
前篇
http://v.youku.com/v_show/id_XMjcyMjkwNDY3Mg==.html
后篇
http://v.youku.com/v_show/id_XMjcyMjkyOTYzMg==.html
end
基于FPGA的IIR滤波器的更多相关文章
- 基于FPGA的图像去噪
目录 结构图 其中FPGA 控制模块为核心,通过它实现视频图像数据的获取.缓存.处理和控制各模块间通讯[1].由CCD 相机对目标成像,高速图像数据由camera link 实时传输[2],经信号转换 ...
- 基于FPGA的16阶级联型iir带通滤波器实现
警告 此文章将耗费你成吨的流量,请wifi下阅读,造成的流量浪费本人不承担任何责任.初版源代码获取(请勿用作他用,仅供学习):https://gitee.com/kingstacker/iir.git ...
- 基于FPGA dspbuilder的DNLMS滤波器实现
自适应滤波器一直是信号处理领域的研究热点之一,经过多年的发展,已经被广泛应用于数字通信.回声消除.图像处理等领域.自适应滤波算法的研究始于20世纪50年代末,Widrow和Hoff等人最早 ...
- 基于FPGA的音频信号的FIR滤波(Matlab+Modelsim验证)
1 设计内容 本设计是基于FPGA的音频信号FIR低通滤波,根据要求,采用Matlab对WAV音频文件进行读取和添加噪声信号.FFT分析.FIR滤波处理,并分析滤波的效果.通过Matlab的分析验证滤 ...
- FIR滤波器和IIR滤波器的区别
数字滤波器广泛应用于硬件电路设计,在离散系统中尤为常见,一般可以分为FIR滤波器和IIR滤波器,那么他们有什么区别和联系呢. FIR滤波器 定义: FIR滤波器是有限长单位冲激响应滤波器,又称为非递归 ...
- 基于FPGA的DDS设计(一)
最近在学习基于FPGA的DDS设计,借此机会把学习过程记录下来,当作自己的学习笔记也希望能够帮助到学习DDS的小伙伴. DDS(Direct Digital Synthesizer)直接数字合成器,这 ...
- IIR滤波器设计(调用MATLAB IIR函数来实现)
转载请注明文章来源 – http://blog.csdn.net/v_hyx ,请勿用于任何商业用途 对于滤波器设计,以前虽然学过相关的理论(现代数字信号处理和DSP设计),但一直不求 ...
- IIR滤波器和FIR滤波器的区别与联系zz
-------------------------------------------------------------------------------------------------- ...
- 基于FPGA的飞机的小游戏
基于FPGA的飞机的小游戏 实验原理 该实验主要分为4个模块,采用至上而下的设计方法进行设计.由50M的晶振电路提供时钟源,VGA显示控制模块.图形显示控制模块.移动模块的时钟为25M,由时钟分频电路 ...
随机推荐
- lightoj1336数论基础
#include<iostream> #include<cstdio> #include<cmath> #define ll long long using nam ...
- Linux的正则表达式grep,egrep
一.概念 正则表达式是对字符串操作的一种逻辑公式,用事先定义好的一组特殊字符,组成一个"规则字符集合",根据用户指定的文本模式对目标文件进行逐行搜索匹配,显示能被模式匹配到的结果. ...
- Redis学习-持久化
Redis 提供了多种不同级别的持久化方式: RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot). AOF 持久化记录服务器执行的所有写操作命令 ...
- Kafka学习-复制
复制 Kafka可以通过可配置的服务器数量复制每个主题分区的日志(可以为每个主题设置复制因子).这允许在集群中的服务器发生故障时自动故障转移到其他副本,因此在存在故障的情况下,消息仍然可用. 其他消息 ...
- 【JAVAWEB学习笔记】06_jQuery基础
接05的学习笔记. 四.使用JQ完成省市二级联动 1.需求分析 使用jquery完成省市二级联动 2.技术分析 2.1数组的遍历操作 方式一: $(function(){ // 全选/ 全不选 $(& ...
- 销量预测和用户行为的分析--基于ERP的交易数据
写在前面: 这段时间一直都在看一些机器学习方面的内容,其中又花了不少时间在推荐系统这块,然后自己做了一套简单的推荐系统,但是跑下来的结果总觉得有些差强人意,我在离线实验中得到Precision,Rec ...
- 传感器系列之4.12GPS定位传感器
4.12 GPS定位实验 一.实验目的 了解GPS的基本概念 了解NMEA-0183格式数据串的组成和关于GPS的常用语句 GPS的数据串解析 二.实验材料 具有串口通讯的电脑一台 ADS1.2开发环 ...
- 主机设置ss代理,虚拟机共享代理
代理的原理: 关于代理的具体的书面定义你百度谷歌可以知道.这里,我想简单通过一个例子,说明代理的原理: 假如,你在北京,但你女朋友在广州,你有东西要给你的女朋友,但是正好你这几天公司有事,所以你不能去 ...
- Nginx教程(四) Location配置与ReWrite语法
Nginx教程(四) Location配置与ReWrite语法 1 Location语法规则 1.1 Location规则 语法规则: location [=|~|~*|^~] /uri/ {- } ...
- 如何打一个FatJar(uber-jar)
如何打一个FatJar(uber-jar) FatJar也就叫做UberJar,是一种可执行的Jar包(Executable Jar).FatJar和普通的jar不同在于它包含了依赖的jar包. 1. ...