Детерминизм в Верилоге;Управление событиями - PullRequest
1 голос
/ 26 октября 2019

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

module test;
  reg a;
  initial begin
    a = 1'b1;
  end
  initial begin
    wait(a) $display("wait(a): %b", a);
    $display("wait(a)");
  end
  initial begin
    @a $display("@a: %b", a);
    $display("@a");
  end
endmodule

Когда я его запускаю, я всегда получаю такой вывод:

wait(a): 1
wait(a)

Что меня смущает. Мое понимание кода выглядит следующим образом:

  1. значение по умолчанию для a равно x.
  2. все начальные блоки начинаются параллельно в момент времени 0.
  3. первый начальный блок выполняет назначение блока, в то время как элементы управления событиями wait и @a читают a.
  4. , поскольку нет последовательности в последовательности между этими тремя, блокировкаприсвоение a=1'b1, может быть выполнено до или после wait(a) или @a.
  5. , если назначение блокировки выполнено до wait(a) и @a, выходные данные не должны отображаться, так как wait(a)и @a не обнаружит никаких изменений в a.
  6. , если, однако, присвоение блокировки a=1'b1 выполняется после чтения a в wait(a) и @a, которые обабудет читаться как x, тогда выход из обоих должен отображаться после завершения назначения блокировки.

Но, как я указал выше, вывод, который я вижу, всегда является выводом из wait(a),Может кто-нибудь, пожалуйста, объясните мне:

  1. Что происходит и дефект в моем понимании?

И в целом, и за пределами приведенного выше примера:

Что именно происходит, когда симулятор обнаруживает wait(a) и @a? wait(a) и @a, обнаруживающие изменения уровня и фронта (в примере изменения уровня и края идентичны). Когда мы говорим «изменить» в этом случае, означает ли это изменение после последнего чтения переменных, участвующих в элементах управления событиями (в этом примере a)?

Спасибо

1 Ответ

4 голосов
/ 26 октября 2019

Вы правы до пункта 5.

Если a=1'b1 выполняется до wait(a), то это не имеет никакого эффекта - оно не приостанавливает процесс. В обратном порядке wait(a) приостанавливает процесс и возобновляет работу после назначения a=1'b1. В вашем примере вы всегда видите выходные данные из второго блока initial независимо от порядка.

Но для третьего блока initial порядок очень важен. @a должен выполняться перед любым изменением на a, в противном случае он приостанавливается, пока не увидит другое изменение. Хотя вы не должны на это полагаться, большинство инструментов выполняли начальные блоки в порядке исходного кода. Но оптимизация и упорядочение между initial блоками в разных модулях никогда не может гарантировать упорядочение.

...