Ваш код хорошо, хотя я согласен с Грегом, что лучше стиль использовать блокирующие назначения в комбинаторной обработать.
На ваших комментариев:
В очень упрощенном виде, планировщик содержит 5 очередей (SV имеет 17), но вы заинтересованы только в 2 из них: active event queue
, и nonblocking assignment update queue
. В данном цикле моделирования симулятор обрабатывает очередь активных событий, а затем неблокирующее обновление . В общем случае это создаст больше событий, а симулятор будет цитировать вокруг очередей в заранее определенном порядке, пока не будет больше событий на времени моделирования. Затем симулятор переходит в следующий раз, когда запланировано событие (например, на следующем фронте такта).
Предположим, что 4 вещи случаются «сразу»: есть изменения в fsm_state
, есть изменение в f(x)
, и оба ваши задания NBA выполняются. Что касается симулятора, эти 4 оператора выполняются в одном и том же циклах моделирования, но в неопределенном порядке. Определение «сразу» довольно сложно, но предположим, что все они происходят из-за края тактового сигнала без каких-либо зависимостей порядка между операторами. Тренажер обычно однопоточный, так что это будет на самом деле выполнить 4 заявления на различных реальных раз, но он знает, что все 4, как ожидается, произойдет в то же время моделирование.
Изменения на fsm_state
и f(dff1)
являются update events
, и добавляются в планировщика active event queue
.
RHS двух НБА немедленно оцениваются, а обновления LHS - , добавленные к nonblocking assignment update queue
.
Симулятор теперь видит очередь с 4 событиями на нем. Он выполняет два активных события сначала в неопределенном порядке, поэтому fsm_in
и fsm_out
получают свои новые значения . Если активных событий нет, тогда выполняется два неблокирующих обновления в неопределенном порядке, поэтому dff1
и fsm_state
теперь получают свои новые значения.
В вашем случае, цикл моделирования не закончен, так как изменение на fsm_in
также событие обновления, и это вызывает оценочное/выполнение из всегда блока, который чувствителен к fsm_in
. Это evaluation event
. Sim выполняет всегда блок, сразу же считывает новое значение fsm_in
и добавляет обновление fsm_state
к обновлению назначения NBA очереди. Если активных событий нет, тогда выполняется назначение, и fsm_state
получает новое значение.
Это продолжается до тех пор, пока в этом цикле моделирования не будет больше событий, а симулятор затем продвинет время, если что-то запланировано в будущем.
Вы можете получить все это из раздела 5 Verilog LRM, но это не делает смысл . Весь язык был привит в конце стандартизации процесс и использует (VHDL) терминологию, которая не используется в других местах LRM. Он также был добавлен таким образом, чтобы соответствовать поведению Verilog-XL и специально для документирования недетерминизма, характерного для XL, поэтому не ожидайте от него слишком большого . НБА даже не добавляли к языку до 1992 года, я думаю, . Не беспокойтесь о SV LRM; есть еще много очередей, и общий текст изменился, просто добавив еще один уровень замешательства.
У Cliff Cummings есть упрощенное описание в одной из его работ (на неблокирующих назначениях), но внимательно прочитайте его. Я уверен, что описание активной очереди событий неверно (для оценки RHS НБА). Если бы он был прав, это вызвало бы всевозможные проблемы; он предположительно получил описание с ранней версии LRM.
Многое самое лучшее, что нужно сделать, это найти любой текст по дельта-циклам VHDL. Эти просты в понимании, и они работают, и всегда делали, и у них есть , которые проползли в Verilog на протяжении многих лет. Детали разные, но вам не нужно знать ничего больше, чем вы найдете в дельта-циклах.
f и g - произвольные выражения, аналогичные математическим моделям i.e f (x) = x2 - x + 1; – chitranna