Verilog всегда блокирует
always
блок является одним из процедурных блоки в Verilog. Операторы внутри блока always выполняются последовательно.
Синтаксис
always @ (event)
[statement]
always @ (event) begin
[multiple statements]
end
always
блок выполняется по какому-то конкретному событию. Событие определяется списком конфиденциальности.
Что такое список конфиденциальности?
Чувствительность list — это выражение, которое определяет, когда должен выполняться блок always, и указывается после @
оператор в скобках ( )
. Этот список может содержать либо один, либо группу сигналов, изменение значения которых приведет к выполнению блока Always.
В приведенном ниже коде все операторы внутри always
блок выполняется всякий раз, когда изменяется значение сигналов a или b.
// Execute always block whenever value of "a" or "b" change
always @ (a or b) begin
[statements]
end
Для чего используется блок always ?
always
блок можно использовать для реализации комбинационных или последовательных элементов. Последовательный элемент, такой как триггер, становится активным, когда он снабжен часами и сбросом. Точно так же комбинационный блок становится активным при изменении одного из его входных значений. Все эти аппаратные блоки работают одновременно независимо друг от друга. Связь между ними определяет поток данных. Чтобы смоделировать такое поведение, always
Блок создается как непрерывный процесс, который запускается и выполняет какое-либо действие, когда сигнал в списке чувствительности становится активным.
В следующем примере все операторы внутри блока always выполняются при каждом положительном фронте сигнала clk.
// Execute always block at positive edge of signal "clk"
always @ (posedge clk) begin
[statements]
end
Что произойдет, если списка деликатности нет?
always
блок повторяется непрерывно на протяжении всей симуляции. Список чувствительности создает определенное ощущение времени, т. е. всякий раз, когда изменяется какой-либо сигнал в списке чувствительности, всегда срабатывает блокировка. Если в блоке always нет операторов управления временем, симуляция зависнет из-за бесконечного цикла с нулевой задержкой!
Пример
Пример, показанный ниже, представляет собой всегда блок, который пытается инвертировать значение сигнала clk. Оператор выполняется через каждые 0 единиц времени. Следовательно, он выполняется навсегда из-за отсутствия задержки в операторе.
// always block is started at time 0 units
// But when is it supposed to be repeated ?
// There is no time control, and hence it will stay and
// be repeated at 0 time units only. This continues
// in a loop and simulation will hang !
always clk = ~clk;
Даже если список чувствительности пуст, должна быть какая-то другая форма временной задержки. Время моделирования увеличивается с помощью оператора задержки в always
построить, как показано ниже. Теперь инверсия часов выполняется через каждые 10 единиц времени.
always #10 clk = ~clk;
Примечание: Явные задержки не синтезируются в логические вентили!
Следовательно, настоящий код разработки Verilog всегда требует списка конфиденциальности.
Пример дизайна последовательного элемента
Код, показанный ниже, определяет модуль с именем tff, который принимает ввод данных, часы и активный низкий уровень сброса. Выход инвертируется всякий раз, когда d оказывается равным 1 на положительном фронте тактового сигнала. Здесь always
блок запускается либо по положительному фронту clk, либо по отрицательному фронту rstn.
Что происходит на положительном фронте часов?
Следующие события происходят на положительном фронте часов и повторяются для всех положительных фронтов часов.
- Первый
if
блок проверяет значение активного-низкого сброса rstn - Если rstn равно нулю, выход q должен быть сброшен до значения по умолчанию, равного 0
- Если rstn равно единице, это означает, что сброс не применяется и должен следовать поведению по умолчанию.
- Если предыдущий шаг неверен:
- Проверить значение d и, если окажется, что оно равно единице, инвертировать значение q
- Если d равно 0, сохранить значение q.
module tff (input d,
clk,
rstn,
output reg q);
always @ (posedge clk or negedge rstn) begin
if (!rstn)
q <= 0;
else
if (d)
q <= ~q;
else
q <= q;
end
endmodule
Что происходит на отрицательном фронте сброса?
Следующие события происходят при отрицательном фронте rstn и происходят во всех подобных случаях.
- Первый
if
блок проверяет значение активного-низкого сброса rstn. На отрицательном фронте сигнала его значение равно 0. - Если значение rstn равно 0, это означает, что применяется сброс, и вывод должен быть сброшен до значения по умолчанию, равного 0.
- Случай, когда значение rstn равно 1, не рассматривается, поскольку текущим событием является отрицательный фронт. рстн
Пример дизайна комбинированного элемента
always
блок также может быть использован при проектировании комбинационных блоков. Например, следующая цифровая схема представляет собой комбинацию трех различных логических вентилей, которые обеспечивают определенный выходной сигнал при сигнале o.
Показанный ниже код представляет собой module
. с четырьмя входными портами и одним выходным портом, называемым o. always
блок срабатывает всякий раз, когда изменяется значение любого из сигналов в списке чувствительности. Выходной сигнал объявлен как тип reg
в списке портов модуля, потому что он используется в процедурном блоке. Все сигналы, используемые в процедурном блоке, должны быть объявлены как тип reg
. .
module combo ( input a,
input b,
input c,
input d,
output reg o);
always @ (a or b or c or d) begin
o <= ~((a & b) | (c^d));
end
endmodule
Обратите внимание, что сигнал o становится равным 1 всякий раз, когда комбинационное выражение в правой части становится истинным. Точно так же o становится 0, когда RHS имеет значение false.
Выходные данные моделированияЩелкните здесь, чтобы просмотреть слайд-шоу с примером моделирования!
Verilog