FPGA實現OFDM通信——FFT與IFFT(2)——調用HLS的FFT庫實現N點FFT(hls:fft)

在HLS中用C語言實現8192點FFT,經過測試,實驗結果正確,但是時序約束不到100M的時鐘,應該是設計上的延時之類的比較大,暫時放棄這個方案,調用HLS中自帶的FFT庫(hls:fft)hls_fft.h。實際上,在HLS中調用該庫實現FFT,其實是Vivado中的那個FFT覈實現的,但是HLS中的配置和給定輸入輸出數據比較方便,並且對其外部封裝其他類型的總線接口非常容易。

1.hls_fft.h初探

在HLS中打開示例例程 fft_single ,注意以下幾點:
(1)默認設定
【1】輸入數據和輸出數據的格式固定,必須採用16位定點複數數據,其中1bit表示整數,其他的表示小數部分,即輸入數據範圍 —1 ~ 1,輸出也是 —1 ~ 1;

【2】結構類型爲流水線型;

【3】默認點數1024點,當不是這個點數時,除了修改頭文件的點數,還需要修改config裏的參數才能重新配置IP核;

【4】默認輸入輸出16位定點,相位因子16位,如果需要改成浮點數輸入輸出,需要更改相位因子爲24或25位,並且在config裏面更改IP核的配置;

【5】HLS中的FFT的IP庫只處理複數類型complex的FFT數據。

【6】Xilinx FFT IP塊只對複數類型數據進行操作。儘管可以對把所有虛部都設爲0的複數進行FFT,但是通過預處理數據可以更有效地執行FFT。

【7】HLS需要bit-reverse命令數據塊後端,所說的自然順序和一個O (N)轉換適用於FFT輸出提取的頻譜數據N-point真實數據集。注意,第一個輸出兩包第0個和512(純粹的)分別輸出頻譜數據的實部和虛部。

【8】設計是完全流水線,流設計高吞吐量;用於數據的連續處理,但具有節流功能(如果輸入停止,則停止)。

【9】AXI4-Stream接口用於連接IP Integrator (IPI)中的所有塊。

(2)在testbench中自己給輸入信號進行測試,先給定一個正弦信號,注意下面的賦值,在2016.2版本是可以直接給複數的實部和虛部賦值的,但是2018.2這種方式會報錯,需要採用下面的賦值函數來給一個複數賦值,參見https://blog.csdn.net/DengFengLai123/article/details/101943417。
在這裏插入圖片描述
(3)scale放縮因子的設定
如果不設置放縮因子,輸入上述 —1 ~ 1的正弦信號後,輸出結果應該爲
在這裏插入圖片描述
可以看到,最大值在x[100]處,虛部已經到-503級別,不符合輸出數據的要求,在此過程中,需要對數據按照FFT的級數縮放,如下圖所示,示例中設置1024點的FFT的放縮因子爲0X2AB,即 10 10 10 10 11,按照每2bit合在一起,即爲 2 2 2 2 3,依次相加爲(2+2+2+2+3)=11,放縮倍數爲2^11=2048。參見:https://www.baidu.com/link?url=PlYmOqDBUyN7J56y8xZx0T8dxT_VMxrz_UUF5WQ7PkW6nsWR7zO3IhIsuEIpPG_iGyL53Em0H4iLQA2Krcjf6wSoAvqE-N_W0o078ZEdJ-y&wd=&eqid=f83fa7820049982b000000035d9b3a1b
在這裏插入圖片描述
具體scale的設置詳見PG109,翻譯過來就是:
對於突發I/O架構,每個階段的擴展調度由最低位的兩個LSBs指定,第一個階段的擴展調度由兩個最低位LSBs指定。縮放可以指定爲3、2、1或0,表示要移位的數目。例如:
【1】對於N =1024, Radix-4突發I/O是[1 0 2 3 2](從最後一級開始排序)
【2】對於N =128, x-2突發I/O或Radix-2 Lite Burst I/O,一種可能的擴展計劃是[1 1 1 1 1 0 1 2] (從最後階段到第一階段排序)。
對於流水線並行I/O架構示例默認使用流水線型),每個Radix-2階段(從兩個LSBs開始)都使用兩位指定伸縮因子。例如:
【4】N = 256的縮放調度可以是[2 2 2 3]。當N不是4的冪時,最後階段的最大位增長爲1位。例如,[0 2 2 2]或[1 2 2 2 2]對於N = 512是有效的擴展調度,但是[2 2 2 2 2]是無效的。對於這個轉換長度,SCALE_SCH的最高位的兩個MSB只能是00或01。此字段僅適用於按比例縮放的算術(不包括未縮放unscaled、塊浮點或單精度float)。
在這裏插入圖片描述

2.更改配置

(1)改成8192點FFT(2^13)
【1】更改最大支持點數FFT_NFFT_MAX=13,這時候FFT_LENGTH也隨之改變,效果爲該FFT支持最大8192點(當設置爲最大支持8192點時,4096/256等比8192小的點數也是支持的),並且本次運行點數時8192點。
在這裏插入圖片描述
【2】修改config配置信息,將修改的點數寫進fft的配置,如果沒有110行的修改,那麼實際上還是執行的1024點的FFT。
在這裏插入圖片描述
【3】修改放縮因子爲0XAAB(8192點FFT,縮小8192倍,一般多少點設置多少倍,然後看overflow信號是否指示數據溢出,若溢出,則繼續增大縮放因子)
在這裏插入圖片描述
此後點擊運行,得到的結構範圍在 —1 ~ 1之間,將所有數據*8192,得到正常的數據,但是,因爲前面的放縮實在每一級上的累計放縮,所以存在較大的誤差累積,通過和C語言double型正常未放縮執行的代碼對比,發現在輸出數據較小的地方誤差非常大,基本可以看成是錯的,在數據較大的地方,比如本例的100Hz的sin信號,在輸出xk_output[100] 處與實際結果誤差很小。

3.更改輸入輸出爲float型,提高精度

對於單精度浮點型輸入,輸入數據時N維複數向量(雙32位浮點數),相位因子必須是24或者25位的定點數(PG109文檔)。
在這裏插入圖片描述
在這裏插入圖片描述

4.結果

(1)輸入
在這裏插入圖片描述
輸出數據
在這裏插入圖片描述

C語言的輸出
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章