fir ip使用流程
使用matlab工具,根据具体需求设计出滤波器系数; 打开fir ip导入滤波器系数即可;
滤波器系数的生成
- 打开matlab使用fdatool工具,填入相应的参数生成系数;
Fs=250; Fpass=50; Fstop=70; Apass=0.01; Astop=80; - 将滤波器系数设置为定点数输出;
- 导出滤波器系数,生成coe文件;
Fir ip核介绍
Select source:选择为coe文件; Coefficient File:选择matlab生成的系数文件; Filter Type:选择single rate单速率的滤波器; 其余的默认选择即可。 Input Sampling Frequency:选择输入的采样频率为250MHz; Clock Frequency:时钟频率设置为250MHz Coefficinet options:选择为有符号系数,数据位宽为16bit; Data path options:输入数据16bit有符号数据,输出选择全刻度输出; 参数默认即可; 选择低电平复位即可;
Matlab生成仿真数据
clc;
clear all;
close all;
addpath('../../matlab_lib');
fs=250;
len=8192;
t=0:1/fs:(len-1)/fs;
fc1=10;
fc2=90;
sig_dat1=cos(2*pi*fc1*t);
sig_dat2=cos(2*pi*fc2*t);
sig_dat1=awgn(sig_dat1,60);
sig_dat2=awgn(sig_dat2,60);
sig_dat=sig_dat1+sig_dat2;
[f,fft_data]=data_fft(sig_dat',fs);
plot(f,fft_data);
sig_dat=round(sig_dat*2^15*0.45);
sig_dat=sign2com(sig_dat',16);
fp=fopen('sim_dat.bin','w');
fprintf(fp,'%04x\n',sig_dat);
fclose all;
Verilog fir设计
1.fir ip接口代码设计
module fir(
input i_clk ,
input i_rst ,
input i_din_vld ,
input [15:0] i_din ,
output reg o_dout_vld ,
output reg [15:0] o_dout
);
wire [39:0] m_axis_data_tdata ;
wire m_axis_data_tvalid ;
fir_ip u_fir_ip (
.aresetn (~i_rst ),
.aclk (i_clk ),
.s_axis_data_tvalid (i_din_vld ),
.s_axis_data_tready ( ),
.s_axis_data_tdata (i_din ),
.m_axis_data_tvalid (m_axis_data_tvalid ),
.m_axis_data_tdata (m_axis_data_tdata )
);
always@(posedge i_clk)begin
if(i_rst)begin
o_dout_vld <=0;
o_dout <=0;
end
else begin
o_dout_vld <=m_axis_data_tvalid;
o_dout <=m_axis_data_tdata[32:17];
end
end
endmodule
Verilog fir顶层设计
module fir_top(
input clk_250m ,
input rst_250m ,
input din_vld ,
input [15:0] din ,
output dout_vld ,
output [15:0] dout
);
fir u_fir(
.i_clk (clk_250m ),
.i_rst (rst_250m ),
.i_din_vld (din_vld ),
.i_din (din ),
.o_dout_vld (dout_vld ),
.o_dout (dout )
);
endmodule
Verilog testbench编写
`timescale 1ns/1ps
module testbench();
reg clk_250m ;
reg rst_250m ;
reg din_vld ;
reg [15:0] din ;
wire dout_vld ;
wire [15:0] dout ;
fir_top u_fir_top(
.clk_250m (clk_250m ),
.rst_250m (rst_250m ),
.din_vld (din_vld ),
.din (din ),
.dout_vld (dout_vld ),
.dout (dout )
);
always #2.000 clk_250m=~clk_250m ;
initial begin
clk_250m=0;
rst_250m=1;
#200;
rst_250m=0;
end
localparam LEN = 8192 ;
reg [15:0] sim_dat_buf[LEN-1:0];
reg [15:0] dat_cnt ;
integer fp ;
initial begin
$readmemh("../matlab/sim_dat.bin", sim_dat_buf, 0, LEN-1);
fp=$fopen("../matlab/sim_dat_out.bin", "w");
end
always@(posedge clk_250m)begin
if(rst_250m)begin
dat_cnt <=0;
din_vld <=0;
din <=0;
end
else begin
if(dat_cnt<LEN-1)begin
dat_cnt <=dat_cnt+1;
din_vld <=1;
din <=sim_dat_buf[dat_cnt];
end
else begin
dat_cnt <=0;
din_vld <=0;
end
end
end
reg [11:0] delay_cnt ;
reg [11:0] write_cnt ;
always@(posedge clk_250m)begin
if(rst_250m)begin
delay_cnt <=0;
write_cnt <=0;
end
else begin
if(delay_cnt<100)begin
delay_cnt <=delay_cnt+1;
end
else begin
if(write_cnt<4096)begin
$fwrite(fp,"%d\n",$signed(dout));
write_cnt<=write_cnt+1;
end
else begin
$fclose(fp);
end
end
end
end
endmodule
仿真结果
完整的工程和仿真文件工程下载
|