2016-12-02 2 views
0

Я пытаюсь написать счетчик, имеющий вход (начало) и три выхода (tsy, tsr, tlg), которые утверждаются для 1 clk_period после 4, 6 и 16 clk_period соответственно. Следующий код отлично подходит для одного утверждения запуска.Weird delayed-output поведение при вызове процесса дважды

library ieee ; 
    use ieee.std_logic_1164.all ; 
    use ieee.numeric_std.all ; 

entity proj_test is 
    port (
    clk, start : in bit; 
    tsy, tsr, tlg : out bit 
) ; 
end entity ; -- proj_test 

architecture behav of proj_test is 

constant clk_period : time := 100 ns; 

begin 

process (start) 
begin 
    if (start='1') then 
     tsy <= '1' after 4*clk_period, '0' after 5*clk_period; 
     tsr <= '1' after 6*clk_period, '0' after 7*clk_period; 
     tlg <= '1' after 16*clk_period, '0' after 17*clk_period; 
    end if; 
end process; 

end architecture ; -- behav 

Output for a single start

В start импульсы 400 нс друг от друга, как и приводится ниже код:

library ieee ; 
    use ieee.std_logic_1164.all ; 
    use ieee.numeric_std.all ; 

entity proj_test_test is 
end entity proj_test_test; 

architecture behav of proj_test_test is 
    constant clk_period : time := 100 ns; 
    signal clk, start : bit; 
    signal tsy, tsr, tlg : bit; 
begin 

    P : entity work.proj_test port map (clk, start, tsy, tsr, tlg); 

    start <= '0', 
      '1' after 2*clk_period, 
      '0' after 3*clk_period, 
      '1' after 6*clk_period, 
      '0' after 7*clk_period, 
      '1' after 42*clk_period; 

end architecture behav; 

или следующих команд тренажера:

force -freeze sim:/proj_test/clk 0 0, 1 {50 ns} -r 100 
force -freeze sim:/proj_test/start 1 0, 0 100, 1 400, 0 500 

Однако, когда я утверждаю вход start во второй раз, tsy охватывает несколько периодов времени.

Output for an added start

Я пытаюсь понять, почему. Я предполагаю, что второй вызов процесса «сбрасывает» присвоения первого. Кроме того, есть ли лучший способ написать поведение этого счетчика?

+0

Вы пытаетесь написать код, который может быть синтезирован? –

+0

@scary_jeff Нет, это для тестового стенда. – usfmohy

+0

Отправьте сообщение [MCVE] (http://stackoverflow.com/help/mcve). Странное поведение выглядит вне этого кода. –

ответ

2

VHDL-симулятор поддерживает очередь событий. Это список симуляторов «To Do». Эффект выполнения любой строки VHDL с назначением сигнала заключается в изменении очереди событий. Обычно события добавляются в очередь событий, но часто события также можно удалить. События будут удалены для модели инерционные задержки; в записях VHDL по умолчанию инерциальны.

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

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

Итак, в момент времени 0 нс очередь событий пуста. Эта линия будет выполнена в момент времени 0

start <= '0', 
     '1' after 2*clk_period, 
     '0' after 3*clk_period, 
     '1' after 6*clk_period, 
     '0' after 7*clk_period, 
     '1' after 42*clk_period; 

Чтобы разместить 6 событий в очереди событий. Очередь событий теперь выглядит следующим образом:

TIME  DELTA SIGNAL VALUE 
    0 ns 1  start  '0' 
200 ns 0  start  '1' 
300 ns 0  start  '0' 
600 ns 0  start  '1' 
700 ns 0  start  '0' 
4200 ns 0  start  '1' 

На время 200 нс, start получает доведенный до '1' и поэтому следующие три строки получить казнены:

tsy <= '1' after 4*clk_period, '0' after 5*clk_period; 
tsr <= '1' after 6*clk_period, '0' after 7*clk_period; 
tlg <= '1' after 16*clk_period, '0' after 17*clk_period; 

которые ставят еще 6 события на событие очередь.Очередь событий теперь выглядит следующим образом:

TIME  DELTA SIGNAL VALUE 
300 ns 0  start  '0' 
600 ns 0  start  '1' 
600 ns 0  tsy  '1' 
700 ns 0  start  '0' 
700 ns 0  tsy  '0' 
800 ns 0  tsr  '1' 
900 ns 0  tsr  '0' 
1800 ns 0  tlg  '1' 
1900 ns 0  tlg  '0' 
4200 ns 0  start  '1' 

затем на 300 нс start получает доведенных до '0' и так очередь событий теперь выглядит следующим образом:

TIME  DELTA SIGNAL VALUE 
600 ns 0  start  '1' 
600 ns 0  tsy  '1' 
700 ns 0  start  '0' 
700 ns 0  tsy  '0' 
800 ns 0  tsr  '1' 
900 ns 0  tsr  '0' 
1800 ns 0  tlg  '1' 
1900 ns 0  tlg  '0' 
4200 ns 0  start  '1' 

затем на 600 нс start получает доведенный до '1'tsy Ведомые в '1' тоже), и поэтому очереди событий теперь выглядит следующим образом:

TIME  DELTA SIGNAL VALUE 
700 ns 0  start  '0' 
700 ns 0  tsy  '0' 
800 ns 0  tsr  '1' 
900 ns 0  tsr  '0' 
1800 ns 0  tlg  '1' 
1900 ns 0  tlg  '0' 
4200 ns 0  start  '1' 

и следующие три строки получить выполняется снова:

tsy <= '1' after 4*clk_period, '0' after 5*clk_period; 
tsr <= '1' after 6*clk_period, '0' after 7*clk_period; 
tlg <= '1' after 16*clk_period, '0' after 17*clk_period; 

которые ставят больше 6 событий на очереди событий:

TIME  DELTA SIGNAL VALUE 
1000 ns 0  tsy  '1' 
1100 ns 0  tsy  '0' 
1200 ns 0  tsr  '1' 
1300 ns 0  tsr  '0' 
2200 ns 0  tlg  '1' 
2300 ns 0  tlg  '0' 

Если следовать правилу я дал выше, вы видите внешний вид очереди событий как это:

TIME  DELTA SIGNAL VALUE 
700 ns 0  start  '0' 
1000 ns 0  tsy  '1' 
1100 ns 0  tsy  '0' 
1200 ns 0  tsr  '1' 
1300 ns 0  tsr  '0' 
2200 ns 0  tlg  '1' 
2300 ns 0  tlg  '0' 
4200 ns 0  start  '1' 

, потому что эти пять событий были удалены:

TIME  DELTA SIGNAL VALUE 
700 ns 0  tsy  '0' 
800 ns 0  tsr  '1' 
900 ns 0  tsr  '0' 
1800 ns 0  tlg  '1' 
1900 ns 0  tlg  '0' 

Если вы посмотрите на след, вы видите, что эти события происходят именно:

  • падение край tsy удаляется (отсюда широкий импульс);
  • первые два события на tsr удалены (отсюда только один импульс);
  • первые два события на tlg удалены (отсюда только один импульс).
+0

Спасибо за ваше время, это был очень информативный ответ. – usfmohy

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