verilog实现1024点FFT算法

1、算法原理参考:
https://blog.csdn.net/qq_36854651/article/details/104834563

2、matlab仿真程序如下:


function y=fft_func (x)
%本程序对输入序列 x实现DIT-FFT基2算法,点数取大于等于x长度的2的幂次
% x=randn(1,2^4);

m=nextpow2 (length(x)); %进行补零操作,满足2的整数幂----nextpow2(7)=3,
N=2 ^m;         %求x的长度对应的2的最低幂次m,对应多少点的FFT

if length(x) <N
    x=[x, zeros(1, N-length(x))] ;%若x的长度不是2的幂,补零到2的整数幂.
end
nxd=bin2dec (fliplr (dec2bin((1:N)-1,m)))+1;    %求1:2^m数列的倒序
%bin2dec将二进制转换为10进制   flip1r倒叙排列   dec2bin把一个十进制数转换成一个字符串形式的二进制数
y=x(nxd) ;          %将x倒序排列作为y的初始值,这样我们输出的数值和蝶形运算的数值相对应。

for mm=1 :m         %将DFT作m次基2分解,从左到右,对每次分解作DFT运算——把DFT分成log2N段来实现
    Nmr= 2 ^mm;     %这里是旋转因子中的N    
    u=1;            %初始化WN0=1
    WN=exp (-1i*2*pi/Nmr) ;     %本次分解的基本DFT因子WN=exp (-i*2*pi/ Nmr)
    for j=1 :Nmr/2              %本次跨越间隔内的各次蝶形运算
        for k=j :Nmr :N         %本次蝶形运算的跨越间隔为Nmr=2 ^mm
            kp=k+Nmr/2;         %确定蝶形运算的对应单元下标.
            t=y (kp) *u;        %蝶形运算的乘积项
            y (kp)=y(k) -t;     %蝶形运算的加法项
            y(k)=y(k) +t;       %蝶形运算的加法项
        end
        u=u*WN;                 %修改旋转因子,多乘一个基本DFT因子WN
    end
end
%% 生产FPGA仿真数据
input =  tx.*2^10;
output  = Gen_TxT(input(1:1:end));
function output = Gen_TxT(input)
N = length(input);
input = round(input);
%% real
fid=fopen('data_real.txt','w');
for k=1:N
fprintf(fid,'%d \n',real(input(k)));
end
fclose(fid)
%% imag
fid=fopen('data_imag.txt','w');
for k=1:N
fprintf(fid,'%d \n',imag(input(k)));
end
fclose(fid)
%%
output = N;
end

3、verilog实现1024点FFT,tb文件

//
 
// Created:
 
`resetall
`timescale 1ns/10ps
module FFT_1024_tb ;
  
  reg         clk;
  reg rst;
  wire  [31:0] data_in;
  reg  [15:0] data_in_a,data_in_b;
  wire [31:0] data_out;
  integer i;

 reg dinen;
 reg [15:0] din_r0,din_i0;
 
   
  wire [15:0] dout_r0,dout_i0;
  wire [9:0]dout_addr;
  
 FFT_1024_top FFT_1024(
  .clk(clk),
  .rst_n (~rst),
  .din_en   (dinen),
  .din_real (din_r0),
  .din_imag (din_i0),
  //output
  .dout_addr (),
  .dout_real (),
  .dout_imag (),  
  .dout_en   (),
  .abs_fft   (), 
  .dout_start()
  );
 
  	parameter clk_period = 10 ;             //clk period
  
  
  initial begin 
  	clk=0; 
    forever  # (clk_period/2) clk = ~clk;
  	end

	initial begin
	rst = 1;  
	# (clk_period*4) rst = 1'b0;		
	end

 
	initial begin
	dinen = 0;  
	   # (clk_period*10) dinen = 1'b1;		
	  // # (clk_period*1024) dinen = 1'b0;		
	end
 
///////////read////////////
	integer r1,r2,i1,i2;
	integer f_din_I0,f_din_Q0;
 
	  initial begin	
		   f_din_I0   =  $fopen("data_real.txt","r");
		   f_din_Q0   =  $fopen("data_imag.txt","r");	   
		end 
		
		always@(posedge clk) 
		begin
			if(rst )begin
              din_r0 <= 0;
		      din_i0 <= 0;		      		
		end
			else if( dinen) begin
					r1 =$fscanf(f_din_I0,"%d",(din_r0));		
					r2 =$fscanf(f_din_Q0,"%d",(din_i0));
		 			
				end	
			else begin
          din_r0 <= 0;
		      din_i0 <= 0;			      		
		end
		 
		end	
 
  endmodule
   

4、modelsim仿真结果(matlab产生多个频点正弦信号导入到modelsim仿真FFT算法)
在这里插入图片描述5、如需代码可私信,代码FFT功能完整。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MRHLT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值