上文基2FFT的算法推導(dǎo)及python仿真推導(dǎo)了基2FFT的公式,并通過(guò)python做了算法驗(yàn)證,本文使用verilog實(shí)現(xiàn)8點(diǎn)基2FFT的代碼。
根據(jù)算法推導(dǎo),8點(diǎn)FFT的verilog代碼整體結(jié)構(gòu)為:
verilog代碼實(shí)現(xiàn)首先進(jìn)行2點(diǎn)FFT的實(shí)現(xiàn),代碼主要做D0+D1操作和(D0+D1)*W02操作,代碼及操作內(nèi)容如下:
// ============================================================
// File Name: cm_fft2_N2
// VERSION : V1.0
// DATA : 2023/1/1
// Author : FPGA干貨分享
// ============================================================
// 功能:基2FFT N=2的數(shù)據(jù)處理
// delay : 2clk
// ============================================================
`timescale 1ns/100ps
module cm_fft2_N2 #(
parameter C_DATA_WITH = 16 )
(
input wire I_sys_clk , /// 工作時(shí)鐘 100M
input wire I_data_start , /// 數(shù)據(jù)開(kāi)始進(jìn)入標(biāo)志,與第一個(gè)數(shù)據(jù)對(duì)齊輸入
input wire [C_DATA_WITH-1:0] I_data_in_real , /// 數(shù)據(jù)輸入,從start開(kāi)始連續(xù)輸入
input wire [C_DATA_WITH-1:0] I_data_in_imag , /// 數(shù)據(jù)輸入,從start開(kāi)始連續(xù)輸入
output reg O_data_start , /// 數(shù)據(jù)開(kāi)始輸出標(biāo)志與第一個(gè)數(shù)據(jù)對(duì)齊輸出
output reg [C_DATA_WITH:0] O_data_out_real , /// 數(shù)據(jù)輸出,從start開(kāi)始連續(xù)輸出
output reg [C_DATA_WITH:0] O_data_out_imag /// 數(shù)據(jù)輸出,從start開(kāi)始連續(xù)輸出
);
// ============================================================
// 內(nèi)部參數(shù)
// ============================================================
/// W02=1
// ============================================================
// 變量
// ============================================================
reg S_data_start ;
reg [C_DATA_WITH-1:0] S_data_in_real_d1 ;
reg [C_DATA_WITH-1:0] S_data_in_real_d2 ;
reg [C_DATA_WITH-1:0] S_data_in_imag_d1 ;
reg [C_DATA_WITH-1:0] S_data_in_imag_d2 ;
// ============================================================
// main code
// ============================================================
always @(posedge I_sys_clk)
begin
S_data_start <= I_data_start ;
O_data_start <= S_data_start ;
end
/// 緩存第一個(gè)數(shù)
always @(posedge I_sys_clk)
begin
S_data_in_real_d1 <= I_data_in_real ;
S_data_in_real_d2 <= S_data_in_real_d1 ;
S_data_in_imag_d1 <= I_data_in_imag ;
S_data_in_imag_d2 <= S_data_in_imag_d1 ;
end
always @(posedge I_sys_clk)
if(S_data_start)
/// x(n)+x(n+N/2)
begin
O_data_out_real <= {S_data_in_real_d1[C_DATA_WITH-1],S_data_in_real_d1} + {I_data_in_real[C_DATA_WITH-1],I_data_in_real} ;
O_data_out_imag <= {S_data_in_imag_d1[C_DATA_WITH-1],S_data_in_imag_d1} + {I_data_in_imag[C_DATA_WITH-1],I_data_in_imag} ;
end
else if(O_data_start)
/// [x(n)-x(n+N/2)]C_W02
begin
O_data_out_real <= {S_data_in_real_d2[C_DATA_WITH-1],S_data_in_real_d2} - {S_data_in_real_d1[C_DATA_WITH-1],S_data_in_real_d1} ;
O_data_out_imag <= {S_data_in_imag_d2[C_DATA_WITH-1],S_data_in_imag_d2} - {S_data_in_imag_d1[C_DATA_WITH-1],S_data_in_imag_d1} ;
end
else
begin
O_data_out_real <= 'd0;
O_data_out_imag <= 'd0;
end
endmodule