巴特沃斯滤波器是电子滤波器的一种。巴特沃斯滤波器的特点是通频带的频率响应曲线最平滑。这种滤波器最先由英国工程师斯替芬·巴特沃斯(Stephen Butterworth)在1930年发表在英国《无线电工程》期刊的一篇论文中提出的。
巴特沃斯滤波器的特点是通频带内的频率响应曲线最大限度平坦,没有起伏,而在阻频带则逐渐下降为零。 在振幅的对数对角频率的波得图上,从某一边界角频率开始,振幅随着角频率的增加而逐步减少,趋向负无穷大。
一阶巴特沃斯滤波器的衰减率为每倍频6分贝,每十倍频20分贝。二阶巴特沃斯滤波器的衰减率为每倍频12分贝、 三阶巴特沃斯滤波器的衰减率为每倍频18分贝、如此类推。巴特沃斯滤波器的振幅对角频率单调下降,并且也是唯一的无论阶数,振幅对角频率曲线都保持同样的形状的滤波器。只不过滤波器阶数越高,在阻频带振幅衰减速度越快。其他滤波器高阶的振幅对角频率图和低级数的振幅对角频率有不同的形状。
数字化巴特沃斯滤波器是IIR滤波器一种,在数字信号处理中,常用二阶设计(基本型),根据巴特沃斯滤波的传递函数以及滤波器的关键参数,例如采样频率、截止频率等利用Matlab滤波器设计软件可以求出传递函数的关键系数。根据传递函数的递推公式,利用FPGA可以设计数字巴特沃斯滤波器如下:
-- 巴特沃斯2阶滤波器的方程表达式:
-- u(n)=x(n)-a(1)*u(n-1)-a(2)*u(n-2);
-- y(n)=b(0)*u(n)+b(1)*u(n-1)+b(2)*u(n-2);
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity butter2_filter is
port
(
clk: in std_logic; --//系统时钟信号
rstn: in std_logic; --//系统复位信号
in_filter_signal: in std_logic_vector(39 downto 0); --//待滤波信号
in_filter_enb: in std_logic;
out_filter_result: out std_logic_vector(39 downto 0);
out_filter_rdy: buffer std_logic
);
end butter2_filter;
architecture rtl of butter2_filter is
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
--definition constant
--b 61.9114 123.8226 61.9114 放大65536倍
--a 65536 -125252 59964 放大65536倍
constant CONST_BUTTER_A1: std_logic_vector(31 downto 0):=X"0001E944";
constant CONST_BUTTER_A2: std_logic_vector(31 downto 0):=X"0000EA3C";
constant CONST_BUTTER_B0: std_logic_vector(31 downto 0):=X"0000003E";
constant CONST_BUTTER_B1: std_logic_vector(31 downto 0):=X"0000007C";
constant CONST_BUTTER_B2: std_logic_vector(31 downto 0):=X"0000003E";
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
-- definition variable
signal step10: std_logic_vector(3 downto 0);
signal temp10_filter_enb: std_logic;
signal temp10_mult_enb: std_logic;
signal temp10_n: std_logic_vector(1 downto 0);
signal temp10_n1: std_logic_vector(55 downto 0);
signal temp10_n2: std_logic_vector(55 downto 0);
signal temp10_n3: std_logic_vector(55 downto 0);
signal temp10_sum: std_logic_vector(87 downto 0);
signal temp10_mult1: std_logic_vector(31 downto 0);
signal temp10_mult2: std_logic_vector(55 downto 0);
signal temp10_sign_flg: std_logic;
signal temp11_mult_enb: std_logic;
signal temp11_product: std_logic_vector(87 downto 0);
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
begin
proc10:process(clk,rstn)
begin
if(rstn='0')then
out_filter_result <= (others=>'0');
temp10_n <= (others=>'0');
temp10_n1 <= (others=>'0');
temp10_n2 <= (others=>'0');
temp10_n3 <= (others=>'0');
temp10_mult_enb <= '0';
step10 <= "0000";
temp10_filter_enb <= '0';
out_filter_rdy <= '0';
temp10_mult1 <= (others=>'0');
temp10_mult2 <= (others=>'0');
temp10_sum <= (others=>'0');
temp10_sign_flg <= '0';
elsif(clk'event and clk='1')then
if(step10="0000")then
if(temp10_filter_enb/=in_filter_enb)then
temp10_filter_enb <= in_filter_enb;
step10 <= "0001";
temp10_mult_enb <= not temp10_mult_enb;
temp10_mult1 <= CONST_BUTTER_A1;
temp10_mult2 <= temp10_n2;
if(in_filter_signal(39)='1')then
temp10_n1 <= X"00000000000000" - (X"FFFF"&in_filter_signal);
temp10_sign_flg <= '1';
else
temp10_n1 <= (X"0000"&in_filter_signal);
temp10_sign_flg <= '0';
end if;
--temp10_sum <= (others=>'0');
end if;
elsif(step10="0001")then
if(temp10_n="01")then
step10 <= "0010";
temp10_n <= (others=>'0');
else
temp10_n <= temp10_n + '1';
end if;
elsif(step10="0010")then
temp10_n <= (others=>'0');
temp10_mult_enb <= not temp10_mult_enb;
temp10_mult1 <= CONST_BUTTER_A2;
step10 <= "0011";
temp10_n1 <= temp10_n1 + temp11_product(71 downto 16);
temp10_mult2 <= temp10_n3;
elsif(step10="0011")then
if(temp10_n="01")then
step10 <= "0100";
temp10_n <= (others=>'0');
else
temp10_n <= temp10_n + '1';
end if;
elsif(step10="0100")then
step10 <= "0101";
temp10_n1 <= temp10_n1 - temp11_product(71 downto 16);
elsif(step10="0101")then
temp10_n <= (others=>'0');
temp10_mult_enb <= not temp10_mult_enb;
temp10_mult1 <= CONST_BUTTER_B0;
step10 <= "0110";
temp10_mult2 <= temp10_n1;
elsif(step10="0110")then
if(temp10_n="01")then
step10 <= "0111";
temp10_n <= (others=>'0');
else
temp10_n <= temp10_n + '1';
end if;
elsif(step10="0111")then
temp10_mult_enb <= not temp10_mult_enb;
temp10_mult1 <= CONST_BUTTER_B1;
step10 <= "1000";
temp10_sum <= temp11_product(87 downto 0);
temp10_mult2 <= temp10_n2;
elsif(step10="1000")then
if(temp10_n="01")then
step10 <= "1001";
temp10_n <= (others=>'0');
else
temp10_n <= temp10_n + '1';
end if;
elsif(step10="1001")then
temp10_mult_enb <= not temp10_mult_enb;
temp10_mult1 <= CONST_BUTTER_B2;
step10 <= "1010";
temp10_sum <= temp10_sum + temp11_product(87 downto 0);
temp10_mult2 <= temp10_n3;
elsif(step10="1010")then
if(temp10_n="01")then
step10 <= "1011";
temp10_n <= (others=>'0');
else
temp10_n <= temp10_n + '1';
end if;
elsif(step10="1011")then
step10 <= "1110";
temp10_sum <= temp10_sum + temp11_product(87 downto 0);
--elsif(step10="1110")
else
out_filter_rdy <= not out_filter_rdy;
temp10_n3 <= temp10_n2;
temp10_n2 <= temp10_n1;
step10 <= "0000";
if(temp10_sign_flg='1')then
out_filter_result <= X"0000000000" - temp10_sum(55 downto 16);
else
out_filter_result <= temp10_sum(55 downto 16);
end if;
end if;
end if;
end process proc10;
proc11:process(clk,rstn)
begin
if(rstn='0')then
temp11_mult_enb <= '0';
temp11_product <= (others=>'0');
elsif(clk'event and clk='1')then
if(temp11_mult_enb/=temp10_mult_enb)then
temp11_mult_enb <= temp10_mult_enb;
temp11_product <= temp10_mult1 * temp10_mult2;
end if;
end if;
end process proc11;
end rtl ;
总结:巴特沃斯滤波器是基本型的二阶IIR滤波器,FPGA程序中设计为一个数据进,一个数据出的方式。数据进入有效,根据使能信号边缘判断。数据出信号有效,根据数据结果的准备信号边缘判断。整个滤波器进程大概需要20个时钟周期!