1、NCO及FIR ip核的调用
在使用ip核之前,首先要将IP核进行破解,可以参考上一篇文章:FPGA NCOip核的使用及仿真(quartusii 13.1+modelsimse 10.5)
FPGA NCOip核的使用及仿真(quartusii 13.1+modelsimse 10.5)_机械 zp的博客-CSDN博客
这里使用两个nco ip核来产生两个正弦信号,频率分别设定为1MHz和10MHz:ip_nco,ip_nco10
FIRip核的相关参数设置:
这里的系数设置也可以通过matlab的fdatools工具生成,然后导入系数文件(.txt)
勾选仿真,选择语言:,
生成ip核,接口如下:
2、代码部分
module fir_top(
input sys_clk,
input sys_rst_n,
output signed[9:0] sin1,
output sin1_vld,
output signed[9:0] sin10,
output sin10_vld,
output signed[10:0] add_sin,
output add_vld,
output signed [29:0] fir_out
);
reg signed[10:0] sum_sin ;
wire signed[9:0] sin1_do ;
wire signed[9:0] sin10_do ;
wire out_en ;
wire s_val ;
wire s_err ;
assign sin1 = sin1_do;
assign sin10 = sin10_do;
assign add_sin = sum_sin;
assign add_vld = sin1_vld & sin10_vld;
//信号相加
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)begin
sum_sin <= 10'd0;
end
else begin
if(sin1_vld & sin10_vld)
sum_sin <= sin1 + sin10;
else
sum_sin <= sum_sin;
end
end
ip_nco u_ip_nco
(
.clk ( sys_clk ),
.reset_n ( sys_rst_n ),
.clken ( 1'b1 ),
.phi_inc_i ( 32'd85899346),
.fsin_o ( sin1_do ),
.out_valid ( sin1_vld )
);
ip_nco10 u_ip_nco10
(
.clk ( sys_clk ),
.reset_n ( sys_rst_n ),
.clken ( 1'b1 ),
.phi_inc_i ( 32'd858993459),
.fsin_o ( sin10_do ),
.out_valid ( sin10_vld )
);
ip_fir u_ip_fir
(
.clk ( sys_clk ),
.reset_n ( sys_rst_n ),
.ast_sink_data ( add_sin ),
.ast_sink_valid ( add_vld ),
.ast_sink_error ( 2'b0 ),
.ast_source_ready (1'b1 ),
.ast_source_data ( fir_out ),
.ast_source_valid ( s_val ),
.ast_source_error ( s_err )
);
endmodule
Test benches代码:
`timescale 1ns/1ns
module tb_fir_top();
//输入信号
reg sys_clk ;
reg sys_rst_n ;
//输出信号
wire [9:0] sin1 ;
wire sin1_vld ;
wire [9:0] sin10 ;
wire sin10_vld ;
wire [10:0] add_sin ;
wire add_vld ;
wire [29:0] fir_out ;
//模块例化
fir_top u_fir_top
(
.sys_clk ( sys_clk ),
.sys_rst_n ( sys_rst_n ),
.sin1 ( sin1 ),
.sin1_vld ( sin1_vld ),
.sin10 ( sin10 ),
.sin10_vld ( sin10_vld ),
.add_sin ( add_sin ),
.add_vld ( add_vld ),
.fir_out ( fir_out )
);
//产生时钟
parameter CLK_PRE = 20;
//时钟周期
always #(CLK_PRE/2) sys_clk = ~sys_clk;
integer i;//循环变量
//产生激励
initial begin
sys_clk = 1'b1;
sys_rst_n = 1'b0;
i=0;
#(CLK_PRE*10);
sys_rst_n = 1'b1;
forever begin
#(CLK_PRE);
i=i+1;
if(i==4000)
$stop;
end
end
endmodule
3、仿真
频率显示,右击黄线,勾选显示频率。