在quartus中使用FFT IP核最全教程(从入门到放弃)

 一、准备工作

 

首先需要把需要的器材准备好,我使用的是quartus18.0,并且要使用IP核被破解的版本,不然无法使用其中的FFT和NCO,一定要注意,quartus对于版本非常敏感,一定要严格对应好版本

1、带IP的quartus18.0

2、modelsim,这个modelsim不能使用自己下载的modelsim,要去官网下载,对应版本的modelsim-altera版本,而不是modesim se,应为modelsim-altera版本,是已经将altera上的器件的lib编译好了,如果自己下载modelsim使用,则还要自己编译相应的altera库,非常的坑

 二、IP核导入

1、在quartus的IP库中,导入FFT核和NCO核,并完成设置,具体的设置结果如下:

设置的位置在tool->platform designer

在quartus中使用FFT IP核最全教程(从入门到放弃)_第1张图片

 在quartus中使用FFT IP核最全教程(从入门到放弃)_第2张图片

设置好以后就generate HDL,在这一步中一定要注意,在simulation中选择verilog选项:

在quartus中使用FFT IP核最全教程(从入门到放弃)_第3张图片

 2、然后将两个IP加入到工程中:

Project->add file in Project,

主要加入的是两个文件,后缀为sip和qip的文件,分别在simulation文件夹下和synthesis文件夹下。加入后如下所示:

在quartus中使用FFT IP核最全教程(从入门到放弃)_第4张图片

三、编写代码

1、fft_wrapper.v


module fft_wrapper(clk,in_signal,
	real_power,
	imag_power,
	fft_source_sop,
	sink_sop,
	sink_eop,
	sink_valid,
	reset_n,
	start);	

	input		clk;
	input 	start;
	input		wire [13:0] in_signal;
	wire		[31:0] short_in_signal;
	output	wire [24:0]	real_power;
	output	wire [24:0]	imag_power;
	//fft signal
	
	output	wire 	sink_valid;
	wire		sink_ready;
	
	output	wire sink_sop;
	output	wire sink_eop;
	
	wire 		[10:0]	fft_pts;
	output 	wire fft_source_sop;
	wire   fft_source_eop;
	output 	reg	reset_n;

	
	wire		[13:0]	real_to_fft_p;
	wire		[13:0] 	imag_to_fft_p;
	reg [4:0] count;
	
	reg eop2, sop2, eop5;
	
	
	initial 
	begin
		reset_n = 0;
		count = 5'd0;
	end
	
	always@(posedge clk)
		begin
			count <= count + 1;
			if(count == 10)
				begin
				reset_n = 1;
				end
		end
	
//	always @(posedge clk)
//		begin
//			if(start)
//				begin
//				reset_n <= 0;
//				count <= 5'd0;
//				end
//			else
//				begin
//					count = count + 5'd1;
//					if(count == 5'd10)
//						begin
//							reset_n <= 1;
//						end
//				end
//		end
	
	control_for_fft control_for_fft_longer_inst(
	.clk(clk),
	.insignal(in_signal),
	.sink_valid(sink_valid),
	.sink_ready(sink_ready),
	.sink_error(),
	.sink_sop(sink_sop),
	.sink_eop(sink_eop),
	.inverse(inverse),
	.outreal(real_to_fft_p),
	.outimag(imag_to_fft_p),
	.fft_pts(fft_pts));
	
	
	
	fft fft_inst (
		.clk          (clk),          //    clk.clk
		.reset_n      (reset_n),      //    rst.reset_n
		.sink_valid   (sink_valid),   //   sink.sink_valid
		.sink_ready   (sink_ready),   //       .sink_ready
		.sink_error   (2'b00),   //       .sink_error
		.sink_sop     (sink_sop),     //       .sink_sop
		.sink_eop     (sink_eop),     //       .sink_eop
		.sink_real    (real_to_fft_p),    //       .sink_real
		.sink_imag    (imag_to_fft_p),    //       .sink_imag
		.fftpts_in    (fft_pts),    //       .fftpts_in
		.inverse      (1'b0),      //       .inverse
		.source_valid (), // source.source_valid
		.source_ready (1'b1), //       .source_ready
		.source_error (), //       .source_error
		.source_sop   (fft_source_sop),   //       .source_sop
		.source_eop   (fft_source_eop),   //       .source_eop
		.source_real  (real_power),  //       .source_real
		.source_imag  (imag_power),  //       .source_imag
		.fftpts_out   ()    //       .fftpts_out
	);	
	
	
endmodule

2、control_for_fft.v

module control_for_fft(
	clk,
	insignal,	
	sink_valid,
	sink_ready,
	sink_error,
	sink_sop,
	sink_eop,
	inverse,
	outreal,
	outimag,
	fft_pts);
	
input clk;
input [13:0] insignal;
output reg sink_valid, sink_sop, sink_eop, inverse, sink_ready;
output reg [1:0] sink_error;

output  [13:0] outreal, outimag;
output reg [10:0] fft_pts;
reg [9:0] count;

initial 
begin
	count = 10'd1;
	inverse = 0;
	sink_valid = 0;
	sink_ready = 1;
	sink_error = 2'b00;
	fft_pts = 11'd1024;
end

assign outreal = insignal;
assign outimage = 14'd0;


always @(posedge clk)
	begin
		begin
			count <= count + 1;
		end
		
		if(count == 10'd1024)
			begin
				sink_eop <= 1;
			end
		if(count == 10'd0)
			begin
				sink_eop <= 0;
				sink_sop <= 1;
				sink_valid <= 1;
			end
		if(count == 10'd1)
			begin
				sink_sop <= 0;
			end
	end
	
endmodule

3、fft_test.v

`timescale 1ns / 1ps
module fft_test;



reg clk;
reg start;

wire reset_n;
wire [13:0] fsin_o, fcos_o;

wire sink_sop_sig;
wire sink_eop_sig;
wire [24:0] real_power_sig;

wire [24:0] imag_power_sig;

initial 
begin 
	clk <= 0;
	start <= 0;
	#2 start <= 1;
end

always begin #10 clk <= ~clk; end


	nco nco_inst (
		.clk       (clk),       // clk.clk
		.reset_n   (reset_n),   // rst.reset_n
//		.clken     (clken),		//  in.clken
		.clken     (1'b1),		//  in.clken
//		.phi_inc_i (phi_inc_i), //    .phi_inc_i
		.phi_inc_i (32'd41943040), //    .phi_inc_i
		.fsin_o    (fsin_o),    // out.fsin_o
		.fcos_o    (fcos_o),    //    .fcos_o
		.out_valid (out_valid)  //    .out_valid
	);





fft_wrapper fft_wrapper_inst
(
	.clk(clk),
	//.in_signal(in_signal_sig),
	.in_signal(fsin_o),
	.real_power(real_power_sig),
	.imag_power(imag_power_sig),
	.fft_source_sop(fft_source_sop_sig),
	.sink_sop(sink_sop_sig),
	.sink_eop(sink_eop_sig),
	.sink_valid(sink_valid_sig),
	.reset_n(reset_n),
	.start(start)
);

endmodule

四、仿真

1、综合后,会发现

在quartus中使用FFT IP核最全教程(从入门到放弃)_第5张图片

有错误出现,不用管,直接联合仿真即可。

仿真结果如下:

在quartus中使用FFT IP核最全教程(从入门到放弃)_第6张图片

你可能感兴趣的:(FPGA,verilog)