VHDL’de FIR Filtre Tasarımı

Aşağıda 10 Hz ve 10 Khz frekansında iki cosin girişinin 100 KHz ile örneklenerek toplandığı VHDL kodu oluşturulmuştur. Kodda 16. dereceden alçak geçiren süzgeç kullanılarak toplam sinyalden 10 Hz’lik sinyal ayrıştırılmaya çalışılmıştır. Aşağıdaki şekilde üstte verilen çıktı toplam sinyal değerini göstermektedir. Alttaki sinyal ise toplam sinyalin filtreden geçirildikten sonraki halini göstermektedir. Filtre çıkışı incelendiğinde başarılı bir süzgeçleme işlemi yapıldığı görülmektedir.

low_filter

  1. library IEEE;
  2. use IEEE.STD_LOGIC_1164.ALL;
  3. use IEEE.STD_LOGIC_ARITH.ALL;
  4. use IEEE.STD_LOGIC_UNSIGNED.ALL;
  5. use IEEE.MATH_REAL.ALL;
  6.  
  7.  
  8. entity FIR_filter is
  9. end FIR_filter;
  10.  
  11. architecture Behavioral of FIR_filter is
  12.    
  13.         constant CLK_PERIOD : time := 10 us; -- 100 KHz
  14.         constant Fs_cos_1 : integer := 10; -- 10 KHz
  15.         constant Fs_cos_2 : integer := 10000; -- 10 Hz
  16.         constant Filter_Order : integer := 16;
  17.         constant DATA_WIDTH : integer := 16;
  18.        
  19.         signal theta_1 : real := 0.0;
  20.         signal theta_2 : real := 0.0;
  21.         signal n_i : integer := 0;
  22.         signal clk : std_logic := '0';
  23.         signal sum_data : real := 0.0;
  24.         signal low_filter_out : integer := 0;
  25.         signal sum_data_int : integer := 0;
  26.        
  27.        
  28.         type Shft_Reg_t is array (0 to Filter_Order) of integer;
  29.         signal Shft_Reg : Shft_Reg_t := (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  30.        
  31.         type Filt_Coef_t is array (0 to Filter_Order) of integer;
  32.         signal Filt_Ceof : Filt_Coef_t := (1, 2, 3, 5, 8, 10, 13, 14, 15, 14, 13, 10, 8, 5, 3, 2, 1);
  33.        
  34.         function f_Shift_Reg(Shft_Reg : Shft_Reg_t; in_data : integer) return Shft_Reg_t is
  35.             variable Shft_Reg_v : Shft_Reg_t;
  36.              
  37.         begin
  38.             Shft_Reg_v := Shft_Reg;
  39.             for n_i in 0 to Filter_Order - 1 loop
  40.                 Shft_Reg_v(n_i) := Shft_Reg_v(n_i + 1);
  41.             end loop;
  42.             Shft_Reg_v(Filter_Order) := in_data;
  43.             return Shft_Reg_v;
  44.        
  45.         end f_Shift_Reg;
  46.  
  47.         function f_Filt_Conv(Shft_Reg : Shft_Reg_t; Filt_Ceof : Filt_Coef_t) return integer is
  48.             variable Shft_Reg_v  : Shft_Reg_t;
  49.             variable Filt_Ceof_v : Filt_Coef_t;
  50.             variable Sum_Conv : integer := 0;
  51.            
  52.         begin
  53.             Shft_Reg_v  := Shft_Reg;
  54.             Filt_Ceof_v := Filt_Ceof;
  55.             Sum_Conv := 0;
  56.             for n_i in 0 to Filter_Order loop
  57.                 Sum_Conv := Sum_Conv + Shft_Reg_v(n_i) * Filt_Ceof_v(n_i);             
  58.             end loop;
  59.             return (Sum_Conv / 128);
  60.        
  61.         end f_Filt_Conv;
  62. begin
  63.    
  64.     process
  65.     begin
  66.         clk <= '1';
  67.         wait for CLK_PERIOD / 2;
  68.         clk <= '0';
  69.         wait for CLK_PERIOD / 2;
  70.     end process;
  71.    
  72.     process(clk)
  73.     begin
  74.         if rising_edge(clk) then
  75.             n_i <= n_i + 1;
  76.             theta_1 <= real(n_i) / real(Fs_cos_1) * 1.0 * 2.0 * MATH_PI;
  77.             theta_2 <= real(n_i) / real(Fs_cos_2) * 1.0 * 2.0 * MATH_PI;
  78.             sum_data <= cos(-theta_1) + cos(-theta_2);
  79.             sum_data_int <= integer(round(sum_data * real(2**(DATA_WIDTH - 1))));
  80.             Shft_Reg <= f_Shift_Reg(Shft_Reg, sum_data_int);
  81.             low_filter_out <= f_Filt_Conv(Shft_Reg, Filt_Ceof);
  82.         end if;
  83.     end process;
  84.  
  85.  
  86. end Behavioral;

Uygulamaya ait Matlab kodu aşağıda verilmiştir.

  1.  
  2. f_s = 100000;
  3. n_t = 1 / f_s : 1 / f_s : 1;
  4.  
  5. f_1 = 10;
  6. f_2 = 10000;
  7.  
  8. A = cos( 2 * pi * n_t  * f_1 );
  9.  
  10. B = 1 * cos( 2 * pi * n_t  * f_2 );
  11.  
  12. C = A + B;
  13.  
  14. X = fir1(16, 500 / f_s, 'low');
  15. for n_i = 1 : length(C) - length(X)
  16.     D(n_i) = sum(C(n_i : n_i + length(X)- 1) .* X);
  17. end
  18.  




Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir