TA的每日心情 | 擦汗 2014-2-12 10:49 |
---|
签到天数: 150 天 连续签到: 1 天 [LV.7]常住居民III
|
基于FPGA的IIR滤波器 by方阳
1.说明
这是之前EDA做的综合大实验,拿出来和大家分享分享!
先说一下,此篇文章是基于你有IIR滤波器的原理和FPGA语言(也就是Verilog HDL)基础上的!至于IIR滤波器的原理和Verilog HDL语言,我这里就不说了,网上有一大堆的资料可以观看,IIR可以看数字信号处理的书或直接百度,Verilog HDL推荐《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 [9:0]ADC_DATA;
- wire DATA_Valid;
- wire [10:0]CtrlWord;
- wire signed[15:0] din;
- wire signed[15:0] dout;
-
- TLV1544_CTRL TLV1544_CTRL0(
- .Clk(Clk),
- .Rst_n(Rst_n),
-
- .Do_Conv(1'b1), //开始转换使能信号
- .AD_DONE(AD_DONE), //转换完成信号
- .ADC_CHSEL(4'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(1'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 [3:0]ADC_CHSEL; //通道选择
-
- output reg [9:0]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 = 1'b1;
-
- reg [7:0] LSM_CNT;//序列计数器
- reg [9:0] rADC_DATA;
-
- always@(posedge Clk or negedge Rst_n)
- if(!Rst_n)
- LSM_CNT <= 8'd0;
- else if(LSM_CNT <204 && (TLV1544_EOC == 1'b1) && (Do_Conv || LSM_CNT > 8'd0))
- LSM_CNT <= LSM_CNT + 1'b1;
- else if(LSM_CNT < 204 && (TLV1544_EOC == 1'b0))
- LSM_CNT <= LSM_CNT;
- else if(LSM_CNT == 204 && (TLV1544_EOC == 1'b1))
- LSM_CNT <= 8'd0;
-
- always@(posedge Clk or negedge Rst_n)
- if(!Rst_n)begin
- rADC_DATA <= 10'd0;
- TLV1544_SDI <= 1'b0;
- TLV1544_SCLK <= 1'b0;
- TLV1544_NCS <= 1'b1;
- AD_DONE <= 1'b0;
- DATA_Valid <= 1'b0;
- ADC_DATA <= 10'd0;
- end
- else begin
- case(LSM_CNT)
- 0:
- begin
- rADC_DATA <= 10'd0;
- TLV1544_SDI <= 1'b0;
- TLV1544_SCLK <= 1'b0;
- TLV1544_NCS <= 1'b1;
- AD_DONE <= 1'b0;
- end
-
- 1:
- begin
- TLV1544_NCS <= 1'b0;
- TLV1544_SDI <= ADC_CHSEL[3];
- end
-
- 9:
- begin
- TLV1544_SCLK <= 1'b1;
- rADC_DATA[9] <= TLV1544_SDO;
- end
-
- 19:
- begin
- TLV1544_SDI <= ADC_CHSEL[2];
- TLV1544_SCLK <= 1'b0;
- end
-
- 29:
- begin
- TLV1544_SCLK <= 1'b1;
- rADC_DATA[8] <= TLV1544_SDO;
- end
-
- 39:
- begin
- TLV1544_SDI <= ADC_CHSEL[1];
- TLV1544_SCLK <= 1'b0;
- end
-
- 49:
- begin
- TLV1544_SCLK <= 1'b1;
- rADC_DATA[7] <= TLV1544_SDO;
- end
-
- 59:
- begin
- TLV1544_SDI <= ADC_CHSEL[0];
- TLV1544_SCLK <= 1'b0;
- end
-
- 69:
- begin
- TLV1544_SCLK <= 1'b1;
- rADC_DATA[6] <= TLV1544_SDO;
- end
-
- 79:TLV1544_SCLK <= 1'b0;
-
- 89:
- begin
- TLV1544_SCLK <= 1'b1;
- rADC_DATA[5] <= TLV1544_SDO;
- end
- 99:TLV1544_SCLK <= 1'b0;
-
- 109:
- begin
- TLV1544_SCLK <= 1'b1;
- rADC_DATA[4] <= TLV1544_SDO;
- end
-
- 119:TLV1544_SCLK <= 1'b0;
-
- 129:
- begin
- TLV1544_SCLK <= 1'b1;
- rADC_DATA[3] <= TLV1544_SDO;
- end
-
- 139:TLV1544_SCLK <= 1'b0;
-
- 149:
- begin
- TLV1544_SCLK <= 1'b1;
- rADC_DATA[2] <= TLV1544_SDO;
- end
-
- 159:TLV1544_SCLK <= 1'b0;
-
- 169:
- begin
- TLV1544_SCLK <= 1'b1;
- rADC_DATA[1] <= TLV1544_SDO;
- end
-
- 179:TLV1544_SCLK <= 1'b0;
-
- 189:
- begin
- TLV1544_SCLK <= 1'b1;
- //rADC_DATA[0] <= TLV1544_SDO;
- if(TLV1544_EOC)
- DATA_Valid <= 1'b1;
- else
- DATA_Valid <= 1'b0;
- ADC_DATA <= {rADC_DATA[9:1],TLV1544_SDO};
- end
-
- 199:
- begin
- TLV1544_SCLK <= 1'b0;
- TLV1544_NCS <= 1'b1;
- end
-
- 204:AD_DONE <= 1'b1;
-
- default:DATA_Valid <= 1'b0;
- endcase
- end
- endmodule
复制代码 2.3 ADC转filter模块
ADC_to_filter.V- module ADC_to_filter (
- ADC_DATA,
- din
- );
- input [9:0]ADC_DATA;
- output signed[15:0]din;
- assign din = ADC_DATA<<6;
- endmodule
复制代码 2.4 myiir模块
myiir.V- module myiir(
- rst,
- clk,
- din,
- dout,
- din_valid,
- dout_valid,
- );
- input rst;
- input clk;
- input signed[15:0] din;
- input din_valid;
- output reg signed[15:0] dout;
- output reg dout_valid;
- 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
复制代码 2.5 filter转DAC模块
filter_to_DAC.V- module filter_to_DAC
- (
- dout,
- CtrlWord
- );
- input signed[15:0] dout;
- output [10:0]CtrlWord;
- assign CtrlWord[7:0]=dout[7:0];
- assign CtrlWord[10:8]=3'b0;
- endmodule
复制代码 2.6 TLC5620驱动
TLC5620_CTRL.V2.7 myiir_first_step模块
myiir_first_step.V2.8 myiir_second_step模块
myiir_second_step.V2.9 myiir_third_step模块
myiir_third_step.V2.10 myiir_fourth_step模块
myiir_fourth_step.V2.11 myiir_fifth_step模块
myiir_fifth_step.V2.12 myiir_sixth_step模块
myiir_sixth_step.V代码到这里终于结束了!辛苦观看。。
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
|
|