2015-05-14 5 views
1

У меня есть 25-мегапиксельная синхронизация в моей FPGA, и я хотел бы сделать таймер, который возвращает «1», когда он отсчитывает 60 секунд. Но у меня есть две проблемы:VHDL Мой таймер не работает

  • Я не понимаю, почему мой сигнал outpout «count_sortie» не определен в Vivado, когда я имитирую его.
  • Чтобы определить свой сигнал count_sortie, я добавляю «: = 0» в файл testbench для имитации, но «count_sortie» остается равным «0» после 60 секундной задержки.

Вот мои VHDL файлы:

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


    entity count is 
     Port (clk : in STD_LOGIC; 
       count_entree : in STD_LOGIC; 
       count_sortie : out STD_LOGIC 
      ); 
    end count; 

    architecture Behavioral of count is 

    signal q : integer range 0 to 30000000 :=0; 

    begin 

     process(clk) 
     begin 
     if (clk'event and clk='1') 
     then 

       while ((count_entree = '1') and (q < 25000000)) loop 

       if (q < 25000000) then 

         q := q + 1; 
         count_sortie <= '0'; 
       else 

        count_sortie <= '1'; 

       end if; 
       end loop; 
     end if; 
     end process; 

    end Behavioral; 

и файл испытательного стенда:

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 

ENTITY tbcount IS 
END tbcount; 

ARCHITECTURE behavior OF tbcount IS 

    -- Component Declaration for the Unit Under Test (UUT) 

    COMPONENT count 
    PORT(
      clk : in STD_LOGIC; 
      count_entree : in STD_LOGIC; 
      count_sortie : out STD_LOGIC 
     ); 
    END COMPONENT; 


    --Inputs 

    signal clk : std_logic := '0'; 
    signal count_entree : std_logic; 

    --Outputs 

    signal count_sortie : std_logic; 

    --Clock 

    constant clk_period : time := 40 ns; 

BEGIN 

    -- Instantiate the Unit Under Test (UUT) 
    uut: count PORT MAP (
      clk => clk, 
      count_entree => count_entree, 
      count_sortie => count_sortie 
     ); 

    -- Clock process definitions 
    clk_process :process 
    begin 
     clk <= '0'; 
     wait for clk_period/2; 
     clk <= '1'; 
     wait for clk_period/2; 
    end process; 


     -- Stimulus process 
    stim_proc: process 
    begin   

    count_entree <= '1'; 

     wait; 
    end process; 

END; 

Спасибо за вашу поддержку.

+0

См. Этот очень похожий вопрос и ответ: http://stackoverflow.com/questions/29948476/creating-a-real-time-delay-in-vhdl/29948930#29948930 – Josh

+0

В поведенческой архитектуре подсчета строка ' q: = q + 1' является синтаксически неправильным. Если 'q' действительно является сигналом, ему требуется назначение сигнала (' <= '). Это переменная, она не определена должным образом в коде, который вы отправили. –

ответ

1

Нет один фактически ответил на ваш вопрос:

  • Я не понимаю, почему мой outpout сигнал «count_sortie» не определено в Vivado, когда я его имитации.
  • Чтобы определить свой сигнал count_sortie, я добавляю «: = 0» в файл testbench для имитации, но «count_sortie» остается равным «0» после 60 секундной задержки.

Как написано с переменным назначением := ваше описание конструкции не является действительным VHDL.

Возможно, стоит пересмотреть предупреждающие сообщения, что происходит, должно быть очевидно. Мгновенное действие count с пометкой uut несвязано в testbench tbcount, и его выходной сигнал не управляется. Что касается тестового стенда, то не существует экземпляра count.

Что касается невысказанный вопрос «как заставить его работать»

И как Джонатан указал ваш код не может делать то, что вы хотите, чтобы в любом случае. Объяснение Джонатаном о том, что делает цикл while, по сути, является правильным, процесс будет работать не так, как предполагалось, даже если создается uut.

Основная идея состоит в том, чтобы рассчитывать до q до 25 000 000 и установить выход count_sortie. Обратите внимание, что при оценке 25000000 фактическая добавляется дополнительная синхронизация часов до count_sortie.

if clk'event and clk = '1' then 
    if q /= 24999999 and count_entree = '1' then 
     q <= q + 1; 
    end if; 
    if q = 24999999 then 
     count_sortie <= '1'; 
    else 
     count_sortie <= '0'; 
    end if; 
end if; 

Это будет считать 24999999 и прекрасным считать. Через один такт будет установлен count_sortie (1).

Это свойство, что если вы должны были очистить или загрузить q обратно в 0, чтобы перезапустить таймер, была бы одна тактовая задержка до того, как count_sortie переместился в '0'.

Если это может нанести ущерб можно восстановить сравнение с 25000000 и двигаться, если заявление с заданием на count_sortie за пределы, если заявление оценивающего нарастающий фронт clk, или даже сделать это одновременно оператор присваивания условного сигнала ,

Сохранение присвоения в процессе может быть более экономным, оно имеет одинаковое сравнение для count в синтезе, гарантировано.

Этот код в этом ответе выше будет выглядеть примерно так:

if clk'event and clk = '1' then 
    if q /= 25000000 and count_entree = '1' then 
     q <= q + 1; 
    end if; 
end if; 
if q = 25000000 then 
    count_sortie <= '1'; 
else 
    count_sortie <= '0'; 
end if; 

И q должен быть в списке чувствительности. Обратите также внимание, что диапазон целочисленного значения q должен только простираться от его лефстома до его самого правого назначенного значения.

Чтобы продемонстрировать это, я делит все значения подсчета на 100000 (для демонстрационных целей, числовой литерал 250 может быть установлен в 25000000 во всех трех местах):

architecture behavioral of count is 

    signal q: integer range 0 to 250 ; 

begin 

timer: 
    process (clk,q) 
    begin 
     if clk'event and clk = '1' then 
      if q /= 250 and count_entree = '1' then 
       q <= q + 1; 
      end if; 
     end if; 
     if q = 250 then 
      count_sortie <= '1'; 
     else 
      count_sortie <= '0'; 
     end if; 
    end process; 

end architecture; 

Scaling Добротность об ожидании все эти часы без необходимости просто продемонстрировать count_sortie работал с тестбенча:

tbcount for q in range 0 to 250 (кликабельны)

Итак, теперь мы не только ответили на ваш вопрос напрямую, но и показали, как заставить его работать правильно.

И если вы намеревались использовать count_sortie в качестве часов, вы хотели бы использовать первый метод (используя 24999999).

+0

Ваш ответ очень полезен.Я решаю свои проблемы, но я не знаю, почему мой счетчик не является инстанцированным в моем файле testbench. Я не нашел ошибку :( – cephal

+0

Обычно это либо порядок анализа, либо потому, что что-то не анализируется в той же рабочей библиотеке, а в библиотеке он не доступен. – user1155120

+0

Но мой VHDL-код действителен в соответствии с вами? за вашу помощь :) – cephal

2

В дополнении к моему комментарию на вашем синтаксисе является недействительным, то есть путаница кастрированного барана q сигнала или переменным, следующий код не будет делать то, что вы ожидаете:

while ((count_entree = '1') and (q < 25000000)) loop 
    if (q < 25000000) then 
     q := q + 1; 
     count_sortie <= '0'; 
    else 
     count_sortie <= '1'; 
    end if; 
end loop; 

Этого цикл либо бесконечный цикл, если он введен в то время как count_entree = '1' и q является сигналом или решает один оператор count_sortie <= '0', если q является переменной.

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

Если q является переменной, цикл развернут и действует только последнее назначение. Обратите внимание, что после выхода из цикла, если q < 25000000, операторы else никогда не выполняются.

Наконец, обратите внимание, что такая структура не будет синтезироваться, если это ваша конечная цель.

Смежные вопросы