基4FFT 1024 fpga(verilog)实现

这篇具有很好参考价值的文章主要介绍了基4FFT 1024 fpga(verilog)实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

文章目录

    • 概要
    • 整体结果
    • 模块设计
    • 细节实现
    • 小结

概要

对于基4fft算法,计算原理无需多说,可以看看知网论文,或者数字信号处理的书籍,本次基4fft按照AXI4-stream总线协议方式,当握手时开始产生传送数据流

整体结构

本次采用的方法是使用状态机实现:(1)S0状态:初始状态.(2)S1状态:开始传送数据,(S2):开始将RAM1的数据读出,进行蝶形运算到RAM2中.(S3)将RAM2数据读出进行蝶形运算到RAM2中.(S4):等待握手从RAM2读出结果,此时RAM1可以接受新的数据,当读完并且存完时,进入状态S2,开始新一轮计算。(当开始接受数据到开始接受下一组数据的间隔大约为3600左右时钟)

模块设计

  • 蝶形运算:输入三个旋转因子可四个数据进行蝶形计算,在第三个时钟出结果,采用流水线形式,用的是*作为乘法。
module butter
    (
     input                       aclk,
     input                       rstn,
     input                       en,
	 input signed  [15:0] 		 w_i_k,
	 input signed  [15:0] 		 w_q_k,
	 input signed  [15:0] 		 w_i_2k,
	 input signed  [15:0] 		 w_q_2k,
	 input signed  [15:0] 		 w_i_3k,
	 input signed  [15:0] 		 w_q_3k,
	 
	 
	 
     input [63:0]   			 data_a,data_b,data_c,data_d,
	 output[63:0] 				 q_a,q_b,q_c,q_d,
	 output valid	
   );
	
	wire signed [31:0] w_i_k_Re,w_i_k_Im,w_i_2k_Re,w_i_2k_Im,w_i_3k_Re,w_i_3k_Im;
	wire signed [31:0] interA_Re,interA_Im,interB_Re,interB_Im,interC_Re,interC_Im,interD_Re,interD_Im;

	
	
	assign interA_Re = data_a[31:0];
	assign interA_Im = data_a[63:32];
	
	assign interB_Re = data_b[31:0];
	assign interB_Im = data_b[63:32];	
	
	assign interC_Re = data_c[31:0];
	assign interC_Im = data_c[63:32];
	
	assign interD_Re = data_d[31:0];
	assign interD_Im = data_d[63:32];
    
	assign w_i_k_Re={{16{w_i_k[15]}},w_i_k};
    assign w_i_k_Im={{16{w_q_k[15]}},w_q_k};

	assign w_i_2k_Re={{16{w_i_2k[15]}},w_i_2k};
    assign w_i_2k_Im={{16{w_q_2k[15]}},w_q_2k};
	
	assign w_i_3k_Re={{16{w_i_3k[15]}},w_i_3k};
    assign w_i_3k_Im={{16{w_q_3k[15]}},w_q_3k};


    reg		[3:0]	en_r ;
    always @(posedge aclk or negedge rstn) begin
        if (!rstn) 
		begin
            en_r   <= 'b0 ;
        end
        else 
        begin
            en_r   <= {en_r[3:0], en} ;
        end
        

    end

	reg signed [63:0] xa_re;
	reg signed [63:0] xa_im;
	
    reg signed [63:0] xb_wnr_real0;
    reg signed [63:0] xb_wnr_real1;
	reg signed [63:0] xb_wnr_imag0;
    reg signed [63:0] xb_wnr_imag1;
	
    reg signed [63:0] xc_wnr_real0;
    reg signed [63:0] xc_wnr_real1;
	reg signed [63:0] xc_wnr_imag0;
    reg signed [63:0] xc_wnr_imag1;  

	reg signed [63:0] xd_wnr_real0;
    reg signed [63:0] xd_wnr_real1;
	reg signed [63:0] xd_wnr_imag0;
    reg signed [63:0] xd_wnr_imag1;
	

	
	
	
    always @(posedge aclk or negedge rstn) begin
        if (!rstn) begin
		
			xa_re		 <= 'b0;
			xa_im		 <= 'b0;
            xb_wnr_real0 <= 'b0;
            xb_wnr_real1 <= 'b0;
            xb_wnr_imag0 <= 'b0;
            xb_wnr_imag1 <= 'b0;
             
            xc_wnr_real0 <= 'b0;
			xc_wnr_real1 <= 'b0;
            xc_wnr_imag0 <= 'b0;
            xc_wnr_imag1 <= 'b0;
          
            xd_wnr_real0 <= 'b0;
            xd_wnr_real1 <= 'b0;
			xd_wnr_imag0 <= 'b0;	
			xd_wnr_imag1 <= 'b0;
						
        end
        else if (en) begin
		
			xa_re		 <= {{18{interA_Re[31]}},interA_Re,14'd0};
			xa_im		 <= {{18{interA_Im[31]}},interA_Im,14'd0};
			
            xb_wnr_real0 <= interB_Re * w_i_k_Re;
            xb_wnr_real1 <= interB_Im * w_i_k_Im;
            xb_wnr_imag0 <= interB_Re * w_i_k_Im;
            xb_wnr_imag1 <= interB_Im * w_i_k_Re;
             
            xc_wnr_real0 <= interC_Re * w_i_2k_Re;
			xc_wnr_real1 <= interC_Im * w_i_2k_Im;
            xc_wnr_imag0 <= interC_Re * w_i_2k_Im;
            xc_wnr_imag1 <= interC_Im * w_i_2k_Re;
          
            xd_wnr_real0 <= interD_Re * w_i_3k_Re;
            xd_wnr_real1 <= interD_Im * w_i_3k_Im;
			xd_wnr_imag0 <= interD_Re * w_i_3k_Im;	
			xd_wnr_imag1 <= interD_Im * w_i_3k_Re;
        end
		else
		begin
			xa_re		 <= 'b0;
            xa_im		 <= 'b0;
			
			xb_wnr_real0 <= 'b0;
            xb_wnr_real1 <= 'b0;
            xb_wnr_imag0 <= 'b0;
            xb_wnr_imag1 <= 'b0;
             
            xc_wnr_real0 <= 'b0;
			xc_wnr_real1 <= 'b0;
            xc_wnr_imag0 <= 'b0;
            xc_wnr_imag1 <= 'b0;
          
            xd_wnr_real0 <= 'b0;
            xd_wnr_real1 <= 'b0;
			xd_wnr_imag0 <= 'b0;	
			xd_wnr_imag1 <= 'b0;
        end
			
    end

    reg signed [63:0] xA_re1;
    reg signed [63:0] xA_im1;
	
    reg signed [63:0] xB_re1;
    reg signed [63:0] xB_im1;	
				
    reg signed [63:0] xC_re1;
    reg signed [63:0] xC_im1;
				
    reg signed [63:0] xD_re1;
    reg signed [63:0] xD_im1;

 
    always @(posedge aclk or negedge rstn) begin
        if (!rstn) begin
            xA_re1    <= 'b0;
            xA_im1    <= 'b0;
		            
			xB_re1	  <= 'b0;
			xB_im1	  <= 'b0;
	
            xC_re1    <= 'b0;
			xC_im1	  <= 'b0;
				         
			xD_re1   <= 'b0;
			xD_im1   <= 'b0;
	
	   
				
        end
        else if (en_r[0]) begin
            xA_re1    <=(xa_re + xb_wnr_real0 - xb_wnr_real1);
            xA_im1    <=(xa_im + xb_wnr_imag0 + xb_wnr_imag1);
            
			xB_re1	  <= (xa_re - xb_wnr_real0 + xb_wnr_real1);
			xB_im1	  <= (xa_im - xb_wnr_imag0 - xb_wnr_imag1);
						
            xC_re1    <= (xc_wnr_real0 - xc_wnr_real1 +  xd_wnr_real0 - xd_wnr_real1);
			xC_im1	  <= (xc_wnr_imag0 + xc_wnr_imag1 +  xd_wnr_imag0 + xd_wnr_imag1); 
						 
			xD_re1	  <= (xc_wnr_imag0 + xc_wnr_imag1 - xd_wnr_imag0 - xd_wnr_imag1); 			 
			xD_im1    <= (xd_wnr_real0 - xd_wnr_real1 - xc_wnr_real0 + xc_wnr_real1);
																					
		
		
		end
		else
			begin
            xA_re1    <= 'b0;
            xA_im1    <= 'b0;
		            
			xB_re1	  <= 'b0;
			xB_im1	  <= 'b0;
	
            xC_re1    <= 'b0;
			xC_im1	  <= 'b0;
				         
			xD_re1	  <= 'b0;
			xD_im1    <= 'b0;
				
			
        end
		
    end


    reg signed [64:0] xA_re;
    reg signed [64:0] xA_im;
				
				
    reg signed [64:0] xB_re;
    reg signed [64:0] xB_im;	
				
    reg signed [64:0] xC_re;
    reg signed [64:0] xC_im;
				
    reg signed [64:0] xD_re;
    reg signed [64:0] xD_im;

	
	
    always @(posedge aclk or negedge rstn) begin
        if (!rstn) begin
            xA_re <= 'b0;
            xA_im <= 'b0;
                  
                  
			xB_re <= 'b0;	
			xB_im <= 'b0;
			
			
			xC_re <= 'b0;
			xC_im <= 'b0;
			
			
			xD_re <= 'b0;
			xD_im <= 'b0;
			
			
        end
        else if (en_r[1]) begin
            xA_re      <=(xA_re1 + xC_re1)>>>14;
            xA_im      <=(xA_im1 + xC_im1)>>>14;
			xB_re      <=(xB_re1 + xD_re1)>>>14;
            xB_im      <=(xB_im1 + xD_im1)>>>14;
			xC_re      <=(xA_re1 - xC_re1)>>>14;
            xC_im      <=(xA_im1 - xC_im1)>>>14;
			xD_re      <=(xB_re1 - xD_re1)>>>14;
            xD_im      <=(xB_im1 - xD_im1)>>>14;
			
        end
		else
		begin
            xA_re <= 'b0;
            xA_im <= 'b0;
                  
                  
			xB_re <= 'b0;
			xB_im <= 'b0;
			
			
			xC_re <= 'b0;
			xC_im <= 'b0;
			
			
			xD_re <= 'b0;
			xD_im <= 'b0;
			
			
        end
    end

    assign valid   = en_r[2] ;
	assign q_a = {xA_im[63],xA_im[30:0],xA_re[63],xA_re[30:0]};
	assign q_b = {xB_im[63],xB_im[30:0],xB_re[63],xB_re[30:0]};
	assign q_c = {xC_im[63],xC_im[30:0],xC_re[63],xC_re[30:0]};
	assign q_d = {xD_im[63],xD_im[30:0],xD_re[63],xD_re[30:0]};
                                                       


endmodule
  • 地址产生模块

第一个模块是存储数据的地址产生模块,需要进行码位倒序

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/06/06 17:03:00
// Design Name: 
// Module Name: addr_rever
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module addr_rever(
	input aclk,rstn,en,
	output done,
	output wire [9:0] re_addr
);
	reg [9:0] addr;
	
	
	always @(posedge aclk or negedge rstn)
	begin
		if (rstn == 1'b0)
		begin
			addr <= 10'd0;	
		end
		else if(addr == 10'd1023)
		begin
			addr <= 10'd0;	
		end
		else if(en)
		begin
			addr <= addr+10'd1;	
		end
		else
		begin
			addr <= addr;
		end
	end	
		
		
		
		
	
	
	

assign done = (addr==10'd1023)? 1:0;


assign re_addr = {addr[0],addr[1],addr[2],addr[3],addr[4],addr[5],addr[6],addr[7],addr[8],addr[9]};

endmodule

第二个模块进行蝶形运算读取RAM的地址。按照每一级进行产生(stage),在出数据地址时也会产生对于的旋转因子地址。

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/06/05 21:07:42
// Design Name: 
// Module Name: addr_gen
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module addr_gen(
	input 				aclk	,
	input 				rstn	,
	input 				en		,
	input		[3:0] 	stage	,
	output 				valid	,
	output 				done	,
	output wire [9:0] 	out1	,
	output wire [9:0] 	out2	,
	output wire [9:0] 	w_1k	,	
	output wire [9:0]	w_2k
    );
	
reg		[10:0] 		cnt			;
reg 	[10:0] 		count		;
wire 	[10:0] 		groups		;
wire 	[10:0] 		p			;
wire 	[10:0] 		count_buf	;
wire 	[10:0] 		p1			;
wire 	[10:0] 		p2			;
wire 	[10:0] 		p3			;
reg  				cls			;
reg 				clk_2		;
reg 				flag		;
reg     [9:0]		counter  	;	//记录
wire    			par2ser_en	;



assign count_buf = en ? 1 << (2 *(stage - 1)) : 0;	
assign groups = en ? 10'd1 << (10 - 2*stage) : 0;	
assign p = en ? count_buf << 2 :0 ; 
assign p1 = 10'd1 << (2*stage - 2);
assign p2 = 10'd2 << (2*stage - 2);
assign p3 = 10'd3 << (2*stage - 2);

//			1/2分频
always @(posedge aclk or negedge rstn)	
	if(rstn == 1'd0)
		clk_2 <= 0;
	else if(en)
		clk_2 <= clk_2 + 1'b1;
	else
		clk_2 <= 0;
			
always @(posedge aclk or negedge rstn)	//256
	if(rstn == 1'd0)
		flag <= 0;
	else if(en)
		begin
		if(clk_2 == 0)
			flag <=  1'b1;
		else
			flag <=  0;
		end
	else
		flag <= 0;		
		

always @(posedge aclk or negedge rstn)	//256
	if(rstn == 1'd0)
		counter <= 0;
	else if(counter == 10'd514)
		counter <= 0;	
	else if(en)
		counter <= counter + 1'b1;
	else
		counter <= 0;
		
		
//	地址产生	
//always @(posedge aclk or negedge rstn)	//256
//	if(rstn == 1'd0)
//		cnt <= 0;
//	else if((cnt == groups-1'b1) & (clk_2 ==1'b1) & flag)
//		cnt <= 0;
//	else if(en)
//		begin
//		if((count == count_buf-1'b1) & flag)
//			cnt <= cnt + 1'b1;
//		else
//			cnt <= cnt;
//		end
//	else 
//		cnt <= 0;
	
		
always @(posedge aclk or negedge rstn)	//1
	if(rstn == 1'd0)
		count <= 0;
	else if((count == count_buf-1'b1) & flag)
		count <= 0;
	else if(en)
		if(flag)
			count <= count + 1'b1;
		else
			count <= count;
	else 
		count <= 0;		
			
	
//数据地址产生	
reg 	[9:0] 		addr		;	
reg 	[9:0] 		addr_1		;
reg 	[9:0] 		addr_2		;
reg 	[9:0] 		addr_3		;
reg 	[9:0] 		addr_4		;	
wire 	[9:0] 		addr_A		;
wire 	[9:0] 		addr_B		;
wire 	[9:0] 		addr_C		;
wire 	[9:0] 		addr_D		;
			
wire 	[9:0] 		out_1		;
wire 	[9:0] 		out_2		;


//旋转因子地址产生	
reg 	[9:0] 		w_addr		;			
reg 	[9:0] 		addr_1k		;		
reg 	[9:0] 		addr_2k		;		
reg 	[9:0] 		addr_3k		;	
wire 	[9:0] 		addr_w_1k	;	
wire 	[9:0] 		addr_w_2k	;	
wire 	[9:0] 		addr_w_3k	;	
wire 	[9:0] 		w1			;	
wire 	[9:0] 		w2			;	
	


	
always @(posedge aclk or negedge rstn)	
	if(rstn == 1'd0)
		addr <= 0;
	else if(en)
		begin
		if((count == count_buf-1'b1) & (addr == 11'd1024) & flag)
			addr <=  0;
		else if((count == count_buf-1'b1) & flag)
			addr <= addr + p;
		end
	else
		addr <= 0;
			
				
always @(posedge aclk or negedge rstn)	
	if(rstn == 1'd0)
		begin
		addr_1 <= 0;		
	    addr_2 <= 0;
	    addr_3 <= 0;
	    addr_4 <= 0;
		end
	else if(en)
		if(flag)
		begin
		addr_1 <= addr + count;		
	    addr_2 <= addr + count + p1;
	    addr_3 <= addr + count + p2;
	    addr_4 <= addr + count + p3;
		end
		else
		begin
		addr_1 <= addr_1;
	    addr_2 <= addr_2;
	    addr_3 <= addr_3;
	    addr_4 <= addr_4;			
		end
	
	else
		begin
		addr_1 <= 0;		
	    addr_2 <= 0;
	    addr_3 <= 0;
	    addr_4 <= 0;
		end

assign addr_A = en ? addr_1 : 0;
assign addr_B = en ? addr_2 : 0;
assign addr_C = en ? addr_3 : 0;
assign addr_D = en ? addr_4 : 0;		

par2ser inst1(
	.data_a(addr_A)		,
	.data_b(addr_B)		,
	.data_c(addr_C)		,
	.data_d(addr_D)		,
	.en(par2ser_en)		,
	.aclk(aclk)			,
	.rstn(rstn)			,
	.out_1(out_1)		,
	.out_2(out_2)
);

assign out1 = en ? out_1 : 0; 	
assign out2 = en ? out_2 : 0; 	
	
always @(posedge aclk or negedge rstn)	//1
	if(rstn == 1'd0)
		w_addr <= 0;
	else if(en)	
		begin
		if(stage == 1)
			w_addr <= 0;
		else if((count == count_buf - 1'b1) & flag) 
			w_addr <= 0;
		else if(flag)
			w_addr <= w_addr + groups;
		else
			w_addr <= w_addr;
		end
	else
			w_addr <= 0;
	
//旋转因子地址产生	
always @(posedge aclk or negedge rstn)	//1
	if(rstn == 1'd0)
		begin
		addr_1k <= 0;
		addr_2k <= 0;
		addr_3k <= 0;
		end
	else if(en)
		if(flag)
		begin
		addr_1k <= w_addr << 1'b1;
		addr_2k <= w_addr;
		addr_3k <= w_addr * 3'd3;
		end
		else
		begin
		addr_1k <= addr_1k;
		addr_2k <= addr_2k;
		addr_3k <= addr_3k;
		end
	else	
		begin
		addr_1k <= 0;
		addr_2k <= 0;
		addr_3k <= 0;		
		end
			
assign addr_w_1k = addr_1k;	
assign addr_w_2k = addr_2k;	
assign addr_w_3k = addr_3k;
	
par2ser inst2(
	.data_a(10'd0)			,
	.data_b(addr_w_1k)	,
	.data_c(addr_w_2k)	,
	.data_d(addr_w_3k)	,
	.en(par2ser_en)		,
	.aclk(aclk)			,
	.rstn(rstn)			,
	.out_1(w1)			,	
	.out_2(w2)
	);	
assign par2ser_en = (counter > 10'd1) ? 1:0;
assign w_1k = w1;	
assign w_2k = w2;	
assign valid = (counter > 10'd2) 	? 1 : 0; 	
assign done  = (counter == 10'd514) ? 1 : 0; 	
endmodule
`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/06/12 15:33:28
// Design Name: 
// Module Name: par2ser
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module par2ser(
	input [9:0] data_a,
	input [9:0] data_b,
	input [9:0] data_c,
	input [9:0] data_d,
	input 		en,
	input aclk,
	input rstn,
    output [9:0] out_1,
    output [9:0] out_2
	);
reg [9:0] cach1;
reg [9:0] cach2;
reg [9:0] data_out1;
reg [9:0] data_out2;
reg cnt;
always @(posedge aclk or negedge rstn)
	if(rstn == 1'b0)
		begin
			data_out1 <= 0;
			data_out2 <= 0;
		end
	else if(en)
		if(cnt == 1'b1)
		begin
			data_out1 <= cach1;
			data_out2 <= cach2;
		end
		else if(cnt == 0)
		begin
			data_out1 <= data_a;
			data_out2 <= data_b;	
		end
	else
		begin
			data_out1 <= 0;
			data_out2 <= 0;
		end
		
always @(posedge aclk or negedge rstn)
	if(rstn == 1'b0)
		begin
			cach1 <= 0;
			cach2 <= 0;
		end
	else if(en)
		begin
			cach1 <= data_c;
			cach2 <= data_d;
		end
	else
		begin
			cach1 <= 0;
			cach2 <= 0;
		end
		
always @(posedge aclk or negedge rstn)
	if(rstn == 1'b0)
		begin
			cnt <= 0;
		end
	else if(en)
		begin
			cnt <= cnt + 1'b1;
		end
	else
		begin
			cnt <= 0;
		end
assign 	out_1 = data_out1;		
assign 	out_2 = data_out2;		
endmodule
	

这里本来是可以出4个并行地址,但是我采用两个双口RAM来相互存储,一次只能读取两个数据,所以我的地址产生模块需要两个两个的出,即两个时钟RAM才会读出四个数据出来。

  • ROM旋转因子表

        首先本次没有采用cordic算法求取旋转因子的值,可以先用Python生成使用下面这个函数,这里采用的14bit的放大.

def generate_rotation_factors():
    with open("rom.v",'w') as f:
        for i in range(1024):
            angle = -2 * math.pi * i / 1024
            cos_val = round(math.cos(angle) * (2**14))
            sin_val = round(math.sin(angle) * (2**14))
            if(cos_val<0):
                cos_val = cos_val + 2**16
            if(sin_val<0):
                sin_val = sin_val + 2**16
            # print("10'd{}:begin  w_rom_i <= 16'h{:04X} ; w_rom_q <= 16'h{:04X}; end".format(i,cos_val, sin_val))
            f.write("10'd{}:begin  w_rom_i <= 16'h{:04X} ; w_rom_q <= 16'h{:04X}; end\n".format(i,cos_val, sin_val))

        rom.v可以写成case语句对应每个地址比如:

基4fft,verilog,python,开发语言,fpga开发

  • 顶层主控模块:控制各个信号,和各个模块的使能信号:
  • 基4fft,verilog,python,开发语言,fpga开发

         输入的数据低16位是实部高16位是虚部,也就是说最高支持16位的有符号数-32767 -- +32767,输出是高32位是虚部,第32位是实部.

细节实现

  • 地址产生块仿真:符合倒序 0 512 256  ...基4fft,verilog,python,开发语言,fpga开发

假设输入的级数是第二级stage=2仿真结果如下:当valid信号拉高表示开始产生旋转因子的地址和ram的地址基4fft,verilog,python,开发语言,fpga开发

  • 顶层模块仿真,仿真了4种波形,分别是方波,三角波,斜坡函数和sign函数,将仿真的数据存入txt文件中,在与python的fft包进行对比结果如下:

基4fft,verilog,python,开发语言,fpga开发

 当master和slave握手时开始进行数据传送,并且测试了接受端和发生端在握手时的信号突然拉低的突发情况,对第一组结果放大:基4fft,verilog,python,开发语言,fpga开发

 可知输入的数据前523都是200,其余为0,得到的仿真结果为基4fft,verilog,python,开发语言,fpga开发

  • 将的得到的结果使用python包的fft进行对比:基4fft,verilog,python,开发语言,fpga开发 方波:
  • 基4fft,verilog,python,开发语言,fpga开发

 

 局部放大:

基4fft,verilog,python,开发语言,fpga开发

 三角波:基4fft,verilog,python,开发语言,fpga开发

 局部放大:

基4fft,verilog,python,开发语言,fpga开发

 斜坡:

基4fft,verilog,python,开发语言,fpga开发

 局部放大:

基4fft,verilog,python,开发语言,fpga开发

sign:

基4fft,verilog,python,开发语言,fpga开发

 局部放大:

 基4fft,verilog,python,开发语言,fpga开发

 综合:仿真完成后进行综合:基4fft,verilog,python,开发语言,fpga开发

小结

我将把我的这个完整的工程文件放入我的资源中包含各个文件的仿真文件,和python的的对比理论值的文件,如果你有什么问题,或者有改进的地方欢迎讨论文章来源地址https://www.toymoban.com/news/detail-754159.html

到了这里,关于基4FFT 1024 fpga(verilog)实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • FPGA实现对锯齿波的FFT分析

    由信号与系统知识: 任意一个周期函数的傅里叶级数构造出来的三角函数展开式形式为:  其中2pi/T是原始信号的角频率,因为n1,可见分量的角频率必然不小于原始信号的频率,是原始信号频率的整数倍。所以这里的n不是索引序号,而是分量的角频率与原始信号角频率的倍

    2024年02月05日
    浏览(42)
  • FPGA:实现快速傅里叶变换(FFT)算法

    第一次使用FPGA实现一个算法,搓手手,于是我拿出一股势在必得的心情打开了FFT的视频教程,看了好几个视频和好些篇博客,于是我迷失在数学公式推导中,在一位前辈的建议下,我开始转换我的思维, 从科研心态转变为先用起来 ,于是我关掉我的推导笔记,找了一篇叫我

    2024年02月03日
    浏览(47)
  • 基于FPGA和Matlab实现的FFT功能验证

    微信公众号上线,搜索公众号 小灰灰的FPGA ,关注可获取相关源码,定期更新有关FPGA的项目以及开源项目源码,包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 一 、FFT设计验证思路 1、基于Matlab与FPGA的混频sin信号的FF

    2024年02月12日
    浏览(35)
  • 基于verilog的四级流水线实现并行fft16(可计算小数和负数)

    目录 夯实基础--FFT算法 定点运算--verilog实现小数运算 Verilog代码实现  FFT系数 W 的准备  输入数值的初始化 蝶形运算端点处的值 仿真结果展示 总结        FFT是DFT的一种快速算法而不是一种新的变换,他可以在数量级的意义上提高运算速度。它主要有两种实现方法:一种是

    2024年02月05日
    浏览(57)
  • Simulink HDL Coder FPGA初级开发实践(五)FFT以及CORDIC算法进行信号相位校正

    前言: 本栏目除特别说明以外,均采用的黑金AX7103开发板,该开发板时钟频率为200M,并且是双端时钟,因此在每个项目中都有一段原语将双端时钟变成200MHz的单端时钟。文章仅作为学习记录,如有不足请在评论区指出,博主不会对各位的问题作出解答,请谅解。博主深知网

    2024年02月06日
    浏览(50)
  • VIVADO中FFT核的使用(FPGA计算FFT和IFFT)

             关于这方面的内容,有些文章已经写的很好很详细了。不过我在使用的过程中,还是踩了一些坑,我在这里详细的介绍了IP核每一个设置的作用,然后写了个fft计算和ifft计算的环路的测试程序。应该可以帮大家学会使用fft的同时,也对它有个较为全面的理解。

    2024年01月18日
    浏览(40)
  • FFT64点傅里叶变换verilog蝶形运算,代码和视频

    名称:FFT64点verilog傅里叶变换 软件:Quartus 语言:Verilog 代码功能:     使用verilog代码实现64点FFT变换,使用蝶形运算实现傅里叶变换 演示视频:http://www.hdlcode.com/index.php?m=homec=Viewa=indexaid=208 FPGA代码资源下载网:hdlcode.com 代码下载: 软件:Quartus 语言:Verilog 代码功能:

    2024年02月08日
    浏览(35)
  • 基于FPGA的FFT图像滤波设计

            FFT滤波就是通过傅里叶运算将图像转换到频域空间,然后在频域中对图像进行处理,最后将处理后的图像通过傅里叶逆运算将图像转会到时域空间。   在频域空间中,我们能够更好的对图像的噪声进行分析,然后找出相关规律将噪声信息去除。    本文重点讲解

    2024年04月17日
    浏览(47)
  • FPGA中FFT IP核应用(二)

    前文主要着重介绍了ise当中的FFT IP核的使用方法,本文将介绍Vivado中的FFT IP核使用方法。并且设计一段仿真代码,进行波形仿真,查看输出结果。 提示:以下是本篇文章正文内容 版本号:Fast Fourier Transform v9.1 Xilinx LogiCORE IP快速傅里叶变换(FFT)核心实现了Cooley-Tukey FFT算法,这

    2024年02月15日
    浏览(45)
  • FPGA中FFT IP核应用(一)

    小编是做通信相关的FPGA工程师,在工作当中必然要用到快速傅里叶变换,那么就有必要讲解一下关于Xilinx器件的FFT IP核用法。首先Xilinx器件经过ise到vivado的软件升级,其对应FFT IP核也相应的升级了,由之前的版本升级为现在的aAXI4总线版本。本文着重介绍AXI4总线版本,也会将

    2024年02月06日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包