基于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,由时钟分频电路 ...
随机推荐
- 观察者模式(Observer)发布、订阅模式
观察者模式定义了对象之间一对多的依赖关系,这样一来,当一个对象改变时,他的所有依赖者都会收到通知并自动更新. 模式中的角色 1.抽象主题(Subject):它把所有观察者对象的引用保存到一个聚集里 ...
- 构建你人生里的第一个 Laravel 项目
安装 Laravel 安装器 composer global require "laravel/installer" 创建项目 laravel new links 检查是否安装成功 ...
- 关于IT创业和反思
2016年8月的某一天本是世上平凡的一天,对于我而言却并不平凡. 这一天,我离开了待了近四年的创业公司.从它成立前的筹备开始,伴随着它的起起伏伏到完成C轮融资,从来没想过以这种方式离开,然而人生总是充 ...
- 使用命令行的方式操作hdfs
必须要用打全路径,没有相对路径的概念,或者cd的概念 打印报告: 所有的命令显示出来: 以下的操作分别是创建创建文件夹,删除文件夹,显示文件夹,可见删除文件夹只能够使用-rmr . 从本地拷贝文件到h ...
- js中addEventListener第三个参数涉及到的事件捕获与冒泡
js中,我们可以给一个dom对象添加监听事件,函数就是 addEventListener("click",function(){},true); 很容易理解,第一个参数是事件类型, ...
- Jdk1.6 JUC源码解析(12)-ArrayBlockingQueue
功能简介: ArrayBlockingQueue是一种基于数组实现的有界的阻塞队列.队列中的元素遵循先入先出(FIFO)的规则.新元素插入到队列的尾部,从队列头部取出元素. 和普通队列有所不同,该队列 ...
- NancyFx 2.0的开源框架的使用-HosingOwin
Nancy框架的Owin使用 先建一个空的Web项目 然后往Nuget库里面添加Nancy包 Nancy Nancy.Owin Nancy.ViewEnglines.Spark 然后添加Models, ...
- Android 应用内多语言切换
最近公司的 App 里需要用到多语言切换,简单来说,就是如果用户没有选择语言选项时,App 默认跟随系统语言,如果用户在 App 内进行了语言设置,那么就使用用户设置的语言.当然,你会发现,App 的 ...
- 【JavaScript制作页面时常用的五个特效,你用到了哪个?】
常用的五个特效的相关知识点见附录(五道例题后有附录哦~): 例一: 1.在某页面中有一个图片和五个超链接,如下图所示: 单击不同的数字超链接显示不同的图片: 图1 图片幻灯片显示效果 提示: (1)默 ...
- Combine Two Tables
Table: Person +-------------+---------+ | Column Name | Type | +-------------+---------+ | PersonId ...