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

Рассмотрим приведенный ниже пример:

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

В приведенном выше примере отображается 0. Моя причина в том, что неблокирующее назначение будет назначено на шаге 3 «Стратифицированной очереди событий», а назначение блокировки и отображение $ выполняются на шаге 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.

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

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

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
1 063
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

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

Ответ принят как подходящий

Моделирование 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 @* $display(a);

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

Другие вопросы по теме