Единственное, что гарантирует симуляция, это то, что все операторы в блоках всегда будут выполняться последовательно. Скажем, как в следующем блоке:
always @(b,c,e,f) begin
a = b | c;
d = e & f;
g = a ^ d ^ x;
...
end
Однако симулятор может принять решение выполнить первые 2 оператора подряд, но затем остановить выполнение этого блока перед последним оператором и позволить другим блокам продолжить. Затем он вернется к последнему утверждению. В этом смысле у вас есть неопределенный c порядок выполнения операторов.
Угадайте, что ?! Значение x
может определенно измениться во время ожидания. a
и d
потенциально могут также измениться при выполнении других операторов. Таким образом, результат g
может быть недетерминированным c. Хорошее программирование поможет устранить этот тип недетерминизма: перечислить все события в списке чувствительности, не использовать сигналы с несколькими приводами ... Затем симулятор сделает все возможное, чтобы избежать таких ситуаций.
Необходимость в этом моделировании чередования состоит в том, чтобы позволить имитаторам выполнять лучшую оптимизацию по соображениям производительности и позволить другим блокам развиваться в случае очень длинных и зацикленных операторов.
Ответ на комментарий о контроле времени и событий
В вышеприведенном блоке симулятор может решить, когда прервать выполнение. С точки зрения программиста, это недетерминировано c. Вы не знаете, когда это может произойти. Единственное, что известно, что это произойдет в одном и том же симуляционном (временном) тике. Хороший симулятор постарается изо всех сил, чтобы избежать любого побочного эффекта этого.
Контроль времени и задержки обеспечивает определение c остановок. Например,
always @(b,c,e,f) begin
a = b | c;
d = e & f;
#1 g = a ^ d ^ x;
...
end
В приведенном выше операторе с #1
вы на самом деле говорите симулятору прекратить выполнение операторов и дождаться следующего такта.
always @(b,c,e,f) begin
a = b | c;
d = e & f;
@(posedge clk)
g = a ^ d ^ x;
...
end
Здесь он остановит выполнение и будет ждать события posedge clk
.
Обратите внимание, что приведенные выше примеры не являются синтезируемыми и должны использоваться только в поведенческом коде (тестовом стенде). Для синтеза вы должны придерживаться самого первого примера и убедиться, что ваш код написан в соответствии с хорошими практиками кодирования Verilog.