N=2^8; %N为采样点数
s_p=0:255;%正弦波一个周期的采样点数
sin_data=sin(2*pi*s_p/N); %200KHz
sin_data1=sin(8*pi*s_p/N); %800KHz
fix_p_sin_data=fix(sin_data*127);
fix_p_sin_data1=fix(sin_data1*127);
fix_p_sin_data2=fix((fix_p_sin_data1+fix_p_sin_data)/2);
for i=1:N
if fix_p_sin_data(i)<0
fix_p_sin_data(i)=N+fix_p_sin_data(i)
else
fix_p_sin_data(i)=fix_p_sin_data(i);
end
end
for i=1:N
if fix_p_sin_data2(i)<0
fix_p_sin_data2(i)=N+fix_p_sin_data2(i)
else
fix_p_sin_data2(i)=fix_p_sin_data2(i);
end
end%下面是mif文件固定格式,不可更改
fid=fopen('800+200KHz.mif','w+');
fprintf(fid,'WIDTH=8;\n');
fprintf(fid,'DEPTH=256;\n');
fprintf(fid,'ADDRESS_RADIX=UNS;\n');
fprintf(fid,'DATA_RADIX=UNS;\n');
fprintf(fid,'CONTENT BEGIN \n');
for i=1:N
fprintf(fid,'%d:%d; \n',i-1,fix_p_sin_data(i));
end
fprintf(fid,'END; \n');
fclose(fid);
打开IP核RAM:1-PORT配置界面
顶层代码
/******************************/
//Project Name : FilterTest
//Email :
//Create Time : 2021/03/16 15:12
//Editor : Liu
//Version : Rev1.0.0
/***********************************************/
`timescale 1 ns/ 1 ps
module filter(
input wire sclk, //50MHz
input wire rst_n, //复位低有效
output wire [15:0] lpf_data//滤波输出数据
);
//DDS例化
wire [7:0] dds_data;
sinx dds_inst(
.sclk (sclk),
.rst_n (rst_n),
.o_wave (dds_data)
);
//FIR例化
fir_IP fir_IP_inst(
.sclk (sclk),
.rst_n (rst_n),
.dds_data (dds_data),
.lpf_data (lpf_data)
);
endmodule
dds输出波形数据
module sinx(
input rst_n,
input sclk,
output signed [7:0] o_wave
);
reg [7:0] addr1;
always @(posedge sclk or negedge rst_n)
if(!rst_n)begin
addr1 <= 1'd0;
end
else begin
addr1 <= addr1 + 2'b1;
end
sp_ram_256x8 sp_ram_256x8_inst(
.address(addr1),
.clock(sclk),
.data(8'd8),
.wren(1'b0),
.q(o_wave)
);
endmodule
FIR信号模块
时钟周期为50MHz,将时钟周期五倍分频得到10MHz采样率即为之前所设采样率,需对应。cnt,fs_pulse两个信号修改采样频率
module fir_IP(
input wire sclk,
input wire rst_n,
input wire [7:0] dds_data,
output reg [15:0] lpf_data
);
reg [5:0] cnt;
reg fs_pulse;//10MHz的脉冲
always @ (posedge sclk or negedge rst_n)
begin
if(!rst_n)
cnt <= 6'd0;
else if(cnt == 6'd4)
cnt <= 6'd0;
else
cnt <= cnt + 1'b1;
end
always @ (posedge sclk or negedge rst_n)
begin
if(!rst_n)
fs_pulse <= 1'b0;
else if(cnt == 6'd4)
fs_pulse <= 1'b1;
else
fs_pulse <= 1'b0;
end
//FIR IP核例化
wire [24:0] lpf_datar;
wire lpf_valid;
wire [1:0] lpf_error;
FirII FirII_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)
begin
if(!rst_n)
lpf_data <= 24'b0;
else if(fs_pulse == 1'b1)
lpf_data <= {lpf_datar[24],lpf_datar[19:5]};//在valid信号有效的时候才输出数据
end
endmodule
testbench
`timescale 1ns/1ns
module tb_fir();
reg sclk,rst_n;
wire [15:0] lpf_data;
wire [7:0] o_wave;
initial begin
sclk = 0;
rst_n = 0;
#100
rst_n = 1;
end
always #10 sclk <= ~sclk;
//例化顶层模块
filter fir_top_inst(
.sclk (sclk),
.rst_n (rst_n),
.lpf_data (lpf_data)
);
sinx dds_inst(
.sclk (sclk),
.rst_n (rst_n),
.o_wave (o_wave)
);
endmodule