Межназначенные и внутриназначенные задержки в Verilog: понимание и применение
Операторы задержки в Verilog могут иметь задержку либо в левой, либо в правой части оператора назначения.
Межназначенные задержки (Inter-assignment Delays)
// Задержка указана слева
#<delay> <LHS> = <RHS>
Межназначенная задержка ставит значение задержки слева от оператора назначения. Это означает, что сам оператор выполняется после истечения задержки — самая распространенная форма управления задержкой.
module tb;
reg a, b, c, q;
initial begin
$monitor("[%0t] a=%0b b=%0b c=%0b q=%0b", $time, a, b, c, q);
// Инициализация в 0 в момент 0
a <= 0; b <= 0; c <= 0; q <= 0;
// Межназначенная задержка: ждем #5, затем назначаем a и c = 1
// a и c обновляются в конце текущего таймстепа
#5 a <= 1; c <= 1;
// Межназначенная задержка: ждем #5, затем назначаем q значением RHS
#5 q <= a & b | c;
#20;
end
endmodule
Обратите внимание: q становится 1 в момент 10 единиц, так как оператор вычисляется в 10 единиц, а RHS (комбинация a, b, c) оценивается в 1.
Simulation Log
xcelium> run [0] a=0 b=0 c=0 q=0 [5] a=1 b=0 c=1 q=0 [10] a=1 b=0 c=1 q=1 xmsim: *W,RNQUIE: Simulation is complete.
Внутриназначенные задержки (Intra-assignment Delays)
// Задержка указана справа
<LHS> = #<delay> <RHS>
Внутриназначенная задержка ставит задержку справа от оператора назначения. Это означает: оператор сначала вычисляется, значения всех сигналов на RHS захватываются, и только после истечения задержки результат присваивается целевому сигналу.
module tb;
reg a, b, c, q;
initial begin
$monitor("[%0t] a=%0b b=%0b c=%0b q=%0b", $time, a, b, c, q);
a <= 0; b <= 0; c <= 0; q <= 0;
#5 a <= 1; c <= 1;
// Внутриназначенная задержка: сначала вычисляем, ждем 5, потом назначаем q
q <= #5 a & b | c;
#20;
end
endmodule
Обратите внимание: назначение q отсутствует в логе!
Simulation Log
xcelium> run [0] a=0 b=0 c=0 q=0 [5] a=1 b=0 c=1 q=0 xmsim: *W,RNQUIE: Simulation is complete.
Это потому, что в 5 единиц a и c назначаются неблокирующими операторами. Поведение неблокирующих операторов: RHS вычисляется, но присваивается переменной только в конце таймстепа.
Значение a и c вычисляется как 1, но еще не назначено, когда выполняется следующий неблокирующий оператор для q. Поэтому при вычислении RHS для q, a и c еще имеют старое значение 0, и $monitor не фиксирует изменение.
Чтобы наблюдать изменение, изменим назначения a и c с неблокирующих на блокирующие.
...
// Неблокирующие заменены на блокирующие, остальное то же
#5 a = 1; c = 1;
q <= #5 a & b | c;
...
Simulation Log
xcelium> run [0] a=0 b=0 c=0 q=0 [5] a=1 b=0 c=1 q=0 [10] a=1 b=0 c=1 q=1 xmsim: *W,RNQUIE: Simulation is complete.
Verilog
- Основы Verilog: проектирование вашего первого И-шлюза
- Освоение Verilog: полное руководство по проектированию цифровых схем
- Освоение конкатенации в Verilog: практическое руководство
- Понимание назначений в Verilog: типы, синтаксис и лучшие практики
- Блокирующие и неблокирующие назначения в Verilog: ключевые различия
- Мастерство функций в Verilog для эффективного RTL дизайна
- Понимание задач (Tasks) в Verilog: отличия от функций, синтаксис и применение
- Управление задержками в Verilog: техники таймингов и лучшие практики
- Понимание задержек гейтов в Verilog: точное тайминг для надежных цифровых схем
- Генератор тактового сигнала в Verilog: проектирование и реализация