Входные данные не загружаются в регистры - проблемы только при моделировании синхронизации после синтеза [VHDL] [Vivado] (решено)

Что это такое

Я пытаюсь создать простой FIR-фильтр. То, что я собираюсь вам представить, может быть не совсем КИХ-фильтром, поскольку я постепенно увеличиваю сложность своего проекта для образовательных целей, пока он не достигнет желаемой функциональности.

Что он должен делать

В основном, что он должен делать до сих пор:

  • загрузить данные в регистры после приложения load = 1,
  • выгрузить обработанные данные (которые являются произведением умножения выборок с соответствующими коэффициентами) после применения start = 1.

Где это не удается

Однако из того, что я заметил, он не может загружать данные в регистры. Похоже, работает как защелка, поскольку после того, как load упадет до 0, последнее значение вектора на входном порте фиксируется в регистрах. Но я могу ошибаться, это просто похоже на то, как это работает в симуляции. Функциональное моделирование до и после синтеза работает! Только время после синтеза не работает должным образом!

Что я пробовал

  • Добавление параметра DONT_TOUCH к объявлению объекта в его .vhd файле,
  • Добавление типа буфера (беззнаковая переменная) после порта data_in, из которого данные передаются в регистры - но он даже не появился в схеме после синтеза, может быть, DONT_TOUCH не сработал?

Моделирование картинок

Функционал до синтеза - https://imgur.com/0TaNQyn

Время после синтеза - https://imgur.com/mEOv67t

Программа

Я использую веб-пакет Vivado 2020.2

Testbench

Код Testbench здесь: https://pastebin.pl/view/d2f9a4ad

Основной код

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;

entity fir is
 Port ( 
 clk: in std_logic;
 data_in: in unsigned(7 downto 0);
 data_out: out unsigned(7 downto 0);
 en: in std_logic;
 load: in std_logic;
 start: in std_logic;
 reset: in std_logic
 );
end fir;

architecture Behavioral of fir is

-- type coeff_array is array (0 to 7) of integer range 0 to 255;
constant reg_size: integer := 8;
constant filter_order: integer := 7;

type samples_reg is array (0 to reg_size-1) of unsigned(7 downto 0);
type coeffs_reg is array (0 to filter_order) of unsigned(7 downto 0);


begin

process(clk, reset)
     
    -- variable coeffs: coeff_array := (0,0,0,0,0,0,0,0);
    --variable b0: unsigned(7 downto 0) := 8D"0";
    variable b0: unsigned(7 downto 0) := to_unsigned(1,8);
    variable b1: unsigned(7 downto 0) := to_unsigned(2,8);
    variable b2: unsigned(7 downto 0) := to_unsigned(3,8);
    variable b3: unsigned(7 downto 0) := to_unsigned(4,8);
    variable b4: unsigned(7 downto 0) := to_unsigned(5,8);
    variable b5: unsigned(7 downto 0) := to_unsigned(6,8);
    variable b6: unsigned(7 downto 0) := to_unsigned(7,8);
    variable b7: unsigned(7 downto 0) := to_unsigned(8,8);
    
    variable i: integer range 0 to reg_size := 0;
    
    variable samples: samples_reg := (others => (others => '0'));
    variable coeffs: coeffs_reg := (b0,b1,b2,b3,b4,b5,b6,b7);
    
    variable data_processed: unsigned(15 downto 0) := (others => '0');
    
       
    
    
    -- variable reg_element:
    
    -- signal s1 : signed(47 downto 0) := 48D"46137344123";
    
    begin    
    
    if reset = '1' then
        -- data_out <= (others => '0');
        samples := (others => (others => '0'));
        data_processed := (others => '0');
        i := 0;            

    -- synch part
    elsif rising_edge(clk) and en = '1' then
    
    samples := samples;
        
        -- loading data
        if load = '1' then
            samples(i) := data_in;
            
            i := i+1;
        else null;
        end if;                      
        
        -- deloading data
        if start = '1' then
            
        data_processed := samples(i)*coeffs(i);
        i := i+1;
        else null; 
        end if;
            
        -- reset counter after overflow
        if(i = reg_size) then
            i := 0;
        else null;
        end if;
        
        -- reset counter if no data is being transferred
        if load = '0' and start = '0' then
            i := 0;
            data_processed := (others => '0');
        else null;
        end if;    
                    
    end if;
    
    data_out <= data_processed(7 downto 0);
    
 end process;


end Behavioral;

Другая информация

  • Я только что заметил, что я держу load = 1 для одного чрезмерного цикла, поэтому первым появляется наибольшее число.
  • Коэффициенты: 1, 2, 3, 4, 5, 6, 7, 8.
  • В постсинтезирующем моделировании после просмотра проверяемого оборудования я заметил, что регистры образцов не загружают данные (за исключением последнего, как я упоминал ранее), i увеличивается и остальное работает нормально.
  • Я буду рад услышать о некоторых улучшениях в моем коде в дополнение к решению проблемы!

person Bartosz Szkoda    schedule 12.01.2021    source источник
comment
Вместо elsif rising_edge(clk) and en = '1' then напишите `` elsifising_edge (clk) then if en = '1' then .... end if; конец, если; `` ''   -  person Oron Port    schedule 14.01.2021
comment
И вы не можете таким образом перебирать i внутри процесса. Используйте инструкцию for.   -  person Oron Port    schedule 14.01.2021
comment
@OronPort Я не совсем понимаю, как использовать оператор for, когда я хочу добавлять (или выводить) новые данные за каждый такт. Разве цикл for не будет выполняться за один такт? Не могли бы вы представить пример или реализовать это в моем коде?   -  person Bartosz Szkoda    schedule 14.01.2021
comment
Предлагаю начать с рисования схемы. Отсюда вам будет легче понять, чем здесь полезен оператор for. for генерирует провода. Цикл продвигается только в конце процесса.   -  person Oron Port    schedule 14.01.2021


Ответы (1)


Оказалось, что при симуляции времени мне пришлось дать устройству время прогрева не менее 100 нс.

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

Я перефразировал заголовок, чтобы другие могли найти этот пост, выполнив поиск основной проблемы в этом случае.

Удачи :)

person Bartosz Szkoda    schedule 14.01.2021