(原創(chuàng)聲明:該文是作者的原創(chuàng),面向?qū)ο笫?/em>FPGA入門者,后續(xù)會有進階的高級教程。宗旨是讓每個想做FPGA的人輕松入門,作者不光讓大家知其然,還要讓大家知其所以然!每個工程作者都搭建了全自動化的仿真環(huán)境,只需要雙擊top_tb.bat文件就可以完成整個的仿真(前提是安裝了modelsim),降低了初學(xué)者的門檻。如需整個工程請留言(WX:Blue23Light),不收任何費用,但是僅供參考,不建議大家獲得資料后從事一些商業(yè)活動!)
上節(jié)課我們將不同頻率的正弦波疊加,造成輸出波形上有很多毛刺,這在實際應(yīng)用中,就是在我們需要的信號上疊加了干擾!如何去除干擾呢?那就要設(shè)計數(shù)字濾波器將干擾頻率的波形濾除,保留需要的信號即可。
常用的數(shù)字濾波器有無限脈沖響應(yīng)數(shù)字濾波器(Infinite Impulse Response),簡稱IIR濾波器;還有就是有限脈沖響應(yīng)數(shù)字濾波器(Finite Impulse Response),簡稱FIR濾波器。
由于本節(jié)課程的重點不是講數(shù)字濾波器的,所以要熟悉數(shù)字濾波器請去網(wǎng)上收索相關(guān)的內(nèi)容,本節(jié)就是使用IIR濾波器來去除高頻的干擾,讓經(jīng)過濾波器后的波形平滑。這兒只說明一點,IIR濾波器不光用到輸入的數(shù)據(jù),還需要輸出的反饋數(shù)據(jù),而FIR濾波器只需要輸入的數(shù)據(jù)即可,所以從設(shè)計難度上來說,IIR設(shè)計難度更大一些。
設(shè)計IIR濾波器,可以不了解濾波的原理,但是要知道IIR的結(jié)構(gòu)。IIR濾波器的系統(tǒng)函數(shù)的標(biāo)準(zhǔn)型如下所示:
但是FPGA設(shè)計的時候需要用的是差分型,如下所示:
以二階的IIR為例,用matlab搭建的simulink仿真圖如下所示,需要的參數(shù)有coeff_scale,coeff_in,coeff_out1和coeff_out2,只要確定這幾個參數(shù)就可以完成IIR濾波器的設(shè)計。
下面講述一下如何確定這幾個參數(shù),通過matlab的APP打開Filter Designer。
參數(shù)設(shè)置頁面進行如下的設(shè)置,Response選擇lowpass,IIR的Elliptic,Specify order選擇2,采樣頻率Fs是2MHz(因為系統(tǒng)時鐘是100MHz,50個系統(tǒng)時鐘輸入一個數(shù)據(jù)就是2MHz),F(xiàn)pass設(shè)置是100KHz。最后點擊Design Filter完成參數(shù)的設(shè)置。
然后點擊File,Export。
最終將參數(shù)導(dǎo)入到Workspace即可,參數(shù)矩陣是SOS,增益參數(shù)是G。
SOS的第2個參數(shù)就是coeff_in,第5個參數(shù)是coeff_out1,第6個參數(shù)是coeff_out2;G的第2個參數(shù)就是coeff_scale。
得到的參數(shù)都是帶小數(shù)點的,直接在FPGA內(nèi)部是無法使用的,我們必須轉(zhuǎn)換成16進制的定點數(shù)??梢允褂弥噶顈=fi(SOS,1,44,40),將SOS的數(shù)據(jù)轉(zhuǎn)化成1個符號位,3個整數(shù)位,40個小數(shù)位的定點數(shù),然后再使用y.hex指令將10進制的定點數(shù)轉(zhuǎn)換成16進制的定點數(shù)。最終的參數(shù)如下所示。
有了參數(shù),我們就開始IIR濾波器的設(shè)計。根據(jù)matlab的simulink仿真圖,我們可以得到如下的差分公式:
y(n)=coeff_scale[x(n)+coeff_in*x(n-1)+x(n-2)]-coeff_out1*y(n-1)-coeff_out2*y(n-2),在這兒我們采用串行的方式,用一個乘法器來實現(xiàn)IIR的濾波。
為了模塊的通用化,通過參數(shù)傳遞完成數(shù)據(jù)位寬的傳遞。這兒對數(shù)據(jù)位寬進行了擴展,考慮有多個加減法,直接將數(shù)據(jù)擴展了8位。輸入的數(shù)據(jù)是9位,擴展8位后是17位。乘法運算后數(shù)據(jù)位寬再擴展44位,即61位。
下面是中間要使用信號的定義,需要注意位寬。
定義了相關(guān)的狀態(tài)機,MULT_SCALE是完成coeff_scale*x(n)的計算,計算的結(jié)果存在mult_scale中,然后按照采樣率打拍緩存到data_in_dly1(就是coeff_scale*x(n-1))和data_in_dly2(coeff_scale*x(n-2))中;狀態(tài)機MULT_DI_DLY1是計算coeff_in*data_in_dly1;狀態(tài)機MULT_DO_DLY1是計算coeff_out1*y(n-1);狀態(tài)機MULT_DO_DLY2是計算coeff_out2*y(n+1);后面的四個狀態(tài)機主要完成前面5個數(shù)據(jù)的加減運行,一個狀態(tài)機完成一步的加或減。
狀態(tài)機的跳轉(zhuǎn)用組合邏輯實現(xiàn),非常的簡單,每次乘法或者加減法計算完成跳轉(zhuǎn)到下一個狀態(tài),如下所示(代碼太長,部分截圖)。
例化了一個乘法器,4個時鐘周期出計算結(jié)果,根據(jù)狀態(tài)機給乘數(shù)和被乘數(shù)賦不同的值,并產(chǎn)生開始計算的mult_en信號,主要用于4個時鐘的計數(shù)。如下圖所示(代碼太長,部分截圖)。
乘法相關(guān)的信號,包括計數(shù)mult_cnt,乘法計算完成mult_vld,和結(jié)果mult_scale,mult_din,mult_dout1,mult_dout2等信號(代碼太長,部分截圖)。需要注意的是對乘法后的結(jié)果進行了小數(shù)位的截斷,因為輸入數(shù)據(jù)是整數(shù),相乘后保留整數(shù)位即可,把小數(shù)直接舍棄即可。首位是符號位,是一定要取的。
根據(jù)狀態(tài)機產(chǎn)生加減運算的使能信號addsub_en(代碼太長,部分截圖)。
產(chǎn)生加減法完成有效的信號addsub_vld,同時將輸入和輸出的數(shù)據(jù)按照采樣率進行打拍,因為這兒用的是二階的IIR,輸入和輸出打兩拍即可,就是得到x(n-1),x(n-2),y(n-1),y(n-2)。
根據(jù)狀態(tài)機完成加減法數(shù)據(jù)的運算。
最后就可以得到IIR濾波器的結(jié)果,注意經(jīng)過IIR濾波器后輸出數(shù)據(jù)的結(jié)果和輸入數(shù)據(jù)的結(jié)果是一樣的。
完成設(shè)計后,建立仿真文件,雙擊sim目錄下的top_tb.bat文件,完成自動化的仿真。
仿真結(jié)果如下所示,經(jīng)過IIR濾波后,基本恢復(fù)出來了低頻的正弦波信號。濾波后的數(shù)據(jù)不是非常的平滑,可以改變?yōu)V波器的參數(shù)來改善一下。
IIR濾波器使用FPGA設(shè)計的流程就是這樣的,讀者可能會說如果需要更快的采樣頻率怎么辦?我們可以大體評估一下現(xiàn)在的一次IIR需要多少時鐘周期。一次乘法共需要8個時鐘周期(進入狀態(tài)機1個時鐘,乘法使能1個時鐘,計數(shù)了6次),一次加減法是3個時鐘周期(進入狀態(tài)機1個時鐘,加減法使能1個時鐘,出結(jié)果1個時鐘),IIR的計數(shù)共用到了4次乘法和4次加法,那就是8*4+4*3=44個時鐘周期,再加上IDLE和END各1個數(shù)時鐘周期,那1次的IIR需要大約46個時鐘周期。
如果想加快采樣頻率,那一次IIR的計數(shù)時間要縮短才可以!這兒就要設(shè)計FPGA設(shè)計的一個重要思想:用面積來換速度!因為上面的設(shè)計只用到了一個乘法器和加減法器,其實是可以使用多個乘法器和加減法器的。IIR可以使用4個乘法器(mult_scale*mult_din可以定義成一個參數(shù)),那就是8個時鐘周期就可以完成所有乘法的運算;使用2個加減法器,4次的加減法可以縮短2次計數(shù)完成,那一次的IIR運算需要8+2*3+2=16個時鐘周期!建議讀者自己設(shè)計完成。文章來源:http://www.zghlxwxcb.cn/news/detail-810601.html
使用FIR濾波器也可以實現(xiàn)上面的功能,可能需要的階數(shù)要多一些,建議讀者自己來實現(xiàn)一下。文章來源地址http://www.zghlxwxcb.cn/news/detail-810601.html
到了這里,關(guān)于孩子都能學(xué)會的FPGA:第十六課——用FPGA實現(xiàn)IIR濾波器濾波的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!