Что такое текущее время моделирования и очередь событий в Verilog?

Рассмотрим пример ниже:

module test;
 reg a;
 initial begin
  a = 1'b0;
  a <= 1'b1;
  $display(a);
 end
endmodule

В приведенном выше примере отображается 0. Моя причина в том, что неблокирующее назначение будет назначено на шаге 3 «Стратифицированной очереди событий», в то время как назначение блокировки и $ display выполняются на шаге 1. Если я изменю пример как:

module test;
 reg a;
 initial begin
  a = 1'b0;
  a <= 1'b1;
  $display(a);
  $monitor(a);
 end
endmodule

Затем печатаются 0 и 1, потому что я предполагаю, что $ monitor выполняется на шаге 4 очереди событий (?). Но если я изменю пример дальше:

module test;
 reg a;
 initial begin
  a = 1'b0;
  a <= 1'b1;
  $monitor(a);
  $display(a);
 end
endmodule

Снова вывод: 0 и 1 - чего я не ожидал. Я ожидал, что будут напечатаны 1 и 1, потому что $ monitor будет оцениваться на шаге 4 очереди событий, когда «a» уже будет 1. После этого у нас есть $ display, который должен напечатать 1.

Ссылки Я мог найти разговоры о «текущем времени моделирования» и «стратифицированной очереди событий», но я не уверен, как это работает.

Я ценю ваше объяснение! Спасибо


person cmutex    schedule 09.06.2019    source источник


Ответы (2)


Моделирование Verilog управляется событиями. Событие - это изменение значения переменной verilog (или именованного события). Моделирование выполняется поэтапно.

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

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

В verilog 2K есть примерно 3 основные зоны:

  1. блокирующая зона назначения. Verilog выполняет все процедурные блоки, запланированные очередью событий, и реагирует на новые события назначения блокировки. Он просто планирует события nbas, которые будут выполняться позже. Когда все блокирующие события выполнены, он переходит в следующую зону.

  2. неблокирующая зона назначения. Здесь он выполняет все блоки, которые реагируют на события расписания nba. Он поместит в очередь как события ba, так и nba. Когда все nba выполнено, он может вернуться в зону «1», если есть событие ba, и сделать все заново.

  3. Зона монитора / строба - это зона, в которой работает $ monitor (и $ strob). Он запускается после того, как будут выполнены зоны ba и nba (больше никаких событий).

В вашем случае a = 1 выполняется в зоне назначения блокировки. это значение сохраняется до конца этой зоны. $display также будет выполняться в этой зоне. Итак, он увидит значение 'a == 0`.

a <= 1 будет расписанием для выполнения в неблокирующей зоне после завершения $ dislpay. $monitor будет отбирать события в зоне мониторинга после того, как будет выполнено неблокирование. Итак, он покажет вам значение 1.

Ваши операторы выполняются в блоке initial. В результате нет распространения события. Только события выбираются операторами always и assign. Если вы поместите свой $display в блокировку Always, вы увидите более интересные результаты. always @* $display(a);

Вы должны прочитать о стандартной семантике моделирования в Verilog, чтобы получить больше информации.

person Serge    schedule 10.06.2019

Цикл моделирования Verilog более сложен, чем описывает ваше текущее объяснение. Краткий ответ на ваш вопрос заключается в том, что $monitor не ожидает окончания текущего цикла, показывает свое сообщение, а затем продолжает выполнение процесса (и, таким образом, впоследствии запускает $display), а вместо этого просто планирует отображение сообщения в конце любого цикл моделирования, в котором изменяется любая из зависимых переменных (в данном случае только a); это очень особенный (и довольно устаревший) способ мониторинга изменений сигналов во время моделирования. $display однако выполняется немедленно, таким образом распечатывая все, что a в данный момент. Таким образом, можно думать об этом по-другому, как о неблокирующем присваивании (<=), $monitor просто настраивает что-то, что должно произойти позже, и выполнение продолжается до следующего оператора, а не внутри его.

Вам следует рассмотреть возможность изучения имитационной модели systemverilogs, принимая во внимание активные, nba и отложенные регионы, как это происходит при выполнении назначений с блокировкой (=), неблокирующих назначений (<=) и $monitor соответственно.

person Unn    schedule 09.06.2019