1 項目背景 (源碼下載 交流輔導群:544453837)1.1 多采樣率數字濾波器 多采樣率就是有多個采樣率的意思。前面所說的FIR,IIR濾波器都是只有一個采樣頻率,是固定不變的采樣率,然而有些情況下需要不同采樣頻率下的信號。 按照傳統的速率轉換理論,我們要實現采樣速率的轉換,可以這樣做,假如有一個有用的正弦波模擬信號,AD采樣速率是f1,現在我需要用到的是采樣頻率是f2的信號,傳統做法是將這個經過f1采樣后的信號進行DA轉換,再將轉換后的模擬信號進行以f2采樣頻率的抽樣,得到采樣率為f2的數字信號,至此完成采樣頻率的轉換 但是這樣的做法不僅麻煩,而且處理不好的話會使信號受到損傷,所以這種思想就被淘汰了,現在我們用到的采樣率轉換的方法就是抽取與內插的思想。 1.2 抽取 先來總體來解釋一下抽取的含義:前面不是說,一個有用的正弦波模擬信號經采樣頻率為f1的抽樣信號抽樣后得到了數字信號,很明顯這個數字信號序列是在f1頻率下得到的,現在,假如我隔幾個點抽取一個信號,比如就是5吧,我隔5個點抽取一個信號,是不是就是相當于我采用了1/5倍f1的采樣頻率對模擬信號進行采樣了?所以,抽取的過程就是降低抽樣率的過程,但是我們知道,這是在時域的抽樣,時域的抽樣等于信號在頻域波形的周期延拓,周期就是采樣頻率,所以,為了避免在頻域發生頻譜混疊,抽樣定理也是我們要考慮的因素 下面來具體來介紹 如上圖所示,假如上面就是某一有用信號經采樣頻率f1抽樣得到的頻譜,假設這時候的采樣頻率為8Khz,可以通過數格子得到,從0到F1處有8個空格,每個空格代表1Khz,有些朋友可能會問,這不是在數字頻域嗎,單位不是π嗎,哪來的hz?是的,這里是數字頻域,采樣頻率F1處對應的是2π,這里只是為了好解釋,我們用模擬頻率來對應數字頻率。 上面是采樣頻率為8K的數字信號頻域圖,現在我要對這個數字信號進行時域抽取,從而來降低信號的采樣率,我們知道,一旦我們對數字信號進行時域抽取,那么采樣率下降,而采樣率就是數字信號頻域的波形周期,那么也就是周期下降,所以,我們對信號進行抽取要有個度,要在滿足抽樣定理的條件下對信號進行抽取,否則就會發生頻譜混疊。 上圖就是對信號進行了1/5倍的F1采樣頻率抽取,可見,由于發生了頻譜混疊現象,因為1/5倍的F1是1600hz,而信號的頻帶是1000hz,不滿足抽樣定理,導致發生了頻譜混疊,所以,為了避免發生這種情況,除了要滿足抽樣定理之外,即抽樣倍數不能太高,我們還需要把信號的頻帶設置在F1/2以下,才能確保信號不發生頻譜混疊,因此,我們需要在抽取之前加一個低通濾波器,書上叫做抗混疊低通濾波器,用來限制信號的頻帶,然后再進行抽取,這樣的話我們來算一下 低通濾波器的截止頻率就是1/2倍的經抽取后的采樣速率,即fc = 1/2 * (F1/M) ,M是抽取倍數。而1/2*F1對應的數域頻率是π,因此我們得出, 抗混疊低通濾波器的截止頻率是π/M 1.3 內插 抽取的過程是降低采樣率的過程,那么插值的過程當然就是提高采樣率的過程。大體的思路可以這么理解,我們將經f1抽樣下得到的數字信號的每兩個點之間進行插值,插入的值是0,插值之后,信號在單位時間內的采樣點數增多,當然也就是采樣速率的提升,采樣速率提升后我們知道,那么信號的頻譜的周期就會增加 需要注意的一點就是,插值前后,我們只是在時域信號中間插入了D-1個零值,僅僅是改變了采樣率,并沒有改變信號的信息,因此,在頻域,信號頻譜的形狀是不會改變的,改變的僅僅是周期,如上圖,F1是插值之前信號的周期,插值之后,信號頻譜的形狀不變,周期成了F1*D,D是插值倍數。如果我們直接用F1*D倍的采樣率采信號,得到的頻譜會發現,就不會有中間兩個波形,因此,這兩個波形是多余的,書上叫做是鏡像頻譜。既然是多余的,我們就可以將它用一個低通濾波器濾掉,這樣的低通濾波器,就叫做鏡像低通濾波器。這樣我們來計算一下鏡像低通濾波器的截止頻率 根據上面這張圖我們可以求出鏡像低通濾波器的截止頻率,可以看到,fc = 1/2 *F1,這里我們假設,內插之后的采樣頻率為F2=F1*D,那么,fc =1/2*(F2/D),而1/2*F2對應的是π,注意,這里是1/2*F2對應π,不是1/2*F1了,因為這已經是插值之后采樣率增加之后的頻譜了,所以我們得出: 鏡像低通濾波器的截止頻率為:π/D 1設計目標 本案例是FPGA內部產生正弦信號,這個正弦信號一路輸出給DA通道A,另一路經過插值濾波器后,輸出給DA通道B。 正弦信號產生電路產生頻率為62.5KHz的正弦信號,該正弦信號由8個點組成。 插值濾波器是4倍的插值,也就是說進來是8個點的正弦波,輸出將是32個的正弦波。 仿真效果,上面的波形為插值前,下面的為插值后可以明顯看出下面的波形更為圓滑。 下面是示波器的顯示效果 3 設計實現3.1 頂層信號 新建目錄:D:\mdy_book\cic_prj。在該目錄中,新建一個名為cic_prj.v的文件,并用GVIM打開,開始編寫代碼。 我們要實現的功能,概括起來就是FPGA產生控制AD9709,讓其中的通道A未濾波的正弦信號,讓通道B輸出濾波后的正弦信號。為了控制AD9709的工作模式,就要控制AD9709的MODE、SLEEP管腳;為了控制通道A,就需要控制AD9729的CLK1、WRT1、DB7~0P1管腳;為了控制通道B,就需要控制AD9729的CLK2、WRT2、DB7~0P2管腳。根據設計目標的要求,整個工程需要以下信號: 1. 使用clk連接到晶振,表示50M時鐘的輸入。 2. 使用rst_n連接到按鍵,表示復位信號。 3. 使用dac_mode信號連接到AD9709的MODE管腳,用來控制其工作模式。 4. 使用dac_sleep信號連接到AD9709的SLEEP管腳,用來控制其睡眠模式。 5. 使用dac_clka信號連接到AD9709的CLK1管腳,用來控制通道A的時鐘。 6. 使用dac_wra信號連接到AD9709的WRT1管腳,用來控制通道A的寫使能。 7. 使用8位信號dac_da連接到AD9709的DB7~0P1管腳,用來控制通道A的寫數據。 8. 使用dac_clkb號連接到AD9709的CLK2腳,用來控制通道B時鐘。 9. 使用dac_wrb號連接到AD9709的WRT2腳,用來控制通道B使能。 10. 使用8位信號dac_db接到AD9709的DB7~0P2腳,用來控制通道B寫數據。 綜上所述,我們這個工程需要10個信號,時鐘clk,復位rst_n,dac_mode、dac_sleep、dac_clka、dac_wra、dac_da、dac_clkb、dac_wrb和dac_db信號,其中dac_da和dac_db是8位信號,其他都是1位信號。下面表格表示了硬件電路圖的連接關系。 將module的名稱定義為cic_prj,代碼如下: 其中clk、rst_n是1位的輸入信號,dac_da和dac_db是8位的輸出信號,dac_mode,dac_clka,dac_wra,dac_sleep,dac_clkb,dac_wrb是一位輸出信號。 3.2 正弦信號設計 假設產生的正弦信號命名為sin_data信號。sin_data一共有8個值,是從一個正弦信號中,按(2*pi/8)的間隔采樣到的,可列出下表。 很自然地定義一個7位的選擇信號addr。我們只要控制好addr,就能方便得到sin_data。因此可以寫出下面代碼。 接下來是設計信號addr。 addr是用來控制選擇數據的地址,通過控制addr的增加值,就能產生所需要的正弦波。 本案例要求產生62.5KHz的正弦信號。該正弦信號的周期是16000ns。本工程的工作時鐘是20ns,也就是16000/20 = 800個時鐘輸出一個正弦信號,也就是800個時鐘將上表的8個值輸出一遍,即每100個時鐘輸出addr加1。 每100個時鐘輸出一個值,那意味著我們需要一個計數器cnt0,該計數器用來對這100進行計數。計數器的加1條件是“1”,結束條件是“數到100個”。因此可寫出cnt0的代碼。 每100個時鐘后,addr就加1。說明這個addr也是一個計數器,該計數器的加1條件是“數到100個時鐘”,即end_cnt0,結束條件是“數到8個”。 3.3 CIC 濾波器設計3.3.1 新建FPGA工程 1.)打開quartus,點擊File 在File菜單中選擇New ProjectWizard.... 。 2.彈出Introduction界面選擇Next。 (3)設置工程目錄,工程名,頂層模塊名 工程目錄設置為:D:\mdy_book\cic_prj 工程名:cic_prj 頂層模塊名:cic_prj 填寫完畢后,點擊next之后進入下一界面。 (3.)在文件添加界面,不選擇任何文件。點擊Next,進入下一個界面。工程類型界面,Project Type選擇Empty project,選擇空白工程。點Next進入下一個界面。 (3.)在文件添加界面,不選擇任何文件。點擊Next,進入下一個界面。 (4.)器件選擇界面。在Device family這一項之中選擇 Cyclone IV E;在下部的Available device 選擇EP4CE6F23C8。完成后直接點擊Finish。 3.3.2FPGA生成CIC IP核 建立工程后,在quartus中IP catalog這一界面中選擇DSP下一目錄中選擇Filter 再選擇 CIC。 點擊后進入此界面給新生成的fir濾波器ip核選擇如下路徑:D:\mdy_book\cic_prj,entityname填寫:my_cic。點擊OK后,進入FIR濾波器設置界面。 按如下設置: Filter Type:要選擇Interpolator,表示是插值濾波器。 Rate change factor:填上4,表示是4倍插值。 output Rounding Method:選擇Truncation,表示輸出的結果要截斷。 Output data width:選擇8。表示輸出結果要截斷為8位。 其他選項默認,點擊窗口右下角的Generate Hdl,會彈出下面的窗口。 注意選擇文件是Verilog文件,其他都不用勾選。點擊Generate,就會生成y_cic的verilog文件。 出現上面的提示,就是生成成功了。 點Finish關閉CIC濾波器生成窗口。 如果出現上面的提示,就是表示要手動將剛才生成的IP核加到本工程。 在Project菜單中選擇Add/Remove File to Project,彈出文件窗口。 點擊右上角的,在彈出來的窗口中,雙擊選擇D:\mdy_book\cic_prj\my_cic\synthesis目錄下的my_cic.qip文件(注意不要搞錯文件類型)。然后記得要點Add,才算正式加到工程。 點OK關閉本窗口。 IP核生成后彈出此對話框點擊yes 將此IP核添加進工程。 3.3.3 例化CIC IP核 用GVIM打開D:\mdy_book\cic_prj\my_cic\synthesis\my_cic.v文件,該文件就是生成的CIC IP核文件 特別注意的是,濾波器的輸入數據和輸出數據都是有符號數(補碼的形式,-128~127)。而我們知道,正弦信sin_data是無符號數(0~255)。所以要將sin_data變成有符號數,再送給FIR進行濾波。假設轉換后的信號為cic_din,該信號位寬為8位。 無符號數轉成有符號數的方法很簡單:cic_din = sin_data - 128。讀者有興趣可以驗證一下。 生成CIC IP核后,我們要對其進行例化,才行使用上這個IP核,例化名起名u_my_cic,cic的輸出數據信號命名為cic_dout。 我們要控制CIC IP核的輸出,使每個數據都能等間隔輸出數據。由于CIC濾波器的輸入是100個時鐘一個數據,CIC是4倍速率,因此輸出是25個時鐘一個數據。所以我們每25個時鐘給一個有效信號連到out_ready接口上。這時需要一個計數器cnt1來計時25個時鐘,該計數器加1條件是“1”,結束條件是“數到25個”。 |