上文基2FFT的算法推導及python仿真推導了基2FFT的公式,并通過python做了算法驗證,本文使用verilog實現8點基2FFT的代碼。
根據算法推導,8點FFT的verilog代碼整體結構為:
verilog代碼實現首先進行2點FFT的實現,代碼主要做D0+D1操作和(D0+D1)*W02操作,代碼及操作內容如下:
// ============================================================
// File Name: cm_fft2_N2
// VERSION : V1.0
// DATA : 2023/1/1
// Author : FPGA干貨分享
// ============================================================
// 功能:基2FFT N=2的數據處理
// delay : 2clk
// ============================================================
`timescale 1ns/100ps
module cm_fft2_N2 #(
parameter C_DATA_WITH = 16 )
(
input wire I_sys_clk , /// 工作時鐘 100M
input wire I_data_start , /// 數據開始進入標志,與第一個數據對齊輸入
input wire [C_DATA_WITH-1:0] I_data_in_real , /// 數據輸入,從start開始連續輸入
input wire [C_DATA_WITH-1:0] I_data_in_imag , /// 數據輸入,從start開始連續輸入
output reg O_data_start , /// 數據開始輸出標志與第一個數據對齊輸出
output reg [C_DATA_WITH:0] O_data_out_real , /// 數據輸出,從start開始連續輸出
output reg [C_DATA_WITH:0] O_data_out_imag /// 數據輸出,從start開始連續輸出
);
// ============================================================
// 內部參數
// ============================================================
/// 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
/// 緩存第一個數
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