Jump to content

    

Реализация КИХ фильтра VHDL

Подскажите пожалуйста пример расчета и реализации КИХ фильтра на VHDL.

Поскольку задачка для меня новая интересует больше пример расчета фильтра

в части получения весовых коэффициентов для дальнейшего прямого использования

в коде на VHDL.

 

Спасибо.

Share this post


Link to post
Share on other sites
Поскольку задачка для меня новая интересует больше пример расчета фильтра

в части получения весовых коэффициентов для дальнейшего прямого использования

в коде на VHDL.

 

кхм, целые тома написаны про синтез цифровых фильтров, а вы хотите в двух словах ? любой учебник по DSP обработке в руки, раздел "Синтез цифровых фильтров" и курить.

 

Ну или по простому матлаб - filter design tool и хелп к нему %)

Share this post


Link to post
Share on other sites
Подскажите пожалуйста пример расчета и реализации КИХ фильтра на VHDL.

Поскольку задачка для меня новая интересует больше пример расчета фильтра

в части получения весовых коэффициентов для дальнейшего прямого использования

в коде на VHDL.

 

Спасибо.

В качестве реализации - свoй кoд или пoкупнoe (вылeчeннoe) ядp0.

Расчет коэффициентов производится внешними программами и загружается "снаружи" либо переключаются соответствующие наборы из предварительно заполненной памяти. ИМХО Рассчитывать коэффициенты на VHDL - неблагородное и бесполезное занятие.

Удачи!

Share this post


Link to post
Share on other sites

В матлаб я уже пробовал. Вроде там не сложно. Выдает весовые коэффициенты.

Преобразовать их в код вроде тоже смогу. Но их там шибко много.

Простейший код на VHDL тоже посмотрел - умножить просуммировать.

Но это в простейшем случае. Наверняка код реального фильтра выглядит посложнее.

Нет ли где примера VHDL в другом варианте? Например с децимацией.

Буду благодарен за пример кода.

Share this post


Link to post
Share on other sites
В матлаб я уже пробовал. Вроде там не сложно. Выдает весовые коэффициенты.

внимательно посмотрите fdatool. Он позволяет генерировать фильтр с экспортом в VHDL . Поиграйтесь и на основе его сделайте свой.

Share this post


Link to post
Share on other sites
В матлаб я уже пробовал. Вроде там не сложно. Выдает весовые коэффициенты.

Преобразовать их в код вроде тоже смогу. Но их там шибко много.

Простейший код на VHDL тоже посмотрел - умножить просуммировать.

Но это в простейшем случае. Наверняка код реального фильтра выглядит посложнее.

Нет ли где примера VHDL в другом варианте? Например с децимацией.

Буду благодарен за пример кода.

пример взят из книги:

Оговариваюсь сразу он простой как "пять копеек", без всяких наворотов и какой-либо оптимизации.

описание во вложении

 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity fir is

Port(   din: in std_logic_vector(7 downto 0);
       sout: out std_logic_vector(15 downto 0);
       r: in std_logic;
       c: in std_logic);
end fir;

architecture Behavioral of fir is

constant h00 : std_logic_vector(7 downto 0) := "00000000";
constant h01 : std_logic_vector(7 downto 0) := "00000001";
constant h02 : std_logic_vector(7 downto 0) := "00000100";
constant h03 : std_logic_vector(7 downto 0) := "00001111";
constant h04 : std_logic_vector(7 downto 0) := "00100100";
constant h05 : std_logic_vector(7 downto 0) := "01000010";
constant h06 : std_logic_vector(7 downto 0) := "01100100";
constant h07 : std_logic_vector(7 downto 0) := "01111100";
constant h08 : std_logic_vector(7 downto 0) := "01111111";
constant h09 : std_logic_vector(7 downto 0) := "01101010";
constant h10 : std_logic_vector(7 downto 0) := "01000010";
constant h11 : std_logic_vector(7 downto 0) := "00100011";
constant h12 : std_logic_vector(7 downto 0) := "11101100";
constant h13 : std_logic_vector(7 downto 0) := "11010110";
constant h14 : std_logic_vector(7 downto 0) := "11010101";
constant h15 : std_logic_vector(7 downto 0) := "11100011";
constant h16 : std_logic_vector(7 downto 0) := "11110111";
constant h17 : std_logic_vector(7 downto 0) := "00001010";
constant h18 : std_logic_vector(7 downto 0) := "00010100";
constant h19 : std_logic_vector(7 downto 0) := "00010011";
constant h20 : std_logic_vector(7 downto 0) := "00001100";
constant h21 : std_logic_vector(7 downto 0) := "00000010";
constant h22 : std_logic_vector(7 downto 0) := "11111000";
constant h23 : std_logic_vector(7 downto 0) := "11110101";

signal x00, x01, x02, x03,x04, x05, x06, x07,
      x08, x09, x10, x11, x12, x13, x14, x15,
      x16, x17, x18, x19, x20, x21,
      x22, x23 : std_logic_vector(7 downto 0);

signal m00, m01, m02, m03, m04, m05, m06, m07,
      m08, m09, m10, m11, m12, m13, m14, m15,
      m16, m17, m18, m19, m20, m21,
      m22, m23 : std_logic_vector(15 downto 0); 
      
begin

m00 <= (signed(x00)*signed(h00));
m01 <= (signed(x01)*signed(h01));
m02 <= (signed(x02)*signed(h02));
m03 <= (signed(x03)*signed(h03));
m04 <= (signed(x04)*signed(h04));
m05 <= (signed(x05)*signed(h05));
m06 <= (signed(x06)*signed(h06));
m07 <= (signed(x07)*signed(h07));
m08 <= (signed(x08)*signed(h08));
m09 <= (signed(x09)*signed(h09));
m10 <= (signed(x10)*signed(h10));
m11 <= (signed(x11)*signed(h11));
m12 <= (signed(x12)*signed(h12));
m13 <= (signed(x13)*signed(h13));
m14 <= (signed(x14)*signed(h14));
m15 <= (signed(x15)*signed(h15));
m16 <= (signed(x16)*signed(h16));
m17 <= (signed(x17)*signed(h17));
m18 <= (signed(x18)*signed(h18));
m19 <= (signed(x19)*signed(h19));
m20 <= (signed(x20)*signed(h20));
m21 <= (signed(x21)*signed(h21));
m22 <= (signed(x22)*signed(h22));
m23 <= (signed(x23)*signed(h23));

sout <= (signed(m00)+signed(m01)+signed(m02)+signed(m03)

        +signed(m04)+signed(m05)+signed(m06)+signed(m07)
       
       +signed(m08)+signed(m09)+signed(m10)+signed(m11)

       +signed(m12)+signed(m13)+signed(m14)+signed(m15)

       +signed(m16)+signed(m17)+signed(m18)+signed(m19)

       +signed(m20)+signed(m21)+signed(m22)+signed(m23));

           
process(c,r)
    begin
    if r = '1' then
               x00 <= (others => '0');
              x01 <= (others => '0');
              x02 <= (others => '0');
              x03 <= (others => '0');
              x04 <= (others => '0');
              x05 <= (others => '0');
              x06 <= (others => '0');
              x07 <= (others => '0');
              x08 <= (others => '0');
              x09 <= (others => '0');
              x10 <= (others => '0');
              x11 <= (others => '0');
              x12 <= (others => '0');
              x13 <= (others => '0');
              x14 <= (others => '0');
              x15 <= (others => '0');
              x16 <= (others => '0');
              x17 <= (others => '0');
              x18 <= (others => '0');
              x19 <= (others => '0');
              x20 <= (others => '0');
              x21 <= (others => '0');
              x22 <= (others => '0');
              x23 <= (others => '0');

       elsif (c'event and c ='1') then
                x00(7 downto 0) <= din(7 downto 0);
            x01(7 downto 0) <= x00(7 downto 0);
            x02(7 downto 0) <= x01(7 downto 0);
            x03(7 downto 0) <= x02(7 downto 0);
            x04(7 downto 0) <= x03(7 downto 0);
            x05(7 downto 0) <= x04(7 downto 0);
            x06(7 downto 0) <= x05(7 downto 0);
            x07(7 downto 0) <= x06(7 downto 0);
            x08(7 downto 0) <= x07(7 downto 0);
            x09(7 downto 0) <= x08(7 downto 0);
            x10(7 downto 0) <= x09(7 downto 0);
            x11(7 downto 0) <= x10(7 downto 0);
            x12(7 downto 0) <= x11(7 downto 0);
            x13(7 downto 0) <= x12(7 downto 0);
            x14(7 downto 0) <= x13(7 downto 0);
            x15(7 downto 0) <= x14(7 downto 0);
            x16(7 downto 0) <= x15(7 downto 0);
            x17(7 downto 0) <= x16(7 downto 0);
            x18(7 downto 0) <= x17(7 downto 0);
            x19(7 downto 0) <= x18(7 downto 0);
            x20(7 downto 0) <= x19(7 downto 0);
            x21(7 downto 0) <= x20(7 downto 0);
            x22(7 downto 0) <= x21(7 downto 0);
            x23(7 downto 0) <= x22(7 downto 0);
    end if;

    end process;
     
end Behavioral;

---TESTBENCH ДЛЯ ТЕСТИРОВАНИЯ ФИЛЬТРА ------------------------

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;

ENTITY fir_test_vhd_tb IS
END fir_test_vhd_tb;

ARCHITECTURE behavior OF fir_test_vhd_tb IS 

    COMPONENT fir
    PORT(
        din : IN std_logic_vector(7 downto 0);
        r : IN std_logic;
        c : IN std_logic;          
        sout : OUT std_logic_vector(15 downto 0)
        );
    END COMPONENT;

    SIGNAL din :  std_logic_vector(7 downto 0);
    SIGNAL sout :  std_logic_vector(15 downto 0);
    SIGNAL r :  std_logic;
    SIGNAL c :  std_logic;

BEGIN

    uut: fir PORT MAP(
        din => din,
        sout => sout,
        r => r,
        c => c  );

         process begin
                for i in 0 to 500 loop
            c <= '0'; wait for 50 ns;
            c <= '1'; wait for 50 ns;
            end loop;
      end process;

      process begin
              r <= '1'; wait for 10 ns;
            r <= '0';
            din <= "00000001";wait for 100 ns;
            din <= "00000000";wait for 5000 ns;
      end process;
END;

KIX.doc

Share this post


Link to post
Share on other sites
пример взят из книги:

 

плохой пример, хуже структуру фильтра с постоянными коэффициентами для фпга, не придумать %)

Share this post


Link to post
Share on other sites

Я этот пример уже рассматривал. Он простейший. Скорее всего просто для

того, чтобы уяснить сам процесс. Наверняка реально (нормальный применяемый в жизни)

VHDL код выглядит посложнее. Константы должны быть в памяти. Сдвиговый регистр

мне кажется там совсем не годится и т. д. Как это делается нормально? Посмотреть бы.

внимательно посмотрите fdatool. Он позволяет генерировать фильтр с экспортом в VHDL . Поиграйтесь и на основе его сделайте свой.

Спасибо посмотрю.

Share this post


Link to post
Share on other sites
Наверняка реально (нормальный применяемый в жизни)

VHDL код выглядит посложнее. Константы должны быть в памяти. Сдвиговый регистр

мне кажется там совсем не годится и т. д. Как это делается нормально? Посмотреть бы.

 

Все зависит от требований к фильтру : ресурс, тактовая/символьная, задержка выхода. Если требуется задержка пару символов, при тактовая/символьная == 1, то никакая память не поможет. А схемы построения стандартны, есть во многих учебниках по DSP обработке. Когда то давно на форуме выкладывал 4 возможные схемы фильтров, правда на SV. Пользуйтесь поиском.

Share this post


Link to post
Share on other sites
Я этот пример уже рассматривал. Он простейший. Скорее всего просто для

того, чтобы уяснить сам процесс. Наверняка реально (нормальный применяемый в жизни)

VHDL код выглядит посложнее. Константы должны быть в памяти. Сдвиговый регистр

мне кажется там совсем не годится и т. д. Как это делается нормально? Посмотреть бы.

 

Спасибо посмотрю.

Если делаете на xilinx, сомтрите user guide на DSP48 на соответствующие семейство, там есть ссылки на код VHDL. Правда, там нет фильтров с децимацией, но за основу их фильтр взять можно и поменять логику адресации памяти.

Share this post


Link to post
Share on other sites

Пользовался ли кто fir_compiler-v3.1.0 который Альтера держит на своем фтп?

Будет ли с него толк?

 

Проверил - все красиво коэффициенты (в памяти не в памяти), характеристика, но сам нормальный vhdl код не дает.

Лицензия нужна.

 

Похоже нужно что то лепить самому.

Когда то давно на форуме выкладывал 4 возможные схемы фильтров, правда на SV

Искал не нашел. Может плохо искал.

Edited by Acvarif

Share this post


Link to post
Share on other sites

Кстати, немного не в тему, но посмотрите еще в сторону Distributed Arithmetic (в инете много чего есть)

 

Вот поковырялся дома в файлах...

Вообщем смотрите тут - http://www.ece.unm.edu/signals/Homeworks/

(FIR Filter Using Distributed Arithmetic)

Читать надо - FIR Filter Using Distributed Arithmetic v3.doc

 

Если еще что надо по DA - могу подкинуть пару статей.

Edited by Victor®

Share this post


Link to post
Share on other sites

Большое спасибо.

Очень хороший материал. Есть блок диаграмма, расчет, vhdl коды. Буду разбираться.

Share this post


Link to post
Share on other sites

Прочитал. Там описывается возможность реализации фильтра через Матлдаб Simulink.

Но для этого требуется пакет с библиотекой Xilinx blockset

 

Не подскажете где ее можно взять. Нужна ли лицензия?

У меня Матлаб 7.01

Share this post


Link to post
Share on other sites
Прочитал. Там описывается возможность реализации фильтра через Матлдаб Simulink.

Но для этого требуется пакет с библиотекой Xilinx blockset

 

Не подскажете где ее можно взять. Нужна ли лицензия?

У меня Матлаб 7.01

 

Хм... вот думаю или не подтолкнул Вас насильно к Xilinx :-)

Хотя и сам на нем сижу.

Для этого нужен Xilinx System Generator. Вот в кратце, что это

http://www.plis.ru/page.php?id=112

 

Где взять отдельно не в курсе. Вообще идет идет в составе ISE DSP Edition и ISE System Edition.

Только сравните соответствия версий Mathlab/Simulink и ISE. Версии должны точно соответствовать друг другу.

 

Справедливости ради замечу, что у Altera есть для этого DSP Builder

http://www.altera.com/support/ip/dsp/ips-d...&WT.oss=DSP

 

Кроме этого - было что-то у Synplicity, сейчас - это Synopsys.

Посмотрите на них. Сможете работать c FPGA разных производителей.

Это наверное, лучший вариант, IMHO.

Может знающие поправят...

 

-- Успехов

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this