c语言 截止频率6低通滤波器,用Verilog在FPGA上实现低通滤波器
在本文中,我們將簡要介紹不同類型的過濾器,然后學習如何實現(xiàn)移動平均過濾器并使用CIC架構(gòu)對其進行優(yōu)化。
在許多設(shè)計中,過濾非常重要。它為我們提供了一個機會,可以提取埋在很多噪聲下的所需信號。我們還可以通過在某些頻率上過濾其輸出來確定系統(tǒng)的非線性。
讓我們首先討論過濾器類型之間的一些差異。理論過濾器的類型
過濾器可根據(jù)通帶類別劃分為以下5組中的一種。每一種的能力都以他們的名字提示。例如,低通濾波器是一種通過低頻輸入并阻止高頻輸入等的濾波器。五種類型是:低通
帶通
帶阻
高通
全通
過濾器也有不同的形狀。例如,它們的通帶上可能有波紋,或者它們可能具有平坦的過渡帶等。過濾器形狀
過濾器通常可按形狀分類如下:
貝塞爾: ? 與其他人相比,最平坦的群體延遲
巴特沃斯: 設(shè)計為在通帶內(nèi)具有最平坦的幅度響應(yīng); 也被稱為“最大平坦”
切比雪夫: 設(shè)計為在理想濾波器和實際濾波器之間具有最小誤差; 可以分為兩種類型:通帶中具有紋波的和阻帶中具有紋波的。
橢圓:在通帶和阻帶都有波紋,但是它們在通帶和阻帶之間有最快的過渡
選擇過濾器的形狀取決于所需的規(guī)格。例如,我們可能需要輸出信號幅度盡可能精確地跟隨通帶中的輸入信號幅度。在這種情況下,我們應(yīng)該使用巴特沃斯濾波器,即使它會給我們更多的過渡帶。
另一方面,我們可能希望輸出信號頻率精確地跟隨輸入信號的線性相位響應(yīng),因此我們應(yīng)該選擇貝塞爾濾波器。如果我們需要使用盡可能少的組件并且具有與其他濾波器相同的順序和轉(zhuǎn)換速度,則橢圓或切比雪夫濾波器可以工作,但是我們在通過或阻帶中會出現(xiàn)波紋。模擬和數(shù)字濾波器在另一方面,濾波器可以以兩種方式構(gòu)造:數(shù)字和模擬。
在模擬電路中,無源濾波器是電感器和電容器或電阻器的階梯。有源模擬濾波器可以是利用放大器或諧振器的結(jié)構(gòu)。只需使用已經(jīng)為設(shè)計模擬濾波器創(chuàng)建的表或應(yīng)用程序,即可確定它們的值。
可以使用IIR和FIR兩種方法創(chuàng)建數(shù)字濾波器。IIR(無限脈沖響應(yīng))濾波器是濾波器的類型,其中輸出取決于輸入和先前的輸出。
圖1. IIR濾波器。
數(shù)字濾波器的另一種濾波器實現(xiàn)是FIR(有限脈沖響應(yīng))。它們不使用反饋,輸出僅與當前和先前的輸入相關(guān)。關(guān)于穩(wěn)定性,FIR濾波器總是穩(wěn)定的, 因為它們的輸出僅與輸入有關(guān)。另一方面,他們需要高階以滿足與IIR相同的規(guī)格。
圖2. FIR濾波器
移動平均線
移動平均線是一個過濾器,它平均先前輸入的N個點并使用它們輸出。
如您所見,移動平均濾波器是一個FIR濾波器,其N系數(shù)為 1/N。具有不同N的一些移動平均濾波器的頻率響應(yīng)如圖3所示。
圖3.移動平均線的頻率響應(yīng)
移動平均(MA)濾波器的脈沖響應(yīng)在不在0到N內(nèi)的點中為零。
因此,MA過濾器的頻率響應(yīng)是:
截止頻率可估算為:
根據(jù)這些公式,截止頻率僅與N有關(guān)。隨著N增加,截止頻率降低但是時間增加。我們需要等待第N個周期才能得到正確的結(jié)果,所以N越大,我們需要更多的時間。隨著濾波器越來越清晰,其輸出需要達到穩(wěn)定狀態(tài)的時間也會增加。
所需設(shè)計的過濾和實現(xiàn)是FPGA設(shè)計中的廣泛主題。需要學習很多東西來設(shè)計合適的濾波器,然后在FPGA上以最少的資源使用或最快的速度實現(xiàn)它。
在本文中,我們將嘗試實現(xiàn)N點移動平均濾波器。我們假設(shè)N是一個參數(shù),可以在實施之前通過Xilinx ISE等CAD工具進行更改。
正如我們在圖2中看到的,FIR濾波器可以通過延遲鏈實現(xiàn),其長度為N,即FIR階,將系數(shù)乘以延遲線的乘法器,以及一些添加乘法器結(jié)果的加法器。這種架構(gòu)需要許多乘法器和加法器,這些乘法器和加法器在FPGA中受到限制,具體取決于您使用的FPGA(盡管即使是功能最強大的FPGA也是有限的)。
設(shè)計FIR濾波器需要進行一些研究以減少這些資源,因為在任何FPGA設(shè)計的每個階段都需要進行縮減。但是,我們不會涉及這個主題 - 相反,我們將使用另一種技巧設(shè)計我們的移動平均濾波器。在移動平均濾波器中,所有系數(shù)都是1/N。如果我們想要實現(xiàn)如圖2所示的濾波器,我們應(yīng)該制作一個抽頭延遲線并存儲N個最后輸入,然后將它們相乘1/N 并累加結(jié)果。但是,我們可以在FIFO中存儲N個最后輸入并累加它們,然后在每個周期中將它們乘以1 / N。通過這種方法,我們只需要一個N乘數(shù)。
代碼說明首先,我們有N,它是輸入點的數(shù)量,作為可以調(diào)整的參數(shù)。我們將添加這N個點以產(chǎn)生輸出。
我們還假設(shè)我們的輸入是28位格式,我們希望輸出格式相同。在處理添加N點時,我們可能會面臨一點點增長。添加兩個28位點會產(chǎn)生28位輸出和一個溢出位。因此,為了增加N個28位點,我們需要一個(log2(N)+28)位輸出。
假設(shè)所有N個點都相同并且添加它們就像將N乘以其中一個。這就是為什么我們實現(xiàn)一個“l(fā)og2”函數(shù),它只是簡單地計算其輸入的對數(shù)。通過N的對數(shù)知道,我們可以設(shè)置輸出長度。請注意,log2不是可綜合的方法,只能用于Xilinx ISE(即,Xilinx ISE計算log2,然后將結(jié)果用于其余的實現(xiàn))。
“l(fā)og2”函數(shù)如下代碼所示:
functionintegerlog2(inputintegerv);
beginlog2=0;
while(v>>log2) log2=log2+1;
endendfunction
現(xiàn)在我們設(shè)置輸入和輸出長度,我們需要創(chuàng)建一個抽頭線存儲N個之前和當前輸入。以下代碼將解決這個問題:
genvari;generatefor(i =0; i < N-1; i = i +1)begin: gdalways@(posedgeclock_in)beginif(reset==1'b1)begindata[i+1]<=0;endelsebegindata[i+1] <= data[i];endendendendgenerate
最后,我們需要一個加法器來匯總存儲在FIFO中的所有數(shù)據(jù)。這個階段有點棘手。如果我們想在每個時鐘周期都有輸出,我們需要制作一個組合電路,逐步將數(shù)據(jù)添加到FIFO中。下面顯示的代碼將執(zhí)行此操作:
genvarc;generateassignsummation_steps[0] = data[0] + data[1];for(c =0; c < N-2; c = c +1)begin: gdzassignsummation_steps[c+1] = summation_steps[c] + data[c+2];endendgenerate
但是,我們的目標FPGA(XC3S400)沒有這么多資源,在這個FPGA上合成這個模塊是不可行的。所以,我要讓問題變得更簡單些。假設(shè)我們希望輸出每N個時鐘周期更新一次。有了這個技巧,我們不再需要存儲所有收到的數(shù)據(jù)了。我們可以簡單地存儲總和并將其添加到每個周期的當前輸入中。以下代碼將起到作用:
always@(posedgeclock_in)beginif(reset)beginsignal_out_tmp<=0;
count<=0;
signal_out<=0;endelsebeginif(down_sample_clk==N_down_sample)beginif(countbegincount<=count+1'b1;
signal_out_tmp<=signal_out_tmp+signal_in;endelsebegincount<=0;
signal_out<=signal_out_tmp[27+N2:N2];
signal_out_tmp<=0;endendendend
在此代碼中,總和保存為signal_out_tmp,并將在每個周期添加到輸入。在N個點之后,輸出將變?yōu)閟ignal_out_tmp,并且該變量將被設(shè)置為零并開始再次存儲總和。
此方法使用非常低的資源,但其輸出將每N個周期更新一次。
模擬
考慮到速度,我們將使用Modelsim進行模擬。我們需要將Modelsim集成到Xilinx ISE。要執(zhí)行此操作,請轉(zhuǎn)到編輯>首選項>集成工具。在Model Tech Simulator部分,我們輸入Modelsim位置,我們就完成了,如圖4所示。
圖4.設(shè)置模型技術(shù)模擬器
Modelsim需要使用XILINX ISE庫才能模擬電路。為此,我們需要單擊項目上的FPGA模型,然后選擇Compile HDL Simulation Libraries,如圖5所示。
圖5.編譯HDL仿真庫
測試平臺包含在項目代碼中,您可以下載。在測試平臺中,我們假設(shè)輸入為步驟并保存輸出。在測試平臺上讀寫非常簡單,如下面的代碼所示。我們可以在測試平臺中使用fopen函數(shù)打開一個文件,然后使用fwrite函數(shù)寫入它。
f =$fopen("output.txt","w");
f2 =$fopen("time.txt","w");$fwrite(f,"%d %d\n",signal_in,signal_out);$fwrite(f2,"%d\n",cur_time);
fwrite中的格式很像C語言中的簡單printf函數(shù)。我們還將在測試平臺中使用$ time變量。使用$ time變量給出了可以寫入文本文件的當前時間。在模擬我們的項目之后,我們可以使用MATLAB中的書寫文件來確保它們是正確的。用MATLAB編寫的代碼首先讀取文件并繪制它們。
A = importdata('D:\low_test\output.txt');
B = importdata('D:\low_test\time.txt');
M2=A(:,2);
M1=A(:,1);
T=B(:,1)*10e-9;
M1=M1/(2^24);
M2=M2/(2^24);
plot(M1);
hold on;
plot(M2);
s=size(M1);
val=0;
t=0:s(1,1)-1;
t=t*50e-9;fori=405:s(1,1)if(abs(M1(i,1)-M2(i,1))<1*.1)
val=i;break;endendstepp=stepinfo(M2,t);
pp=stepp.RiseTime;
fc=.35/pp
cycles=val-405time=((cycles)*50)/1000
出于測試目的,我們首先使用輸入步驟模擬我們的工作臺,然后將輸入更改為正弦。圖顯示在圖6和圖7中。
圖6.步驟響應(yīng)
圖 7.Sin(x)* sin(x)響應(yīng)
從圖6中可以看出,在0.2ms之后,濾波器輸出變得與輸入幅度一樣高。圖6顯示了每N個周期的響應(yīng),因為輸出不會平滑變化。相反,它在第N個周期后發(fā)生變化。
在圖7中,因為輸入是6 * sin(x)* sin(x),我們知道這個輸入的DC偏移是3,因為我們的低通濾波器輸出是3。
CIC過濾器
級聯(lián)積分梳狀濾波器是一種硬件高效的FIR數(shù)字濾波器。
CIC濾波器由相同數(shù)量級的理想積分濾波器和抽取器組成。CIC濾波器架構(gòu)如圖8所示。
圖8. CIC過濾器圖像
我們可以通過使用CIC濾波器和重寫移動平均方程來優(yōu)化我們的移動平均低通濾波器,如下所示:
該架構(gòu)由梳狀部分(c [n] = x [n] -x [nN])和積分器(y [n] = y [n-1] + c [n])組成,因此我們可以在這里使用CIC架構(gòu)。在這種架構(gòu)中,我們將加法器減少到只有三個部分,這樣我們就可以在每個周期都有輸出,這是CIC濾波器的神奇之處。
使用CIC過濾器拓撲優(yōu)化移動平均值。我們可以使用以下Verilog代碼在硬件中實現(xiàn)上述等式:wiresigned[27+N2:0] ? signal_out_tmp_2=signal_out_tmp_3+signal_in-data[N-1];
具有sin(x)* sin(x)輸入的新結(jié)構(gòu)的輸出如圖9所示。
圖9. CIC輸出
結(jié)論
數(shù)字和模擬路由都可用于過濾。每個都有自己的優(yōu)勢,但數(shù)字過濾允許重新編程和較小的實現(xiàn)區(qū)域。在本文中,我們首先研究了構(gòu)建過濾器的方法,然后以最簡單的方式實現(xiàn)了移動平均過濾器。最后,我們使用CIC架構(gòu)對其進行了優(yōu)化。
總結(jié)
以上是生活随笔為你收集整理的c语言 截止频率6低通滤波器,用Verilog在FPGA上实现低通滤波器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 移植ffplay媒体播放器和sdl2到A
- 下一篇: 阿里测试开发9年,我的升级打怪之路。