Menu
Coddy logo textTech

Неблокирующее присваивание

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

В предыдущем уроке мы рассмотрели блокирующее присваивание (=), которое выполняется шаг за шагом. Теперь мы рассмотрим неблокирующее присваивание (<=), которое выполняется одновременно — параллельно.

В неблокирующем присваивании используется оператор <=. Оно называется «неблокирующим», потому что оно не блокирует выполнение следующей инструкции. Все неблокирующие присваивания в блоке выполняются одновременно.

Синтаксис:

variable <= expression;

Когда использовать неблокирующее присваивание

Неблокирующее присваивание (<=) используется для последовательной логики — схем, которые используют тактовый сигнал и обладают памятью. Выходы изменяются только по фронту тактового сигнала (обычно по нарастающему фронту).

Примеры последовательностной логики:

  • Триггеры
  • Регистры
  • Счётчики
  • Автоматы состояний
  • Сдвиговые регистры

Пример на Verilog:

initial begin
  a <= 5;      // Запланировано, но ещё не выполнено
  b <= a + 2;  // Запланировано, использует СТАРОЕ значение a
  c <= b * 3;  // Запланировано, использует СТАРОЕ значение b
end

Все три присваивания происходят одновременно, используя старые значения. В конце шага времени все обновления выполняются вместе.

Неблокирующие присваивания в блоках always (последовательностная логика)

Неблокирующие присваивания используются для последовательностной логики — схем, которые используют clock и имеют память (триггеры, регистры, счетчики).

always @(posedge clk) begin
  q <= d;           // q получает d по фронту тактового сигнала
  count <= count + 1; // count увеличивается по фронту тактового сигнала
end

Оба присваивания происходят одновременно, используя значения до фронта тактового сигнала.

Итоги

ПравилоОбъяснение
Используйте <= для последовательной logicalways @(posedge clk)
Используйте = для комбинационной logicalways @(*)
non-blocking выполняется параллельноAll присваивания происходят одновременно
Values обновляются в end шага StepНе сразу
challenge icon

Задание

Завершите неблокирующее присваивание

Добавьте пропущенные неблокирующие присваивания, чтобы этот 2-битный сдвиговый регистр заработал.

Как это работает:

  • На каждом фронте тактового сигнала q1 принимает значение d
  • q2 принимает старое значение q1

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

  1. Присвойте d переменной q1 (неблокирующее присваивание)
  2. Присвойте q1 переменной q2 (неблокирующее присваивание)

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

module shift_register (
  input clk,
  input reset,
  input d,
  output reg q1,
  output reg q2
);
  
  always @(posedge clk or posedge reset) begin
    if (reset) begin
      q1 <= 0;
      q2 <= 0;
    end else begin
      // TODO: Добавить логику сдвига
      // Шаг 1: Присвоить d к q1 (неблокирующее)
      // Шаг 2: Присвоить q1 к q2 (неблокирующее)
    end
  end
endmodule
quiz iconПроверьте себя

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

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