Xilinx FPGA FFT 應用筆記

這個是2012年寫的,現在給放上來了,其實百度文庫也有。

系統工作環境:

    芯片爲:xilinxSpartan 6

    軟件:ise 12.2

    IP coreFFT版本:7.1  

目標:完成對放大板的標定


一、標定的過程簡單介紹:

放大板包含3級程控放大器的放大電路、4個可選擇的高頻濾波器、1個50Hz的工頻濾波器,放大板主要是針對低頻信號,放大頻率範圍:0-20KHz,

標定示意圖:


         ◎offset 調節:控制放大板的輸入接地,將放大器的放大倍數設置爲1000倍,測試AD 的輸出電壓是否爲0V,如果不是,則說明放大器內部有直流偏置,通過調節DA的offset輸出電壓,使得放大板在輸入爲0v時,輸出也爲0v。

          ◎直流標定:直流標定挺簡單的,讓DA輸出固定的電位,設置放大器的倍數,看看輸出是否與理論值一致。

例:輸入爲0.1mv,放大倍數爲1000倍,檢查輸出是否爲:0.1V ,目的主要是爲了檢查放大板對直流的響應。


          ◎交流標定:交流標定比較複雜,爲了測量放大板對交流信號的響應,主要體現在放大器對信號的相頻與幅頻特性。


          ◎具體的做法:FPGA控制DA產生一個正弦波,再通過AD採集放大後的數據,並對其做FFT(快速傅里葉變換),計算出信號的相位與幅度,與輸入的波形對比,檢測放大板的對交流信號的響應。

     例:①輸入f=1Hz,A=10mv,Phase = 0°的正弦波,測量輸出的

信號的A、Phase、f。

              ②輸入f=2Hz,A=10mv,Phase = 0°的正弦波,測量輸出的

 信號的A、Phase、f

        ③輸入f =3Hz……

………

⑩輸入f =2000Hz……

其實簡單點,就是一個頻譜分析儀,求放大板的頻譜圖,看看放大器對交流信號有沒有產生頻移與幅度的衰減。

二、FGPA的工作

◎控制放大器,簡單的IO應用

◎驅動ADS1274

◎驅動AD5664r

◎在內部生成一個DDS(直接數字頻率合成器),輸出頻率、相位可調的正弦波。

◎對AD採集的數據進行FFT的轉換。

三、DFT(離散傅里葉變換)的理解

3.1傅里葉變換的基礎知識

其實,大學的時候幾乎每個童鞋都學過傅里葉變換,應該算是必修的課程,但是當時我也就爲考試,背背公式,不知道大家是什麼心情,但是沒有想過有一天居然真的用到了,表示很無力啊。

  在網上找了一下資料,也看了一些書。把一些感覺好的東西記錄一下,加上自己的一些理解。

傅立葉是一位法國數學家和物理學家的名字,英語原名是:Jean Baptiste Joseph Fourier(1768-1830)Fourier對熱傳遞很感興趣,於1807年在法國科學學會上發表了一篇論文,運用正弦曲線來描述溫度分佈,論文裏有個在當時具有爭議性的決斷:任何連續週期信號可以由一組適當的正弦曲線組合而成。

舉個的例子理解下

在數學上,關於一個信號最基本的問題在於如何將它表示和描述出來。按照上面所說的辦法,把一個信號理解成一個定義在時間或空間上的函數是一種自然而然的表示方式,但是它對理解這一信號的內容來說常常不夠。例如一段聲音,如果單純按照定義在時間上的函數來表示,它畫出來是這個樣子的:



這通常被稱爲波形圖。毫無疑問,它包含了關於這段聲音的全部信息。但是同樣毫無疑問的是,這些信息幾乎沒法從上面這個「函數」中直接看出來,事實上,它只不過是巴赫的小提琴無伴奏 Partita No.3 的序曲開頭幾個小節。下面是巴赫的手稿,從某種意義上說來,它也構成了對上面那段聲音的一個「描述」:


這兩種描述之間的關係是怎樣的呢?第一種描述刻劃的是具體的信號數值,第二種描述刻劃的是聲音的高低(即聲音震動的頻率)。人們直到十九世紀才漸漸意識到,在這兩種描述之間,事實上存在着一種對偶的關係,而這一點並不顯然。 

根據原信號的不同類型,我們可以把傅立葉變換分爲四種類別:

  四種不同信號的變換結果:


摘自《數字信號處理》 王世一

。提問數字信號處理只能處理離散的信號,所以在以上的4種情況中,只有第4種是可行的,但是同時也參生了一個問題,就是信號必須是週期的,但是在實際的數據中,不一定都是週期的啊,這個怎麼辦呢!以下是在《Digitalsignal processing》(一個老外寫的特別好的書)的圖,看完圖後應該就能明白了。


就是把有限長的信號進行復制,讓其變成一個週期信號進行處理。

說到這,上一下離散傅里葉級數的公式:


上面是DFT的公式,至於怎麼來的,我也嘗試過搞明白,但是一頭霧水,大致的情況是:

(連續週期信號的傅里葉變換)

    通過對連續的週期的信號的公式進行抽樣處理,然後推到出來的,推的過程就很複雜了,也不太好理解。

3.2這樣理解DFT的公式(不知道對不對??)

當我看到離散傅里葉級數的公式:


我的第一個感覺就是,他代表的是什麼意思啊,憑什麼這個公式就是對的啊,怎麼樣理解這個公式呢。

⑴先說說公式各項:

◎x[i]:表示待處理的離散數據序列,其中i的範圍爲{0,N-1}   

:Re是Real的縮寫,表示實部(複數), 表示離散的頻率序列, 表示週期信號,K的範圍爲{0,N-1}

:cos函數

⑵公式的意義任何連續週期信號可以由一組適當的正弦曲線組合而成

把連續改成離散的:任何離散週期信號可以由一組適當的離散正弦曲線組合而成。

爲什麼可以算就是對的呢???

在網上看到了這樣一段話,感覺挺好的:

    傅立葉變換是一個數學上極爲精美的對象:

Ø  它是完全可逆的,任何能量有限的時域或空域信號都存在唯一的頻域表達,反之亦然;它完全不損傷信號的內在結構;

Ø  任何兩個信號之間有多少相關程度(即內積);它們的頻域表達之間也一定有同樣多的相關程度;

Ø  它不改變信號之間的關聯性:一組信號收斂到一個特定的極限,它們的頻域表達也一定收斂到那個極限函數的頻域表達。

那怎麼計算相關性呢,在網上看見了一個很不錯的例子:

http://blog.csdn.net/v_JULY_v/article/details/6196862

以下是他舉的例子

利用第一種方法、信號的相關性(correlation)可以從噪聲背景中檢測出已知的信號,我們也可以利用這個方法檢測信號波中是否含有某個頻率的信號波:把一個待檢測信號波乘以另一個信號波,得到一個新的信號波,再把這個新的信號波所有的點進行相加,從相加的結果就可以判斷出這兩個信號的相似程度。如下圖:


上面a和 b兩個圖是待檢測信號波,圖a很明顯可以看出是個3個週期的正弦信號波,圖b的信號波則看不出是否含有正弦或餘弦信號,圖c和d都是個3個週期的正弦信號波,圖e和f分別是a、b兩圖跟c、d兩圖相乘後的結果,圖e所有點的平均值是0.5,說明信號a含有振幅爲1的正弦信號c,但圖f所有點的平均值是0,則說明信號b不含有信號d。這個就是通過信號相關性來檢測是否含有某個信號的方法。

通過上面的例子,可以進一步確定:任何兩個信號之間有多少相關程度(即內積),它們的頻域表達之間也一定有同樣多的相關程度。

再來個實際的例子:

這個是圈圈寫的,在此引用:

一個模擬信號,經過ADC採樣之後,就變成了數字信號。採樣定理告訴我們,採樣頻率要大於信號頻率的兩倍,這些我就不在此羅嗦了。

採樣得到的數字信號,就可以做FFT變換了。N個採樣點,經過FFT之後,就可以得到N個點的FFT結果。爲了方便進行FFT運算,通常N取2的整數次方。

假設採樣頻率爲Fs,信號頻率F,採樣點數爲N。那麼FFT之後結果就是一個爲N點的複數。每一個點就對應着一個頻率點。這個點的模值,就是該頻率值下的幅度特性。具體跟原始信號的幅度有什麼關係呢?假設原始信號的峯值爲A,那麼FFT的結果的每個點(除了第一個點直流分量之外)的模值就是A的N/2倍。而第一個點就是直流分量,它的模值就是直流分量的N倍。而每個點的相位呢,就是在該頻率下的信號的相位。第一個點表示直流分量(即0Hz),而最後一個點N的再下一個點(實際上這個點是不存在的,這裏是假設的第N+1個點,也可以看做是將第一個點分做兩半分,另一半移到最後)則表示採樣頻率Fs,這中間被N-1個點平均分成N等份,每個點的頻率依次增加.n所表示的頻率爲:Fn=(n-1)*Fs/N。由上面的公式可以看出,Fn所能分辨到頻率爲爲Fs/N,如果採樣頻率Fs爲1024Hz,採樣點數爲1024點,則可以分辨到1Hz。1024Hz的採樣率採樣1024點,剛好是1秒,也就是說,採樣1秒時間的信號並做FFT,則結果可以分析到1Hz,如果採樣2秒時間的信號並做FFT,則結果可以分析到0.5Hz。如果要提高頻率分辨力,則必須增加採樣點數,也即採樣時間。頻率分辨率和採樣時間是倒數關係。

假設FFT之後某點n用複數a+bi表示,那麼這個複數的模就是An=根號a*a+b*b,相位就是Pn=atan2(b,a)。根據以上的結果,就可以計算出n點(n≠1,且n<=N/2)對應的信號的表達式爲:An/(N/2)*cos(2*pi*Fn*t+Pn),即2*An/N*cos(2*pi*Fn*t+Pn)。對於n=1點的信號,是直流分量,幅度即爲A1/N。由於FFT結果的對稱性,通常我們只使用前半部分的結果,即小於採樣頻率一半的結果。

好了,說了半天,看着公式也暈,下面圈圈以一個實際的信號來做說明。假設我們有一個信號,它含有2V的直流分量,頻率爲50Hz、相位爲-30度、幅度爲3V的交流信號,以及一個頻率爲75Hz、相位爲90度、幅度爲1.5V的交流信號。用數學表達式就是如下:

S=2+3*cos(2*pi*50*t-pi*30/180)+1.5*cos(2*pi*75*t+pi*90/180)

式中cos參數爲弧度,所以-30度和90度要分別換算成弧度。我們以256Hz的採樣率對這個信號進行採樣,總共採樣256點。按照我們上面的分析,Fn=(n-1)*Fs/N,我們可以知道,每兩個點之間的間距就是1Hz,第n個點的頻率就是n-1。我們的信號有3個頻率:0Hz、50Hz、75Hz,應該分別在第1個點、第51個點、第76個點上出現峯值,其它各點應該接近0。實際情況如何呢?我們來看看FFT的結果的模值如圖所示。

 

圖1 FFT結果
從圖中我們可以看到,在第1點、第51點、和第76點附近有比較大的值。我們分別將這三個點附近的數據拿上來細看:
1點: 512+0i
2點: -2.6195E-14 - 1.4162E-13i
3點: -2.8586E-14 - 1.1898E-13i

50點:-6.2076E-13 - 2.1713E-12i
51點:332.55 - 192i
52點:-1.6707E-12 - 1.5241E-12i

75點:-2.2199E-13 -1.0076E-12i
76點:3.4315E-12 + 192i
77點:-3.0263E-14 +7.5609E-13i
    很明顯,1點、51點、76點的值都比較大,它附近的點值都很小,可以認爲是0,即在那些頻率點上的信號幅度爲0。接着,我們來計算各點的幅度值。分別計算這三個點的模值,結果如下:
1點: 512
51點:384
76點:192
   按照公式,可以計算出直流分量爲:512/N=512/256=2;50Hz信號的幅度爲:384/(N/2)=384/(256/2)=3;75Hz信號的幅度爲192/(N/2)=192/(256/2)=1.5。可見,從頻譜分析出來的幅度是正確的。

附上自己對DFT的理解:

。假設採樣率爲N,輸入點的個數也爲N,

。根據奈奎斯特定理,DFT能分解出來的最高頻率爲:NHz,

。分辨率爲:1Hz,

DFT的意義就是將:0Hz,1Hz,2Hz……N/2Hz的信號與輸入的離散序列做內積,求每一個頻率與輸入的離散序列的相關程度。相關程度越大,表示這個頻率的信號在組成輸入序列的所有頻率信號中佔有的比重越大,他的幅值也越大。(不知道對不對??)

3.3  FFT與DFT

快速傅氏變換(FFT)是離散傅氏變換的快速算法,它是根據離散傅氏變換的奇、偶、虛、實等特性,對離散傅立葉變換的算法進行改進獲得的。它對傅氏變換的理論並沒有新的發現,但是對於在計算機系統或者說數字系統中應用離散傅立葉變換,可以說是進了一大步。

設x(n)爲N項的複數序列,由DFT變換,任一X(m)的計算都需要N次複數乘法和N-1次複數加法,而一次複數乘法等於四次實數乘法和兩次實數加法,一次複數加法等於兩次實數加法,即使把一次複數乘法和一次複數加法定義成一次“運算”(四次實數乘法和四次實數加法),那麼求出N項複數序列的X(m),即N點DFT變換大約就需要 次運算。當N=1024點甚至更多的時候,需要 =1048576次運算,在FFT中,利用WN的週期性和對稱性,把一個N項序列(設N=2k,k爲正整數),分爲兩個N/2項的子序列,每個N/2點DFT變換需要(N/2)2次運算,再用N次運算把兩個N/2點的DFT變換組合成一個N點的DFT變換。這樣變換以後,總的運算次數就變成 。繼續上面的例子,N=1024時,總的運算次數就變成了525312次,節省了大約50%的運算量。而如果我們將這種“一分爲二”的思想不斷進行下去,直到分成兩兩一組的DFT運算單元,那麼N點的DFT變換就只需要 次的運算,N在1024點時,運算量僅有10240次,是先前的直接算法的1%,點數越多,運算量的節約就越大,這就是FFT的優越性。

四、用FPGA做FFT的仿真

芯片爲:xilinxSpartan 6

軟件:ise 12.2

IP core FFT版本:7.1  

在做FFT之前,讀了一下IP core FFT的數據手冊,他的輸出端口比較簡單,但是也有一些疑惑的地方。

ISE 提供了FFT/IFFT 的IP Core,可以完成實數、複數信號的FFT 以及IFFT 運算。FFT 的

IP Core 提供三種結構,分別爲:

(1)            流水線,Streaming I/O 結構:允許連續的數據處理;

(2)基4,Burst I/O 結構:提供數據導入/導出階段和處理階段。此結構擁有較小的結構,但轉換時間較長;

(3)基2,Burst I/O 結構:使用最少的邏輯資源,同Radix-4 相同,提供兩階段的過程。

其配置界面有3 頁,第一頁如圖5-57所示,主要用於配置實現結構;第二頁配置數據位寬以及數據處理操作;第三頁配置數據緩存空間。在實際硬件操作中,模塊的執行速度是很重要的參數,所以本文分析第一種結構,即流水線Streaming I/O結構,以進行連續的數據處理。在進行當前幀的N 點數據時,可加載下一幀的N 點數據,同時輸出前一幀的N點數據。此結構由多個基2的蝶形處理單元構成,每個單元都有自己的存儲單元來存儲輸入和中間處理的數據。FFT 的計算單元具有豐富的控制信號,其詳細說明見下文。

XN_RE、XN_IM :輸入操作數,分別爲實部和虛部,以2 的補碼輸入。在使用時應當確定其位寬。

START:FFT 開始信號,高有效。當此信號變高時,開始輸入數據,隨後直接進行FFT 轉換操作和數據輸出。一個START 脈衝,允許對一幀進行FFT 轉換。如果每N 個時鐘有一個START 脈衝或者START 始終爲高,,則都可以連續進行FFT 。如果在最初的START 前,還沒有NFFT_WE ,FWD_INV_WE,SCALE_SCH_WE信號,則START 變高後就使用這些信號的默認值。由於此IP Core 支持非連續的數據流,因此在任何時間輸入START,即可開始數據的加載。當加載N 個數據結束後,就開始FFT 轉換運算。

UNLOAD:對於Burst I/O 結構,此信號將開始輸出處理的結果。對於流水線結構和比特逆序輸出的情況,此端口不是必要的。

NFFT :此端口只對實時可配置應用時有用。

NFFT_WE :此端口是NFFT 端口的使能信號。

FWD_INV :用以指示IP Core 爲FFT 還是IFFT,其等於1 時IP Core 進行FFT 運算,否則進行IFFT 運算。至於採用哪種轉換運算是可以逐幀變化的。這一端口給FFT 的使用提供了很大的方便。

FWD_INV_WE :作爲FWD_INV 端口的使能信號。

SCALE_SCH:(1) 在IP Core 設計時,如果選擇在計算過程中進行中間數據的縮減,那麼此信號纔可起作用;(2) 輸入的位寬等於2*ceil(NFFT/2),其中NFFT = log2(point size)。(3) 流水線結構中,將每個基2 的蝶形處理單元視爲一個階段,每個階段進行一次數據的縮減,縮減的比例以此輸入中對應階段的兩比特表示。(4)每階段的兩比特數可以是3,2,1 或0 :它們表示了數據所需要移動的比特數。

SCALE_SCH_WE :作爲SCALE_SCH 的使能信號。

SCLR :可選端口。

Reset :重置信號端口。Reset=1 時,所有工作都停止且初始化。但內部的幀緩存保留其內容。

CE :可選端口。

CLK :輸入時鐘。

XK_RE,XK_IM :輸出數據總線,以2 的補碼輸出。SCALE_SCH_WE 有效時,輸出位寬等於輸入;否則,輸出位寬= 輸入位寬+NFFT+1。

XN_INDEX :位寬等於log2(point size),輸入數據的下標。

XK_INDEX :位寬等於log2(point size),輸出數據的下標。

RFD :數據有效信號,高有效,在加載數據時爲高電平。

BUSY :IP Core 工作狀態的指示信號,在計算FFT 轉換時爲高電平。

DV :數據有效指示信號,當輸出端口存在有效數據時變高。

EDONE :高有效。在DONE 信號變高的前一個時鐘變爲高電平。

DONE :高有效。在FFT 完成後變高,且只存在一個時鐘。在DONE 變高後,IP Core 開始輸出計算結果。

BLK_EXP :當使用Burst I/O 結構時可用,若選擇流水線,則此端口無效

OVFLO :算法溢出指示。在數據輸出時,如每幀有溢出,此信號變高。在每幀開始處,此信號重置。

總體說這個核功能很強大,用的時候最重要的就是注意start 信號要早於輸入信號4個週期,但是實際應用中並不需要4個週期就已經開始加載數據了,可以這樣做:START 一直開,認爲第一次加載數據是初始化,即從第二次開始正式工作,從而簡化了設計。

Xilinx FFT IP核V7.1支持三種算法類型:全精度無壓縮、塊浮點型和定點壓縮(壓縮比由用戶自定義)。

對於全精度無壓縮結構,數據通道內任意一位有意義的整數都將被保留,在運算過程中產生的小數部分都被截斷或者取整。此種結構,對於定點算法,經過多級乘法操作以後,數據位寬將加倍遞增,其輸出位寬爲(輸入位寬+log2(數據轉換長度)+1)bits。

對於塊浮點型,對於一幀數據裏面的任何一數據點有相同的壓縮比,這個壓縮比值由塊指數(Block Exponent)作爲輸出值顯示,而且只有在FFT IP核檢測到將會產生數據溢出的時候,纔會進行壓縮運算。

本文所採用的是定點壓縮結構。該結構相對於全精度無壓縮結構,能夠大大減少FPGA內部資源Xtreme DSP Slices和塊RAM的使用,而相對於塊浮點型,可靈活調節壓縮比。定點壓縮結構的壓縮比例表(Scale_SCH)完全由用戶自定義得到。壓縮比例是按照1、2、4或者8對每一階進行壓縮,即對應於分別向右移位0、1、2或者3。如果壓縮不充分,則蝶形輸出結果會超出其動態範圍,引起數據溢出。對於Burst I/O結構,Scale_SCH的表示方法:對於每一階的壓縮比都由指定的一個2bits的數表示,零階的2bits數爲最低位,具體形式爲[N4,N3,N2,N1,N0],每一個2bits數分別對應着相應階數的壓縮比。例:對於基4結構,數據轉換長度N=1024,Scale_SCH=[0110 00 1110]則表示對階0右移位2,對階1右移位3,對階2右移位0,對階3右移位2,對階4右移位1。經驗總結(可以防止產生數據溢出):對於1024點的基4,Burst I/O結構,Scale_SCH=[10 10 10 10 11];而對於1024點的基2結構,Scale_SCH=[01 01 01 01 01 01 01 01 0110]。對於流水線,Streaming I/O結構,把臨近的一對基2階組在一起,即階0和階1爲組0,階2和階3爲組1,等等。Scale_SCH的表示方法:對於每一組的壓縮比都由指定的一個2bits的數表示,零組的2bits數爲最低位,具體形式爲[N4,N3,N2,N1,N0],每一個2bits數分別對應着相應組的壓縮比,表示同組內的兩個基2階有相同的壓縮比。例:數據長度N=1024,Scale_SCH=[10 10 00 01 11]表示對組0(階0和階1)右移位3,對組1(階2和階3)右移位1,對組2(階4和階5)沒有移位,對組3(階6和階7)右移位2,對組4(階8和階9)右移位2。若變換長度N不是4的冪次方的時候,最後一組只包含一個基2階,只能用00或者01表示。經驗總結(可以防止產生數據溢出):N=512時,Scale_SCH=[01 10 10 10 11];N=1024時,Scale_SCH=[1010 10 10 11]。壓縮比例Scale_SCH的位寬,對於流水線,Streaming I/O結構和基4,Burst I/O結構,爲2*ceil(0.5*log2(N));對於基2,Burst I/O結構和基2Lite Burst I/O結構,爲2* log2(N),其中N爲轉換數據長度。

在仿真過程中遇到的問題:

1.  數據的輸入:datasheet上寫的是“two’s complement”,我看了許多的翻譯,多是翻譯爲2的補碼的形式,我就想2的補碼的形式是什麼形式,後來百度後才知道two’s complement就是補碼的意思,而不是2的補碼。

2.  還是輸入的問題,數據輸入分爲實部和虛部,但是AD輸出的信號爲實數信號,怎麼將實數轉換成複數輸入,網上有個哥們提出了相同的問題。

有的人回答:將實數做正交轉換,但是怎麼轉換呢????

還有的回答是:實部與虛部都輸入AD的輸出值,說FFT的速度會加快,沒有驗證過。

我的理解應該:實部爲AD的輸出值,虛部爲0,驗證正確。

3.  設置Scale_SCH時,不確定設置多大數值時,可以將ovflo引腳引出,看看仿真的時候會不會溢出。

4.  數據的輸入要在rfd爲高時,纔有效。

 

 

※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※

FFT的設置:

Transform length:16

R-2,Burest IO

datawidth 16, Phase factor16.

scaled,

convergentrounding,

naturalorder without cycle prefix insertion.

memoryblock ram,

complexmultiplier- 3 multiplier structure,

butterflyarithmetic ,

useCLB logic

※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※

仿真的程序:

`timescale1ns / 1ps

////////////////////////////////////////////////////////////////////////////////

//Company:

//Engineer:calm_yi

//

//Create Date:   09:47:47 04/24/2012

//Design Name:   fft

//Module Name:  C:/Users/PC/Desktop/FFT/fft/fftt.v

//Project Name:  fft

//Target Device: 

//Tool versions: 

//Description:

//

//Verilog Test Fixture created by ISE for module: fft

//

//Dependencies:

//

//Revision:

//Revision 0.01 - File Created

//Additional Comments:

//

////////////////////////////////////////////////////////////////////////////////

modulefftt;

 

    // Inputs

    reg start;

    regfwd_inv;

    regclk;

    regscale_sch_we;

    regfwd_inv_we;

    reg [7:0] scale_sch;

    wirerfd;

    wire [3:0] xn_index;

    reg [15:0] xn_re;

    reg [15:0] xn_im;

 

    // Outputs

    wire done;

    wire busy;

    wireedone;

    wireovflo;

    wire dv;

    wire [3:0] xk_index;

    wire [15:0] xk_im;

    wire [15:0] xk_re;

   

    // Instantiate the Unit Under Test (UUT)

    fftuut (

           .rfd(rfd),

           .start(start),

           .fwd_inv(fwd_inv),

           .dv(dv),

           .done(done),

           .clk(clk),

           .busy(busy),

           .scale_sch_we(scale_sch_we),

           .fwd_inv_we(fwd_inv_we),

           .edone(edone),

           .ovflo(ovflo),

           .xn_re(xn_re),

           .xk_im(xk_im),

           .xn_index(xn_index),

           .scale_sch(scale_sch),

           .xk_re(xk_re),

           .xn_im(xn_im),

           .xk_index(xk_index)

    );

 

    initial begin

           // Initialize Inputs

           start = 1;

           fwd_inv = 1;

           clk = 0;

           scale_sch_we =1;

           scale_sch = 8'b01010101;

           fwd_inv_we = 1;

           xn_re = 0;           

           xn_im = 0;

num= 0;

           // Wait 100 ns for global reset tofinish

           #100;   

    end

always

    begin

      #10 clk<= 1;

           #10clk<= 0;

    end

reg[3:0]num;

always@(posedgeclk)

begin

    if(rfd)

    begin

           num<= num + 1'b1;

           case(num)

                  4'd0: xn_re<= 10000;

                                       4'd1:xn_re<= 10000;

                                       4'd2:xn_re<= 10000;

                                       4'd3:xn_re<= 10000;

                                       4'd4:xn_re<= 10000;

                                       4'd5:xn_re<= 10000;

                                       4'd6:xn_re<= 10000;

                                       4'd7:xn_re<= 0;

                                       4'd8:xn_re<= 0;

                                       4'd9:xn_re<= 0;

                                       4'd10:xn_re<= 0;

                                       4'd11:xn_re<= 0;

                                       4'd12:xn_re<= 0;

                                       4'd13:xn_re<= 0;

                                       4'd14:xn_re<= 0;

                                       4'd15: xn_re<=10000;

                                default: ;

                         endcase

    end

end

endmodule

仿真的時序圖

◎輸入爲16個點:

。實數部分:10000、10000、10000、10000、10000、10000、10000、10000、

              0、  0、     0、    0、    0、    0、    0、    0、

。虛實部分:0、0、0、0、0、0、0、0、0、0、0、0、0、0、0、0

其實就是一個幅值爲10000,佔空比爲50%的方波在rfd爲高電平時輸入:

  

FFT輸出的數據

dv爲高電平時輸出轉換的數據:

Num

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

Re

5000

625

0

625

0

625

0

625

0

625

0

625

0

625

0

625

Im

0

-3142

0

-936

0

-418

0

-124

0

124

0

418

0

936

0

3142

爲了驗證仿真的結果,用matlab做了一下相同的十六個點的仿真,結果如下:


 

在結果中,我們發現,matlab做出來的結果都是FPGA仿真的結果的兩倍,爲什麼,(待解決)

但是可以看出,應該是仿真結果是對的,因爲0Hz時,也就是直流分量FPGA的仿真結果爲5000,而matlab的爲10000,所以應該是matlab的結果不知道那出了問題!

◎下面是做的第二個仿真,FFT的點數爲64,其他的參數與上面的一樣。

。壓縮比例:scale_sch =12'b000000010101;

。輸入的數據採樣率爲:64Hz/s

。採樣時間爲:1s

。採樣的函數爲:

輸入的數據就是對P的採樣後的64個數據。


。輸入的細節:


。FFT後輸出的數據:




在圖中,可以看到:22Hz、5Hz、18Hz時的幅值是非常高的。證明包含的頻率分量是對的,但是幅值是不對的,可能跟壓縮比例有關係。

以下是改變壓縮比例後的結果:

壓縮比例:scale_sch= 12'b010101010101;


兩者之間有什麼關係,需要進一步驗證。

 

 

以下是matlab的輸出結果


 

 

 

                    

                                                                                                  yi

                                                                                                  EMEQGroup

                                                                                                  2012.04.27


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