Menu
Coddy logo textTech

Задержки в присваиваниях

Часть раздела Основы путешествия по Verilog на Coddy — урок 69 из 90.

В предыдущих уроках мы рассмотрели общие задержки (#10 a = b;) и задержки вентилей (and #5 (out, a, b);). Теперь мы рассмотрим задержки присваивания, которые представляют собой задержки, возникающие внутри процедурного блока (такого как initial или always) как часть оператора присваивания.

Задержка присваивания ожидает в течение указанного времени, а затем выполняет присваивание. Задержка помещается после символа # и перед присваиванием.

Синтаксис:

variable = #delay expression;

В отличие от обычной задержки #10 a = b; (задержка, затем присваивание), задержка внутри присваивания a = #10 b; берет значение b в этот момент, ожидает 10 единиц времени, а затем присваивает его a.

Задержка присваивания против общей задержки

 Общая задержкаЗадержка присваивания
Синтаксис#10 a = b;a = #10 b;
Когда считывается значение?В момент присваивания (после задержки)Немедленно (перед задержкой)
Какое значение присваивается?Значение b в этот моментЗначение b в момент времени 0 (или в момент считывания)
Когда присваивается значение?После задержкиПосле задержки

Пример: Разница

initial begin
  b = 1;
  #5 b = 0;
  
  // Общая задержка
  #10 a1 = b;     // Ожидает 10, затем считывает b (b=0) → a1=0
  
  // Задержка присваивания
  a2 = #10 b;     // Считывает b сейчас (b=0), ожидает 10, затем присваивает → a2=0
end

Оба варианта дают здесь одинаковый результат. Разница проявляется, когда b изменяется во время задержки.

Пример ключевого различия

To show b changing during the delay, we need two separate initial blocks that run in parallel:

initial begin
  b = 1;
  a1 = #10 b;     // Считывает b=1 в момент времени 0, присваивает a1=1 в момент времени 10
end

initial begin
  #5 b = 0;       // Изменяет b на 0 в момент времени 5 (во время задержки)
end
  • В момент времени 0: a1 считывает b = 1
  • В момент времени 5: b изменяется на 0 (пока a1 все еще ожидает)
  • В момент времени 10: a1 присваивается 1 (значение, считанное в момент времени 0), а не 0

При обычной задержке #10 a2 = b; в отдельном блоке, b будет считано в момент времени 10 (значение 0).

Важные правила

ПравилоОбъяснение
= ставится перед #a = #10 b;, а не a #10 = b;
Значение считывается немедленноПравая часть вычисляется сразу
Присваивание происходит после задержкиЛевая часть получает значение позже
Только для процедурных блоковИспользуется в initial или always
challenge icon

Задание

Что нужно сделать:

Добавьте недостающую задержку присваивания, чтобы a получила значение b через 15 единиц времени, но считывала b немедленно.

Шпаргалка

Задержка присваивания (Assignment delay) считывает правую часть выражения немедленно, выжидает задержку, а затем выполняет присваивание:

variable = #delay expression;

Ключевое отличие от обычной задержки:

Обычная задержка #10 a = b;Задержка присваивания a = #10 b;
Когда считывается значение bПосле задержкиНемедленно
Когда присваивается значениеПосле задержкиПосле задержки

Когда b изменяется в течение задержки, результаты различаются:

initial begin
  b = 1;
  a1 = #10 b;   // Считывает b=1 сейчас, присваивает a1=1 в момент времени 10
  #5 b = 0;     // b меняется в момент времени 5 — a1 все равно получит 1
  // С #10 a2 = b; → считает b=0 в момент времени 10, поэтому a2=0
end

Допустимо только внутри процедурных блоков (initial или always).

Попробуйте сами

module assignment_challenge;
  reg a, b;
  
  // Отдельный блок для изменения b во время задержки
  initial begin
    b = 1;
    // TODO: Добавить задержку присваивания
    // a должно получить значение b через 15 единиц времени
    // Прочитать b сейчас, присвоить после задержки

  end
  
  initial begin
    #5 b = 0;      // Изменяет b во время задержки
    #20 $display("Time %0t: a = %b", $time, a);
    $finish;
  end
endmodule
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Основы