FIR滤波器仿真--基于Quartus II的FIR Compiler II IP核的脚本仿真
来源:互联网 发布:淘宝水印美图秀秀教程 编辑:程序博客网 时间:2024/05/29 08:13
FIR滤波器仿真
--基于Quartus II的FIR Compiler II IP核的脚本仿真
数字滤波器有更高的精度,更高的信噪比,更高的可靠性。最近和小伙伴探讨了一番FIR滤波器的相关知识,一起把FIR滤波器仿真了一下。总结加深印象,分享交流~
使用工具
实现过程
第一步 仿真并生成滤波器的系数
使用MATLAB里面的FDATOOL工具箱设计滤波器
1,设置滤波器参数响应类型选择低通滤波器;采用窗函数设计滤波器,在窗函数里面选择海明窗,也可以选择其它的窗函数,窗函数的特性不想赘述;滤波器阶数设为31阶,阶数越高占用资源越多,但是会有32个抽头系数,这要联系滤波器的传输函数;采样频率设为10MHz,截止频率设为200KHz,因为滤波器的输入数据是用dds生成的2路正弦波频率分别为100KHz和1MHz的叠加波形。
输入信号通过滤波器, 1MHz的波形被滤除,保留了100KHz的波形,截止频率设为200KHz并不是绝对的,只要满足要求即可,观察图1中的频率响应得100KHz:-0.58dB,1MHz:-46dB。
2,量化滤波器系数(图1左下小框)Set quantization parameters-->Fixed-point-->16bit量化
如果设计好滤波器之后直接导出系数的话,系数的精度比较高,所以会以科学计数法的形式来表示,但是FIR Compiler II IP核不能识别科学计数法,但是修改起来又比较麻烦,所以可以在导出系数之前对系数进行一次量化,这样导出的系数就方便多了。由图可见,16bit的量化对频率响应几乎没什么影响。
3,导出系数File-->Export,就把系数导入到MATLAB的工作区,再把这些系数复制粘贴到一个TXT文件中,OK
图1 MATLAB仿真滤波器
第二步 生成FIR Compiler II IP核
Quartus II-->Tools-->MegaWizard Plug-In Manager-->DSP-->Filters-->FIR Compiler II v13.11,设置IP核参数:滤波器类型Filter Type:Single Rate,系数位宽Coefficient Bit Width:12bit,输入位宽Input Bit Width:8bit,时钟频率Clock Frequency:50MHz,输入采样率:Input Sample Rate:10MSPS,其它默认设置
2,导入TXT系数文件,可看到相应的频率相应。
图2 FIR Compiler II IP核参数设置
第三步 编写设计文件和测试文件
设计文件里面共有三个模块,一个是顶层模块,例化子模块,相互联系;一个是dds模块,产生两路正弦波100KHz和1MHz的相加波形,作为滤波器的输入,还有一个是FIR模块,例化FIR IP核,产生10MHz的采样脉冲给ast_sink_valid信号,在脉冲有效的时候将滤波器的数据取出。
强调一下ast_sink_valid这个信号,表示数据有效,只有为高时,滤波器才会工作。给一个10MHz的采样脉冲,也就是1/(10M)=100ns工作一次,对应了IP核设置时的10MSPS。而且要在脉冲为高的时候再把滤波器的数据取出,之前没考虑好这个地方,所以滤出来的数据一直是杂乱的。顶层模块
module fir_top(inputwiresclk, //50MHzinputwirerst_n, //复位低有效outputwire [24:0]lpf_data//滤波输出数据);//DDS例化wire [7:0]dds_data;dds dds_inst(.sclk(sclk),.rst_n(rst_n),.o_wave(dds_data));//FIR例化fir_IPfir_IP_inst(.sclk(sclk),.rst_n(rst_n),.dds_data(dds_data),.lpf_data(lpf_data));endmodule
FIR模块
module fir_IP(inputwiresclk,inputwirerst_n,inputwire[7:0]dds_data,outputreg[24:0]lpf_data);reg[2:0]cnt;regfs_pulse;//10MHz的脉冲always @ (posedge sclk or negedge rst_n)beginif(rst_n == 1'b0)cnt <= 3'd0;else if(cnt == 3'd4)cnt <= 3'd0;elsecnt <= cnt + 1'b1;endalways @ (posedge sclk or negedge rst_n)beginif(rst_n == 1'b0)fs_pulse <= 1'b0;else if(cnt == 3'd4)fs_pulse <= 1'b1;elsefs_pulse <= 1'b0;end//FIR IP核例化wire[24:0]lpf_datar;wirelpf_valid;wire[1:0]lpf_error;fir_lpf fir_lpf_inst(.clk(sclk),//IP核内部工作时钟.reset_n(rst_n),//复位,低有效.ast_sink_data(dds_data),//输入数据.ast_sink_valid(fs_pulse),//采样脉冲.ast_sink_error(2'd0),//输入错误,使其无效.ast_source_data(lpf_datar),//输出数据.ast_source_valid(lpf_valid),//输出有效.ast_source_error(lpf_error)//输出错误);always @ (posedge sclk or negedge rst_n)beginif(fs_pulse == 1'b1)lpf_data <= lpf_datar;//在valid信号有效的时候才输出数据endendmodule
dds模块
module dds(inputwiresclk,//50MHzinputwirerst_n,outputwire [7:0]o_wave);parameterFRQ_W1 = 32'd8589935;//100KparameterFRQ_W2 = 32'd85899346;//1Mreg[31:0]phase_sum1,phase_sum2;wire [7:0]addr1,addr2;wire[7:0]o_wave1,o_wave2;wire[8:0]wave_plus;//产生2路信号的地址always @(posedge sclk or negedge rst_n)beginif(rst_n == 1'b0)phase_sum1 <= 32'd0;else phase_sum1 <= phase_sum1 + FRQ_W1;endassign addr1 = phase_sum1[31:24];always @(posedge sclk or negedge rst_n)beginif(rst_n==1'b0)phase_sum2 <= 32'd0;else phase_sum2 <= phase_sum2 + FRQ_W2;endassign addr2 = phase_sum2[31:24];//2路波形相加输出assignwave_plus = {o_wave1[7],o_wave1} + {o_wave2[7],o_wave2};assigno_wave = wave_plus[8:1];//相加结果寄存器是9位,取高8位作为输出结果//调用2次RAM取数据ram_8x256_spram_8x256_sp_inst1(.address( addr1 ),.clock( sclk ),.data( 8'd0 ),.wren( 1'b0 ),.q( o_wave1 ));ram_8x256_spram_8x256_sp_inst2(.address ( addr2 ),.clock( sclk ),.data( 8'd0 ),.wren( 1'b0 ),.q( o_wave2 ));endmodule
testbench测试文件
`timescale 1ns/1nsmodule tb_fir();reg sclk,rst_n;wire [24:0]lpf_data;initial beginsclk = 0;rst_n = 0;#200rst_n = 1;endalways #10 sclk <= ~sclk;//例化顶层模块fir_top fir_top_inst(.sclk(sclk),.rst_n(rst_n),.lpf_data(lpf_data));endmodule第四步 编写测试脚本并仿真生成FIR Compiler II IP核的时候会附带生成一个sim的文件夹,里面有两个tcl脚本,在这两个脚本的基础上编写我们的测试脚本。脚本的编写参考了尤老师的课程,有兴趣的旁友可以去看看。脚本里面的路径需要修改(Line39)。
测试脚本
quit-sim.mainclear# Create compilation librariesproc ensure_lib { lib } { if ![file isdirectory $lib] { vlib $lib } }ensure_lib ./libraries/ ensure_lib ./libraries/work/vmap work ./libraries/work/vmap work_lib ./libraries/work/if ![ string match "*ModelSim ALTERA*" [ vsim -version ] ] { ensure_lib ./libraries/altera_ver/ vmap altera_ver ./libraries/altera_ver/ ensure_lib ./libraries/lpm_ver/ vmap lpm_ver ./libraries/lpm_ver/ ensure_lib ./libraries/sgate_ver/ vmap sgate_ver ./libraries/sgate_ver/ ensure_lib ./libraries/altera_mf_ver/ vmap altera_mf_ver ./libraries/altera_mf_ver/ ensure_lib ./libraries/altera_lnsim_ver/ vmap altera_lnsim_ver ./libraries/altera_lnsim_ver/ ensure_lib ./libraries/cycloneive_ver/ vmap cycloneive_ver ./libraries/cycloneive_ver/ ensure_lib ./libraries/altera/ vmap altera ./libraries/altera/ ensure_lib ./libraries/lpm/ vmap lpm ./libraries/lpm/ ensure_lib ./libraries/sgate/ vmap sgate ./libraries/sgate/ ensure_lib ./libraries/altera_mf/ vmap altera_mf ./libraries/altera_mf/ ensure_lib ./libraries/altera_lnsim/ vmap altera_lnsim ./libraries/altera_lnsim/ ensure_lib ./libraries/cycloneive/ vmap cycloneive ./libraries/cycloneive/ }if ![info exists QUARTUS_INSTALL_DIR] { set QUARTUS_INSTALL_DIR "D:/altera/13.1/quartus/"}if ![ string match "*ModelSim ALTERA*" [ vsim -version ] ] { vlog "$QUARTUS_INSTALL_DIR/eda/sim_lib/altera_primitives.v" -work altera_ver vlog "$QUARTUS_INSTALL_DIR/eda/sim_lib/220model.v" -work lpm_ver vlog "$QUARTUS_INSTALL_DIR/eda/sim_lib/sgate.v" -work sgate_ver vlog "$QUARTUS_INSTALL_DIR/eda/sim_lib/altera_mf.v" -work altera_mf_ver vlog -sv "$QUARTUS_INSTALL_DIR/eda/sim_lib/mentor/altera_lnsim_for_vhdl.sv" -work altera_lnsim_ver vlog "$QUARTUS_INSTALL_DIR/eda/sim_lib/cycloneive_atoms.v" -work cycloneive_ver vcom "$QUARTUS_INSTALL_DIR/eda/sim_lib/altera_syn_attributes.vhd" -work altera vcom "$QUARTUS_INSTALL_DIR/eda/sim_lib/altera_standard_functions.vhd" -work altera vcom "$QUARTUS_INSTALL_DIR/eda/sim_lib/alt_dspbuilder_package.vhd" -work altera vcom "$QUARTUS_INSTALL_DIR/eda/sim_lib/altera_europa_support_lib.vhd" -work altera vcom "$QUARTUS_INSTALL_DIR/eda/sim_lib/altera_primitives_components.vhd" -work altera vcom "$QUARTUS_INSTALL_DIR/eda/sim_lib/altera_primitives.vhd" -work altera vcom "$QUARTUS_INSTALL_DIR/eda/sim_lib/220pack.vhd" -work lpm vcom "$QUARTUS_INSTALL_DIR/eda/sim_lib/220model.vhd" -work lpm vcom "$QUARTUS_INSTALL_DIR/eda/sim_lib/sgate_pack.vhd" -work sgate vcom "$QUARTUS_INSTALL_DIR/eda/sim_lib/sgate.vhd" -work sgate vcom "$QUARTUS_INSTALL_DIR/eda/sim_lib/altera_mf_components.vhd" -work altera_mf vcom "$QUARTUS_INSTALL_DIR/eda/sim_lib/altera_mf.vhd" -work altera_mf vcom "$QUARTUS_INSTALL_DIR/eda/sim_lib/altera_lnsim_components.vhd" -work altera_lnsim vcom "$QUARTUS_INSTALL_DIR/eda/sim_lib/cycloneive_atoms.vhd" -work cycloneive vcom "$QUARTUS_INSTALL_DIR/eda/sim_lib/cycloneive_components.vhd" -work cycloneive }#以上的文件格式基本固定,不用多管vlog./tb_fir.vvlog./../design/*.vvlog./../quartus_prj/ipcore_dir/ram_8x256_sp/*.vvlog./../quartus_prj/ipcore_dir/fir_lpf/*.vvlog./../quartus_prj/ipcore_dir/fir_lpf/fir_lpf/*.v#vhdl文件的编译有顺序,不同的工程只是最后 3 个vhdl文件名需要更改vcom ./../quartus_prj/ipcore_dir/fir_lpf/fir_lpf/auk_dspip_math_pkg_hpfir.vhd vcom ./../quartus_prj/ipcore_dir/fir_lpf/fir_lpf/auk_dspip_lib_pkg_hpfir.vhd vcom ./../quartus_prj/ipcore_dir/fir_lpf/fir_lpf/auk_dspip_avalon_streaming_controller_hpfir.vhdvcom ./../quartus_prj/ipcore_dir/fir_lpf/fir_lpf/auk_dspip_avalon_streaming_sink_hpfir.vhd vcom ./../quartus_prj/ipcore_dir/fir_lpf/fir_lpf/auk_dspip_avalon_streaming_source_hpfir.vhd vcom ./../quartus_prj/ipcore_dir/fir_lpf/fir_lpf/auk_dspip_roundsat_hpfir.vhd vcom ./../quartus_prj/ipcore_dir/fir_lpf/fir_lpf/dspba_library_package.vhd vcom ./../quartus_prj/ipcore_dir/fir_lpf/fir_lpf/dspba_library.vhdvcom ./../quartus_prj/ipcore_dir/fir_lpf/fir_lpf/fir_lpf_0002_rtl.vhd vcom ./../quartus_prj/ipcore_dir/fir_lpf/fir_lpf/fir_lpf_0002_ast.vhdvcom ./../quartus_prj/ipcore_dir/fir_lpf/fir_lpf/fir_lpf_0002.vhd#链接库文件,编译vsim-voptargs=+acc -L work -L work_lib -L altera_ver -L lpm_ver -L sgate_ver -L altera_mf_ver -L altera_lnsim_ver -L cycloneive_ver -L altera -L lpm -L sgate -L altera_mf -L altera_lnsim -L cycloneive work.tb_fir#添加需要仿真的波形addwavetb_fir/fir_top_inst/sclkaddwavetb_fir/fir_top_inst/rst_naddwavetb_fir/fir_top_inst/fir_IP_inst/fir_lpf_inst/ast_sink_validaddwavetb_fir/fir_top_inst/fir_IP_inst/fir_lpf_inst/ast_source_validaddwave-format analog -height 100 -max 127 -min -128 tb_fir/fir_top_inst/dds_dataaddwave tb_fir/fir_top_inst/lpf_datarun100us
从测试脚本可以看出,这种方法的仿真比较繁琐,ModelSim编译库的时间也比较长,所以打算下一篇学习总结一下联合仿真的大致方法。
- FIR滤波器仿真--基于Quartus II的FIR Compiler II IP核的脚本仿真
- FIR滤波器仿真----基于Quartus II的FIR II IP核与ModelSim-Altera的联合仿真
- 基于Quartus II 和MATLAB 的FIR滤波器设计与仿真(一)
- 基于Quartus II和MATLAB的FIR滤波器设计与仿真(二)
- 基于Simulink的FIR滤波器设计与仿真--初识matlab
- Quartus II和Modelsim的联合仿真
- FPGA与MATLAB联合仿真FIR滤波器
- 基于DSP的FIR滤波器的设计
- 基于DSP的FIR滤波器的设计
- FIR滤波器的实现
- 二相并行FIR滤波器的matlab及使用FIR IP 核的FPGA实现
- 基于java的滤波器设计(FIR)
- quartus ii 和 modelsim 编译仿真的流程
- Quartus II和Modelsim的联合仿真(详细)
- Modelsim与Quartus ii联合仿真的一些问题
- Quartus II和Modelsim的联合仿真(详细)
- Quartus II和Modelsim的联合仿真(详细)
- Quartus II 调用ModelSim 仿真
- 第一课、课程简介
- error和exception区别
- 331. Verify Preorder Serialization of a Binary Tree
- linux学习之旅(八)&& 系统控制systemd
- 强制类型转换
- FIR滤波器仿真--基于Quartus II的FIR Compiler II IP核的脚本仿真
- Po_python_lesson3_list和tuple的区别_2017/7/23
- 110. Balanced Binary Tree
- FTP主动模式与FTP被动模式所需的端口
- There is no Action mapped for namespace [/] and action name [] associated with context p
- cv::Mat and Halcon
- 两个关于操作系统空间使用100%的案例分享
- mac air装linux双系统
- Printer Queue