您當前的位置:首頁 > 書法

FIR濾波器理論與實現程式碼(VHDL)

作者:由 HHXx 發表于 書法時間:2017-05-27

推薦使用電腦瀏覽。

數字濾波器

是一個作用範圍很廣的功能模組,當然FPGA發展到現在,有了很多很實用的濾波器IP核,方便開發者進行專案的開發,IP核的使用不在文章的探討範圍n。

在這裡先推薦一下matlab中的fda(filter design & analysis)工具,對於濾波器的設計和理解會有很大的幫助。

本文主要講FIR數字濾波器的基礎理論,自己的一些理解和程式碼示例。

FIR是

有限脈衝響應

(Finite Impulse Response),即訊號輸入FIR濾波器的響應最終會趨於0,通俗點講就是在每個取樣時刻累加次數是有限的,這個可以結合下面的公式進行理解。FIR因為其具有很好的

相位線性的特性

線性相位

通俗講就是很多通帶訊號同時輸入到FIR濾波器中,經過一定時間後又同時輸出)使其在工程中得到了廣泛的使用。

FIR濾波器本質上就是有限線性卷積的過程,對於係數f[n]有(M+1)個的FIR輸出和輸入時間序列x[n]的關係公式可以表示成:

FIR濾波器理論與實現程式碼(VHDL)

FIR濾波器理論與實現程式碼(VHDL)

時域上是

卷積過程

(這裡*號是卷積,

翻轉滑動相乘累加

),這裡根據公式對FPGA中濾波器

輸出最大不溢位位寬

的計算做個介紹,首先假設輸入x[n-k]是

幅值

為1,符號與f[k]相同的資料,則

y[n]=\sum_{k=0}^{M}{|f[k]|}

。此時y[n]就是輸出與輸入間幅值差最大的時候,將其換算成

最小位寬差

W= log_{2}(\sum_{k=0}^{M}{|f[k]|} )

,輸出位寬

最小

為輸入訊號位寬加W(向上取整)。對於時域卷積公式對於理解FIR濾波不是很好,現在將公式進行z變換(卷積z變換後就是相乘)後再理解:

FIR濾波器理論與實現程式碼(VHDL)

FIR濾波器理論與實現程式碼(VHDL)

變換到z域(這裡可以理解為

頻域

)後理解起來就很簡單了,畫張頻域圖來幫助理解。

FIR濾波器理論與實現程式碼(VHDL)

FIR濾波器理論與實現程式碼(VHDL)

這就是理論上(係數取值從負無窮到正無窮)濾波器濾波的原理。因為FIR濾波器係數實際工程中無法選擇無數個,所以導致工程濾波器存在過渡帶,通帶會有抖動,

阻帶

是按照一定比例衰減等等為問題。而工程FIR濾波器設計就是透過選擇不同的係數和其長度來平衡這些問題達到設計需求。

現在我們有了公式,要做的就是將公式轉化為工程,這個轉化過程是多種多樣的,這裡只做其中直接形和轉置形介紹。首先將上述卷積公式進行展開:

FIR濾波器理論與實現程式碼(VHDL)

FIR濾波器理論與實現程式碼(VHDL)

為了方便畫圖和理解,我們這裡假設M=2,公式變成:

FIR濾波器理論與實現程式碼(VHDL)

FIR濾波器理論與實現程式碼(VHDL)

將上面等式的結構畫出來是:

FIR濾波器理論與實現程式碼(VHDL)

FIR濾波器理論與實現程式碼(VHDL)

Unit Delay代表這裡有一個延遲。這裡假設三個係數分別是{-2,4,-2},公式和結構都非常清晰和簡單,根據上面的結構圖將其轉化成VHDL語言程式碼:

——工程名:直接形FIR濾波器

——濾波係數:f[0-2]={-2,4,-2}

library

ieee

use

ieee。std_logic_1164。

all

use

ieee。std_logic_arith。

all

use

ieee。std_logic_unsigned。

all

entity

fir_Direct

is

generic

w0

integer

:=

11

——濾波器輸出位寬

w1

integer

:=

13

——中間變數的位寬

);

port

clk

in

std_logic

rstn

in

std_logic

data_In

in

std_logic_vector

7

downto

0

);

data_Out

out

std_logic_vector

w0

-

1

downto

0

);

end

fir_Direct

architecture

beha

of

fir_Direct

is

type

array_3x8

is

array

0

to

2

of

std_logic_vector

7

downto

0

);

——定義一個數組

type

array_2x4

is

array

integer

range

<>

of

std_logic_vector

3

downto

0

);

signal

tap

array_3x8

signal

tap_Add

std_logic_vector

8

downto

0

);

signal

tap_Delay

std_logic_vector

8

downto

0

);

signal

c_t_mul1

c_t_mul2

data_OTemp

std_logic_vector

w1

-

1

downto

0

);

signal

coef

array_2x4

0

to

1

);

begin

coef

0

<=

conv_std_logic_vector

-

2

4

);

coef

1

<=

conv_std_logic_vector

4

4

);

process

clk

rstn

begin

if

rstn

=

‘0’

then

for

i

in

0

to

2

loop

——loop 是在一個時鐘內迴圈一遍

tap

i

<=

others

=>

‘0’

);

end

loop

tap_Add

<=

others

=>

‘0’

);

tap_Delay

<=

others

=>

‘0’

);

elsif

rising_edge

clk

then

tap

0

<=

data_In

tap

1

to

2

<=

tap

0

to

1

);

——tap(0)對應x[n],tap(1)對應x[n-1],後面依次對應

—— data_OTemp <= tap(0)*(-2) + tap(1)*4 + tap(2)*(-2)

——上面的寫法資源佔用較多,執行速度也比較慢

——係數對稱節約乘法器

tap_Add

<=

tap

0

)(

7

&

tap

0

))

+

tap

2

)(

7

&

tap

2

));

tap_Delay

<=

tap

1

)(

7

&

tap

1

);

c_t_mul1

<=

signed

tap_Add

*

signed

coef

0

));

c_t_mul2

<=

signed

tap_Delay

*

signed

coef

1

));

data_OTemp

<=

c_t_mul1

+

c_t_mul2

data_Out

<=

data_OTemp

w0

-

1

downto

0

);

end

if

end

process

end

beha

下面介紹一下轉置型別的FIR濾波器,轉置型別FIR濾波器相當於交換輸入輸出,顛倒訊號流方向,將加法器移動到延遲後面,

轉置型別FI

R結構圖如下:

FIR濾波器理論與實現程式碼(VHDL)

FIR濾波器理論與實現程式碼(VHDL)

很容易看出轉置結構最終轉化為公式和直接形是等效的,所不同的是輸入不需要額外的移位暫存器,為FPGA工程提供了一種新的結構,這種結構程式碼效率和資源量都要優於直接形。根據新的結構圖,將其轉化為VHDL程式碼:

——工程名:轉置形FIR濾波器

——濾波係數:f[0-2]={-2,4,-2}

library

ieee

use

ieee。std_logic_1164。

all

use

ieee。std_logic_arith。

all

use

ieee。std_logic_unsigned。

all

entity

fir_Transposed

is

generic

w0

integer

:=

11

——濾波器輸出位寬

w1

integer

:=

12

——中間變數的位寬

);

port

clk

in

std_logic

rstn

in

std_logic

data_In

in

std_logic_vector

7

downto

0

);

data_Out

out

std_logic_vector

w0

-

1

downto

0

);

end

fir_Transposed

architecture

beha

of

fir_Transposed

is

type

array_3x8

is

array

0

to

2

of

std_logic_vector

7

downto

0

);

type

array_3xx

is

array

0

to

2

of

std_logic_vector

w1

-

1

downto

0

);

signal

sum

c_t_mul

array_3xx

signal

tap

array_3x8

begin

c_t_mul

0

<=

signed

tap

0

))

*

signed

conv_std_logic_vector

-

2

4

));

c_t_mul

1

<=

signed

tap

0

))

*

signed

conv_std_logic_vector

4

4

));

c_t_mul

2

<=

c_t_mul

0

);

process

clk

rstn

begin

if

rstn

=

‘0’

then

tap

0

<=

others

=>

‘0’

);

for

i

in

0

to

2

loop

sum

i

<=

others

=>

‘0’

);

end

loop

elsif

rising_edge

clk

then

tap

0

<=

data_In

sum

0

<=

c_t_mul

2

);

for

i

in

1

to

2

loop

sum

i

<=

sum

i

-

1

+

c_t_mul

2

-

i

);

end

loop

data_Out

<=

sum

2

)(

w0

-

1

downto

0

);

end

if

end

process

end

beha

標簽: logic  Tap  濾波器  FIR  vector