邵瑞,付永慶
哈爾濱工程大學 信息與通信工程學院,黑龍江 哈爾濱 150001
短時傅里葉變換作為一種常用的時-頻分析方法,在語音信號、信號識別等方面應用十分廣泛[1-3],其基本思想是在傅里葉變換的基礎上實現時域的局部化。對于時變信號,短時傅里葉變換采用一個滑動窗截取信號,并且認為窗內的信號是平穩的,對這些信號進行傅里葉變換,可以得到信號在某一時刻的頻譜。通常情況下,為了克服窗與窗內數據的關聯性,相鄰兩窗會有所重疊,重疊的長度越長對分析該信號的頻譜越準確。本文設置每次滑動的數據長度為滑動窗長度的1/4。
離散序列信號的短時傅里葉變換的定義為

式中:x(m)為待分析的信號;w(n)為分析窗函數;X(ejω)即為待分析信號每個窗的傅里葉變換。離
n散短時傅里葉變換通過滑動窗截取信號,并對該信號進行離散傅里葉變換,提取出信號的局部頻域信息。
本設計所采用的開發板為Altera 公司提供的Stratix ii-EP2S180C3,使用的軟件環境為Quartus ii 13.0,波形仿真采用了第三方軟件Modelsim,開發板的實物圖如圖1所示。

圖1 Stratix ii-EP2S180C3 開發板
本設計充分利用Altera 公司所提供的IP 核,簡化了以往設計的過程,設計利用ROM 核存儲漢明窗的數據。FIFO 核實現滑動窗。通過使用FFT 核實現傅里葉變換,要根據設計需求進行FFT 核模式的選取,并根據芯片手冊進行FFT 核時序的編寫。利用這些工具可以很方便地實現滑動短時傅里葉變換的功能,不需要推導復雜的數學公式,相對于文獻[4-6]中的復雜數學公式推導更簡潔,更容易使用現有工具進行實現。
設計的前提條件是希望判斷下一段信號在各個窗內頻譜特征,根據頻譜特征可以檢驗信號所含有的頻率成分,用于信號解調,設計總體框圖如圖2 所示。

圖2 滑動短時傅里葉變換的FPGA 設計框圖
設計中為了避免數據堵塞及丟失,應用了乒乓思想[7],使用了4 個相同的FIFO。4 個FIFO 通過輸入數據選擇流單元進行控制,使用FIFO_cnt的計數大小判定當前哪個FIFO 寫入數據。設計中每次滑動窗更新數據長度為90,則當FIFO1_cnt的大小大于90,此時FIFO2 就要準備進行寫入數據;當FIFO2_cnt 的大小大于90,此時FIFO3 就要準備進行寫入數據;當FIFO3_cnt 的大小大于90,此時FIFO4 就要準備進行寫入數據。至此一個循環下,FIFO 的寫使能都打開了。輸出數據流選擇單元也是通過FIFO_cnt 的數據大小來決定當前哪個FIFO 的數據輸出,每個時刻只有一個數據輸出,其FIFO 間的滑動圖如圖3 所示,90、180、270、360 分別代表FIFO 中的4 個地址段。

圖3 滑動窗(FIFO)控制設計
漢寧窗的實現采用了ROM 核,存放漢寧窗[8]函數數據。通過MATLAB 生成360 點Hanning 窗函數系數表,由于該數據為浮點數,而本設計中采用定點化運算,將系數表生成mif 文件,作為ROM 的初始化文件。
FIFO 核和ROM 核的使用中設計一個共同的使能,當FIFO 核有數據讀出時,ROM 核也會有數據讀出,兩者同步輸出:送入乘法器進行加窗計算,輸出數據位寬24 位,送給后端的FFT 模塊進行計算,根據FFT 的輸出有效信號source_valid 的高低指示,進行判斷信號特征,解調信號。
滑動窗使用了異步FIFO[9],FIFO 選擇結構如圖4 所示。其中FIFO 的大小設置的512,數據位寬是16,讀時鐘Rdclk 和寫時鐘Wrclk 的大小相差5 倍,FIFO 的讀寫使能分別為Rdreq、Wrreq,輸出滿標志位Wrfull,空標志位Rdempty。

圖4 異步FIFO 的結構
設計中需要4 個FIFO,4 個FIFO 輪換輸出數據,4 個FIFO 的切換采用了狀態機的思想,狀態機設計了8 種狀態,如圖5 所示。當一個狀態完成之后,再切換到下一個狀態,否則一直處于當前狀態。

圖5 滑動窗的狀態機設計
圖6 為滑動窗口的仿真波形,剛開始時,Fifo1_wreq 的電平為高,FIFO1 開始寫入數據;當寫到第90 個數據時,此時FIFO2 的Fifo2_wreq 置成高電平,FIFO2 開始寫入數據;此時State 同時發生跳轉;當FIFO2 寫數據寫到第90 個時,FIFO3的Fifo3_wreq 被置高電平,FIFO3 開始寫數據;此時state 在此發生了跳轉,數據繼續進行寫入;當FIFO3 寫入數據寫到第90 個數據時,此時FIFO1寫到了第270 個數據,FIFO4 的Fifo4_wreq 被置成高電平,開始寫數據;此時4 個FIFO 的Wreq 都被制成高電平,寫入數據。當FIFO1 再寫進18 個數據時就要開始讀數據,Fifo1_rdreq 變為1,維持讀時鐘的72 個高電平,360 個數據被寫進FIFO1時,同時也讀空了,之后開始新的循環。

圖6 滑動窗口的仿真波形
當FIFO1 在寫進288 個數據時就要開始讀數據,Fifo1_rdreq 變為1,維持讀時鐘的72 個高電平,360 個數據被寫進FIFO1 時,同時也讀空了,此時FIFO1 的讀使能就被關閉;當FIFO2 在寫進288 個數據時,FIFO2 就要開始讀數據,Fifo2_rdreq變為1,維持讀時鐘的72 個高電平,360 個數據被寫進FIFO2 時,同時也讀空了,Fifo2_rdeq 變為0;同理FIFO3、FIFO4。4 個FIFO 輪流輸出數據,每次只有一個讀使能有效。
圖7 為滑動窗模塊的仿真波形,可以看到每個窗相鄰的將有3/4 的數據是重復的,4 個FIFO輪換輸出數據。

圖7 滑動窗口控制仿真波形
Hanning 窗使用了ROM[10],ROM 采用Altera公司提供的IP 核,ROM 中的地址線由于只能為2 的整次數冪,取最貼近碼元寬度的512 作為該ROM 的地址數,數據位寬為A/DC 的輸出數據寬度12,ROM 值在初始化時被賦予了漢寧窗的數據,其結構如圖8 所示。
Hanning 窗數據仿真波形為圖9,在每個時鐘的上升沿數據從ROM 端讀出,其數據波形如圖中的q 所示。
乘法器的結構如圖10 所示。

圖8 ROM 窗結構

圖9 ROM 讀出的數據顯示波形

圖10 乘法器設計的結構圖
輸入端數據Dataa、Datab 分別來自于FIFO 輸出的數據和ROM 窗內的數據,二者相乘之后的結果為24 位,為信號加過窗的數據,數據送給FFT 模塊進行計算。
傅里葉變換[11]部分選擇FFT 核[12],FFT 核可以設置FFT 變換的數據長度、輸入數據精度、運算中旋轉因子數據精度,并提供了4 種運算結構,可以根據板子的運算速度及硬件資源情況進行選擇使用。由于數據是實時采集進來的,所以設計結構中選擇了流模式。流模式的運算分2 個進程:載入數據及輸出數據進程和FFT 變換運算過程,且這2 個進程可以同一時間處理。當FFT 變換啟動時,輸入數據首先在時鐘的控制下輸入信號到FFT 核內部的存儲器內,當一幀數據載入完成后才開始計算,FFT 變換后的數據在FFT 變換完成后再輸出到相應的端口,流模式下的FFT 結構如圖11 所示。

圖11 流模式下的FFT 結構
流模式的時序接口如表1 所示。流模式的FFT 時序圖如圖12 所示。從圖中可以看出,輸入數據是連續的,無論載入數據還是FFT 運算,數據輸出都是同時進行的。

表1 FFT 核模塊端口介紹

圖12 流模式下的FFT 時序
實際應用中,可以根據變換有效數據輸出時Source_valid 為高電平期間來確定出現峰值的位置,進而根據位置號推算出信號中包含的信號頻率,進行信號的解調等處理。
流模式下的FFT 工作,Modelsim 的波形如圖13所示。當有數據輸入時Sink_valid 為1;當輸入第一個數據時,Sink_sop 為高;當輸入最后一個數據時,Sink_eop 電平由低變高,維持一個時鐘的高電平。FFT 核計算結束結果輸出,Source_valid 拉高。當輸出數據第一個值時,Source_sop 被拉高一個時鐘的高電平,之后變成低電平;當輸出數據最后一個值時,Source_eop被拉高一個時鐘的高電平,之后變成低電平。

圖13 流模式下的FFT 仿真波形
本文提出了利用Altera 公司提供的現有IP 核進行直接設計實現滑動短時傅里葉變換,從思路到實現上難度都不大,并給出了具體的設計與實現,其采用的方法可以用來其他的相關處理。
1)滑動窗口的實現采用了具有數據先進先出特點的FIFO 作為數據緩存,讀寫時鐘可以不一樣,且不用控制地址線,使用操作都很簡單。
2)設計中使用了Altera 公司提供的FFT 核直接進行傅里葉變換,只需要根據FFT 手冊進行恰當的時序設計,完成自己想要的功能,不需要從原理基礎上設計出一個傅里葉變換模塊,可以減少研發時間,降低研究成本。