Неблокирующее присваивание
Часть раздела Основы путешествия по 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Оба присваивания происходят одновременно, используя значения до фронта тактового сигнала.
Итоги
| Правило | Объяснение |
|---|---|
Используйте <= для последовательной logic | always @(posedge clk) |
Используйте = для комбинационной logic | always @(*) |
| non-blocking выполняется параллельно | All присваивания происходят одновременно |
| Values обновляются в end шага Step | Не сразу |
Задание
Завершите неблокирующее присваивание
Добавьте пропущенные неблокирующие присваивания, чтобы этот 2-битный сдвиговый регистр заработал.
Как это работает:
- На каждом фронте тактового сигнала
q1принимает значениеd q2принимает старое значениеq1
Что нужно сделать:
- Присвойте
dпеременнойq1(неблокирующее присваивание) - Присвойте
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В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Основы
1Введение
Что такое VerilogHardware против SoftwareУровни абстракции проектированияВаш первый модульКомментарии4Операторы. Часть 1
Арифметические операторыОператор остатка от деленияОператоры сравненияПовторение: простая математикаПобитовые операторы7Оператор Assign и логические вентили
Непрерывное присваиваниеAssign с операторамиВстроенные примитивы вентилейВентили AND, OR, NOTВентили XOR, XNORИтоги: Схемы на логических вентилях10Принятие решений
Оператор ifКонструкция if - elseПовторение: простой компараторОператор caseОператоры casex и casezПовторение: проектирование ALU5Операторы. Часть 2
Логические операторыОператоры редукцииОператоры сдвигаОператор конкатенацииУсловный операторПовторение — Испытание по операторам3Системы счисления
Двоичное представлениеЧисла с заданным размеромЧисла без заданного размераОтрицательные числаСпециальные значения X и ZИтоги — форматы чисел6Модули
Структура модуляВходные и выходные портыПорты InoutИнстанцирование модуляПодключение портов по имениПодключение портов по порядкуИтоги: создание модуля9Процедурные блоки
Блок alwaysБлок initialСписок чувствительностиБлокирующее присваиваниеНеблокирующее присваиваниеИтоги: always против initial