Временная задержка (delay)
Временная задержка представляет собой способ задания симулятору задержки между моментом, когда он встречается с инструкцией, и моментом, когда он фактически её выполняет.
Если выражение задержки вычисляется как неизвестное или высокоимпедансное значение, оно будет интерпретироваться как нулевая задержка. Если оно принимает отрицательное значение, то оно будет интерпретировано как беззнаковое целочисленное значение, соответствующее значению в формате дополнения до 2, того же размера, что и временная переменная.
Синтаксис
#<number>
#<identifier>
#(<min_exp>: <typical_exp>, <max_exp>)
<> = #<number> <>
<> = #<identifier> <>
<> = #(<min_exp>: <typical_exp>, <max_exp>) <>
Пример
`timescale 1ns/1ps
module timescale_tb;
reg [3:0] a, b;
initial begin
{a, b} <= 0; $display("Time [%5t]: a=%0d b=%0d", $realtime, a, b);
#10; a <= $random; $display("Time [%5t]: a=%0d b=%0d", $realtime, a, b);
#10 b <= $random; $display("Time [%5t]: a=%0d b=%0d", $realtime, a, b);
#(a) $display("Time [%5t]: After delay of a=%0d units", $realtime, a);
#(a+b) $display("Time [%5t]: After delay of (a=%0d + b=%0d =) %0d units", $realtime, a, b, a+b);
#((a+b)*10ps) $display("Time [%5t]: After delay of %0d * 10ps", $realtime, a+b);
#(b-a) $display("Time [%5t]: Expr evaluates to a negative delay", $realtime);
#('h10) $display("Time [%5t]: Delay in hex", $realtime);
a = 'hX;
#(a) $display("Time [%5t]: Delay is 'hX, taken as zero a=%h", $realtime, a);
a = 'hZ;
#(a) $display("Time [%5t]: Delay is in high impedance, taken as zero a=%h", $realtime, a);
#1ps $display("Time [%5t]: Delay of 10ps", $realtime);
end
endmodule
Результат исполнения
Time [ 0]: a=x b=x
Time [10000]: a=0 b=0
Time [20000]: a=4 b=0
Time [24000]: After delay of a=4 units
Time [29000]: After delay of (a=4 + b=1 =) 5 units
Time [29050]: After delay of 5 * 10ps
Time [42050]: Expr evaluates to a negative delay
Time [58050]: Delay in hex
Time [58050]: Delay is 'hX, taken as zero a=x
Time [58050]: Delay is in high impedance, taken as zero a=z
Time [58051]: Delay of 10ps
Задержка также может указываться внутри оператора присваивания. В таком случае сначала будет вычислена правая часть оператора, затем произойдёт задержка на указанное время, после чего произойдёт запись вычисленного значения в переменную слева.
Пример 1
Пример 2
module inter_assignment_delays_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 <= a & b | c;
#20;
end
endmodule
module intra_assignment_delays_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;
q <= #5 a & b | c;
#20;
end
endmodule
Результат исполнения
Результат исполнения
[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
[0] a=0 b=0 c=0 q=0
[5] a=1 b=0 c=1 q=0
Пояснение к примеру
Результат вывода в примере справа изменился, потому что теперь задержка внутри оператора присваивания не позволяет симулятору вычислить значение выражения q = a & b | c
, пока не истечет задержка.
Таким образом, значение a и c вычисляется равным 1, но еще не присваивается, когда выполняется следующий неблокирующий оператор. Таким образом, когда вычисляется правая часть переменной q
, значения a и c по-прежнему равны 0, и, следовательно, $monitor
не обнаруживает изменения для отображения выражения.
Last updated