Перейти к содержанию
    

Есть описание FIR фильтр и тестбенч для него.

Если делать со статическими коеффициентами фильтр работает, но когда добавляю сигналы загрузки коеффициентов фильтра и разрешения работы, квартус компилит без ошибок, а вот моделсим выдает ошибку

 

# ** Fatal: (vsim-3421) Value 33 is out of range 0 to 32.

# Time: 375 ns Iteration: 1 Process: /agg_vhd_tst/i1/mul File: D:/Project_hdl/sss/agg.vhd

# Fatal error in Process mul at D:/Project_hdl/sss/agg.vhd line 107

ошибка ссылается на строку описания, где загружаются коеффициенты:

coeff(conv_integer(addr)) <= input;

 

я понимаю что проблема в индексах, но не пойму как ее решить и сделать чтобы фильтр заработал ...

test_agg.vhd

agg.vhd

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

я понимаю что проблема в индексах, но не пойму как ее решить и сделать чтобы фильтр заработал ...

уменьшение разрядности адресса на 1 бит не помогает ? (он у вас 6 ти битный вообще то, а надо 5бит судя по размеру фильтра)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

уменьшение разрядности адресса на 1 бит не помогает ? (он у вас 6 ти битный вообще то, а надо 5бит судя по размеру фильтра)

моделирование начинается, но появляется неопределеность состояния на выходе фильтра (красная линия в моделсиме)

PS неопределеность понятна - загружаем только 32 из 33 коеффициентов

 

PS PS пробовал как представлено ниже - фильтр не коректно работает (циклограмма во вложении)

 

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.std_logic_unsigned.all;
USE IEEE.numeric_std.ALL;

package FilterPak is 
    constant POW_IN            : natural := 12;--разрядность входных данных
    constant POW_OUT         : natural := 12;--разрядность выходных данных
    constant POW_COEFF        : natural := 12;--разрядность коэффициентов
    constant POW_SUMM        : natural := 28;--разрядность сумматоров
    constant POW_POINT        : natural := 10;--позиция точки
    constant FILTER_ORDER    : natural := 63; --порядок фильтра чётный(общее число коэффициентов = FILTER_ORDER+1)
    constant N_COEFF         : natural := FILTER_ORDER+1;
    --TYPE coeff_type IS ARRAY (NATURAL range <>) OF signed(POW_COEFF-1 DOWNTO 0);
--    constant coeff             : coeff_type(0 TO N_COEFF-1) := (
--        to_signed(6, POW_COEFF),
--        to_signed(7, POW_COEFF),
--        to_signed(2, POW_COEFF),
--        to_signed(-6, POW_COEFF),
--        to_signed(-11, POW_COEFF),
--        to_signed(-7, POW_COEFF),
--        to_signed(4, POW_COEFF),
--        to_signed(15, POW_COEFF),
--        to_signed(16, POW_COEFF),
--        to_signed(4, POW_COEFF),
--        to_signed(-15, POW_COEFF),
--        to_signed(-28, POW_COEFF),
--        to_signed(-23, POW_COEFF),
--        to_signed(2, POW_COEFF),
--        to_signed(32, POW_COEFF),
--        to_signed(46, POW_COEFF),
--        to_signed(29, POW_COEFF),
--        to_signed(-15, POW_COEFF),
--        to_signed(-59, POW_COEFF),
--        to_signed(-71, POW_COEFF),
--        to_signed(-34, POW_COEFF),
--        to_signed(39, POW_COEFF),
--        to_signed(104, POW_COEFF),
--        to_signed(112, POW_COEFF),
--        to_signed(38, POW_COEFF),
--        to_signed(-91, POW_COEFF),
--        to_signed(-201, POW_COEFF),
--        to_signed(-203, POW_COEFF),
--        to_signed(-41, POW_COEFF),
--        to_signed(272, POW_COEFF),
--        to_signed(646, POW_COEFF),
--        to_signed(950, POW_COEFF),
--        to_signed(1066, POW_COEFF));
end package FilterPak; 





LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
USE IEEE.numeric_std.ALL;
use work.FilterPak.all;

ENTITY agg IS

--generic (
--    POW_IN            : integer := 12;--разрядность входных данных
--     POW_OUT         : integer:= 12;--разрядность выходных данных
--     POW_COEFF        : integer := 12;--разрядность коэффициентов
--     POW_SUMM        : integer := 28;--разрядность сумматоров
--     POW_POINT        : integer := 10;--позиция точки
--     FILTER_ORDER    : integer := 64; --порядок фильтра чётный(общее число коэффициентов = FILTER_ORDER+1)
--     N_COEFF         : integer  := 32 --FILTER_ORDER/2+1;
--);

   PORT( clk                :   IN    std_logic; 
         reset                :   IN    std_logic; 
            load                :   IN    std_logic; 
            enable            :   IN    std_logic; 
            addr           :   IN    std_logic_vector(4 DOWNTO 0);
         filter_in            :   IN    std_logic_vector(POW_IN-1 DOWNTO 0);
         filter_out            :   OUT   std_logic_vector(POW_OUT-1 DOWNTO 0)
         );

END;

ARCHITECTURE rtl OF agg IS
    TYPE regmul_pipeline_type IS ARRAY (NATURAL range <>) OF signed(POW_IN+POW_COEFF-1 DOWNTO 0);
    TYPE regsum_pipeline_type IS ARRAY (NATURAL range <>) OF signed(POW_SUMM-1 DOWNTO 0);
    --TYPE coeff_type IS ARRAY (NATURAL range <>) OF signed(POW_COEFF-1 DOWNTO 0);
    signal reg_mul : regmul_pipeline_type((N_COEFF-1) DOWNTO 0);
    signal reg_sum : regsum_pipeline_type((FILTER_ORDER+1) DOWNTO 0);
    signal input : signed(POW_IN-1 DOWNTO 0);
    signal reg_out : signed(POW_OUT-1 DOWNTO 0);
    TYPE coeff_type IS ARRAY (NATURAL range <>) OF signed((POW_COEFF-1) DOWNTO 0);
    signal coeff   : coeff_type(0 TO (N_COEFF-1));

BEGIN
input <= signed(filter_in);

filter_out <= std_logic_vector(resize(reg_sum(0), POW_OUT)); --std_logic_vector(resize(reg_sum(0)(POW_SUMM-1 DOWNTO POW_POINT),POW_OUT)); 

mul: PROCESS (clk, reset)
BEGIN
    IF reset = '1' THEN
        reg_mul <= (OTHERS => (OTHERS => '0'));
        reg_sum <= (OTHERS => (OTHERS => '0'));
    ELSIF rising_edge(clk) THEN
     if load = '1' then 
             coeff(conv_integer(addr)) <= input;
        end if;
     
     if enable = '1' then
        for i in 0 to N_COEFF-2 loop
            reg_mul(i) <= input * coeff(i);
            reg_sum(i) <= resize(reg_sum(i+1),POW_SUMM) + resize(reg_mul(i),POW_SUMM);
            reg_sum(FILTER_ORDER-i) <= resize(reg_sum(FILTER_ORDER+1-i),POW_SUMM) + resize(reg_mul(i),POW_SUMM);
        end loop;

        reg_mul(N_COEFF-1) <= input * coeff(N_COEFF-1);
        reg_sum(N_COEFF-1) <= resize(reg_sum(N_COEFF),POW_SUMM) + resize(reg_mul(N_COEFF-1),POW_SUMM);
   
END IF;  END IF;
    
END PROCESS;
END rtl;

post-24839-1395301472_thumb.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Глупый вариант на внимательность может generic обновляется во внешнем модуле? Или вот в pakage constant N_COEFF : natural := FILTER_ORDER+1; хатя ниже написано что -- N_COEFF : integer := 32 --FILTER_ORDER/2+1; вот и разница в два раза

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Глупый вариант на внимательность может generic обновляется во внешнем модуле? Или вот в pakage constant N_COEFF : natural := FILTER_ORDER+1; хатя ниже написано что -- N_COEFF : integer := 32 --FILTER_ORDER/2+1; вот и разница в два раза

внешний модуль сейчас только тестбенч - его выложил...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

внешний модуль сейчас только тестбенч - его выложил...

может здесь во времянках проблема?

            load <= '0'; wait for 40 ns;
            load <= '1'; wait for 680 ns;
            load <= '0'; wait;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

может здесь во времянках проблема?

            load <= '0'; wait for 40 ns;
            load <= '1'; wait for 680 ns;
            load <= '0'; wait;

коеффициенты ж грузятся и правильно...

 

---

 

Проблема описанная в 1 посту с тестбенчем не связана

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

коеффициенты ж грузятся и правильно...

 

---

 

Проблема описанная в 1 посту с тестбенчем не связана

Ошибка именно в тестбенче, он выставляет недопустимый addr, равный 33. Кстати, не забывайте о конвейеризации умножений, это поднимает fmax в 2-3 раза.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

заменил загрузку коеффициентов - сделал через сдвигающий регистр:

...
if load = '1' then 
             coeff(N_COEFF-1) <= input;
            for i in N_COEFF-2 downto 0 loop
            coeff(i) <= coeff(i+1);
            end loop;
        end if;
if enable = '1' then
...

Вход

addr           :   IN    std_logic_vector(5 DOWNTO 0);

убрал за ненадобностью.

 

Сейчас проверяю работоспособность - на первый взгляд работает.

 

Ошибка именно в тестбенче, он выставляет недопустимый addr, равный 33. Кстати, не забывайте о конвейеризации умножений, это поднимает fmax в 2-3 раза.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

А адрес при этом должен быть 0-32, 33 уже недопустимо, о чём и пишет Моделсим.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А адрес при этом должен быть 0-32, 33 уже недопустимо, о чём и пишет Моделсим.

возможно (скорее Вы правы), но я все равно не знаю как исправить в случае использования входа addr

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

            load <= '1'; wait for 680 ns;

 

А может здесь 320 или 330 нс нужно вместо 680?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

в тестбенче я задал порядка 70 значений коеффициентов, перепишутся ничего страшного... :)

спасибо...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Бррр, давайте еще раз.

 

Вы создаете массив из 33 элементов с диапазоном адресов 0 - 32.

По этим адресам в тестбенче начинаете писать коэффициенты, при записи 34 коэффициента по адресу 33 - моделсим выдает вам ошибку. Вроде, все логично.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Бррр, давайте еще раз.

 

Вы создаете массив из 33 элементов с диапазоном адресов 0 - 32.

По этим адресам в тестбенче начинаете писать коэффициенты, при записи 34 коэффициента по адресу 33 - моделсим выдает вам ошибку. Вроде, все логично.

Логичнее не бывает :)

Я это понимаю и писал об этом

я понимаю что проблема в индексах, но не пойму как ее решить и сделать чтобы фильтр заработал ...

вопрос как это исправить ;)

 

PS Сейчас альтернативный выход найден - использование сдвигового регистра при загрузке коеффициентов (описано выше в моем посте)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...