基于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,由时钟分频电路 ...
随机推荐
- mysql sql语句
1.数据库和表的操作 创建 create修改 alter删除 drop查看 show 1.1创建数据库 CREATE DATABASE [IF NOT EXISTS] db_name [crea ...
- [转载]PHP检测一个元素是否存在于数组中
- hdu1541 Stars 树状数组
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1541 题目大意就是统计其左上位置的星星的个数 由于y已经按升序排列,因此只用按照x坐标生成一维树状数组 ...
- Unite'17 Shanghai再一次问候
Unite'17 Shanghai再一次问候 --暨Unity2017年度大会 2017年5月11日,主题为"再一次问候"的Unity年度盛会在上海国际会议中心举行,这是Unity ...
- Springmvc+mybatis+restful+bootstrap框架整合
框架整合: Springmvc + Mybatis + Shiro(权限) + REST(服务) + WebService(服务) + JMS(消息) + Lucene(搜搜引擎) + Quartz( ...
- js事件中的event对象
addEvent(oDiv,"click",function(event){ console.log(event.bubbles+"事件是否冒泡"); cons ...
- 开涛spring3(6.3) - AOP 之 6.3 基于Schema的AOP
6.3 基于Schema的AOP 基于Schema的AOP从Spring2.0之后通过“aop”命名空间来定义切面.切入点及声明通知. 在Spring配置文件中,所以AOP相关定义必须放在<a ...
- python利用selenium和safari浏览器驱动实现新浪微博自动点赞 Demo
import time from selenium import webdriver browser = webdriver.Safari() browser.get('http://weibo.co ...
- TCP--telnet为何在127s后返回?
背景 近期编写了监控业务服务器的脚本,主要原理是用shell脚本(运行shell的机器称之为监控机)调用项目组专用的接口测试工具,对指定的业务服务器进行业务操作,根据接口测试工具的返回结果判断业务服务 ...
- YII缓存依赖的应用
YII缓存依赖的应用 缓存 缓存依赖 Yii 缓存是提升Web应用性能的简便有效的方式.当我们在加载网页需要过多的时间,比如说查询时间过久,抑或是调用接口占用过多I/O,建立缓存是一个行之有效的方法, ...