Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> Verilog

Контроль задержки Verilog

В Verilog есть два типа контроля времени:задержка и событие выражения. задержка управление — это просто способ добавить задержку между моментом, когда симулятор встречает оператор, и моментом его фактического выполнения. Выражение события позволяет отложить оператор до возникновения некоторого события моделирования, которое может быть изменением значения в цепи или переменной (неявное событие ) или событие с явным именем, которое запускается в другой процедуре.

Время моделирования можно увеличить одним из следующих способов.

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

Управление задержкой

Если выражение задержки оценивается как неизвестное или высокоимпедансное значение, оно будет интерпретировано как нулевая задержка. Если оно дает отрицательное значение, оно будет интерпретироваться как целое число без знака в дополнении до 2 того же размера, что и временная переменная.

  
  
`timescale 1ns/1ps

module tb;
  reg [3:0] a, b;
  
  initial begin
    {a, b} <= 0;
    $display ("T=%0t a=%0d b=%0d", $realtime, a, b);
    
    #10;
    a <= $random;
    $display ("T=%0t a=%0d b=%0d", $realtime, a, b);
    
    #10 b <= $random;
    $display ("T=%0t a=%0d b=%0d", $realtime, a, b);
    
    #(a) $display ("T=%0t After a delay of a=%0d units", $realtime, a);
    #(a+b) $display ("T=%0t After a delay of a=%0d + b=%0d = %0d units", $realtime, a, b, a+b);
    #((a+b)*10ps) $display ("T=%0t After a delay of %0d * 10ps", $realtime, a+b);
    
    #(b-a) $display ("T=%0t Expr evaluates to a negative delay", $realtime);
    #('h10) $display ("T=%0t Delay in hex", $realtime);
    
    a = 'hX;
    #(a) $display ("T=%0t Delay is unknown, taken as zero a=%h", $realtime, a);
    
    a = 'hZ;
    #(a) $display ("T=%0t Delay is in high impedance, taken as zero a=%h", $realtime, a);
    
    #1ps $display ("T=%0t Delay of 10ps", $realtime);
  end
  
endmodule

  

Обратите внимание, что точность шкалы времени составляет 1 пс и, следовательно, $realtime требуется для отображения значения точности оператора с выражением задержки (a+b)*10ps.

Журнал моделирования
xcelium> run
T=0 a=x b=x
T=10000 a=0 b=0
T=20000 a=4 b=0
T=24000 After a delay of a=4 units
T=29000 After a delay of a=4 + b=1 = 5 units
T=29050 After a delay of 5 * 10ps
T=42050 Expr evaluates to a negative delay
T=58050 Delay in hex
T=58050 Delay is unknown, taken as zero a=x
T=58050 Delay is in high impedance, taken as zero a=z
T=58051 Delay of 10ps
xmsim: *W,RNQUIE: Simulation is complete.

Контроль событий

Изменения значений в цепях и переменных могут использоваться как событие синхронизации для запуска выполнения других процедурных операторов и являются неявными мероприятие. Событие также может быть основано на направлении изменения, например, к 0, что делает его negedge и изменение в сторону 1 делает его posedge .

Переход из того же состояния в то же состояние не считается ребром. Краевое событие, такое как posedge или negedge, может быть обнаружено только в LSB векторного сигнала или переменной. Если выражение дает один и тот же результат, оно не может рассматриваться как событие.

  
  
module tb;
  reg a, b;

  initial begin
    a <= 0;
    
    #10 a <= 1;
    #10 b <= 1;

    #10 a <= 0;
    #15 a <= 1; 
  end

  // Start another procedural block that waits for an update to
  // signals made in the above procedural block
  
  initial begin 
    @(posedge a); 
    $display ("T=%0t Posedge of a detected for 0->1", $time); 
    @(posedge b); 
    $display ("T=%0t Posedge of b detected for X->1", $time);
  end 
  
  initial begin
    @(posedge (a + b)) $display ("T=%0t Posedge of a+b", $time);

    @(a) $display ("T=%0t Change in a found", $time);
  end
endmodule

  
Журнал моделирования
ncsim> run
T=10 Posedge of a detected for 0->1
T=20 Posedge of b detected for X->1
T=30 Posedge of a+b
T=45 Change in a found
ncsim: *W,RNQUIE: Simulation is complete.

Именованные события

Ключевое слово event может использоваться для объявления named событие, которое может быть вызвано явно. event не может хранить какие-либо данные, не имеет временной длительности и может произойти в любое конкретное время. Именованное событие запускается с помощью -> оператора, поставив перед ним префикс перед именованным дескриптором события. Именованное событие можно ожидать с помощью @ оператор, описанный выше.

  
  
module tb;
  event a_event;
  event b_event[5];
  
  initial begin
    #20 -> a_event;
    
    #30;
    ->a_event;
    
    #50 ->a_event;
    #10 ->b_event[3];
  end
  
  always @ (a_event) $display ("T=%0t [always] a_event is triggered", $time);
  
  initial begin
    #25;
    @(a_event) $display ("T=%0t [initial] a_event is triggered", $time);
    
    #10 @(b_event[3]) $display ("T=%0t [initial] b_event is triggered", $time);
  end
endmodule

  

Именованные события можно использовать для синхронизации двух или более одновременно запущенных процессов. Например, always блок и второй initial блок синхронизируется с помощью a_event. События могут быть объявлены как массивы, как в случае b_event, который представляет собой массив размером 5, а индекс 3 используется для запуска и ожидания.

Журнал моделирования
ncsim> run
T=20 [always] a_event is triggered
T=50 [always] a_event is triggered
T=50 [initial] a_event is triggered
T=100 [always] a_event is triggered
T=110 [initial] b_event is triggered
ncsim: *W,RNQUIE: Simulation is complete.

Событие или оператор

or оператор может использоваться для ожидания, пока любое из перечисленных событий не будет запущено в выражении. Запятая , также можно использовать вместо or оператор.

  
  
module tb;
  reg a, b;
  
  initial begin
    $monitor ("T=%0t a=%0d b=%0d", $time, a, b);
    {a, b} <= 0;
    
    #10 a <= 1;
    #5  b <= 1;
	#5  b <= 0;
  end
  
  // Use "or" between events
  always @ (posedge a or posedge b) 
    $display ("T=%0t posedge of a or b found", $time);
  
  // Use a comma between
  always @ (posedge a, negedge b)
    $display ("T=%0t posedge of a or negedge of b found", $time);
  
  always @ (a, b) 
    $display ("T=%0t Any change on a or b", $time);
endmodule

  
Журнал моделирования
ncsim> run
T=0 posedge of a or negedge of b found
T=0 Any change on a or b
T=0 a=0 b=0
T=10 posedge of a or b found
T=10 posedge of a or negedge of b found
T=10 Any change on a or b
T=10 a=1 b=0
T=15 posedge of a or b found
T=15 Any change on a or b
T=15 a=1 b=1
T=20 posedge of a or negedge of b found
T=20 Any change on a or b
T=20 a=1 b=0
ncsim: *W,RNQUIE: Simulation is complete.

Список неявных выражений событий

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

  
  
module tb;
	reg a, b, c, d;
	reg x, y;
	
	// Event expr/sensitivity list is formed by all the
	// signals inside () after @ operator and in this case
	// it is a, b, c or d
	always @ (a, b, c, d) begin
		x = a | b;
		y = c ^ d;
	end
	
	initial begin
		$monitor ("T=%0t a=%0b b=%0b c=%0b d=%0b x=%0b y=%0b", $time, a, b, c, d, x, y);
		{a, b, c, d} <= 0;
	
		#10 {a, b, c, d} <= $random;
		#10 {a, b, c, d} <= $random;
		#10 {a, b, c, d} <= $random;
	end
endmodule

  
Журнал моделирования
ncsim> run
T=0 a=0 b=0 c=0 d=0 x=0 y=0
T=10 a=0 b=1 c=0 d=0 x=1 y=0
T=20 a=0 b=0 c=0 d=1 x=0 y=1
T=30 a=1 b=0 c=0 d=1 x=1 y=1
ncsim: *W,RNQUIE: Simulation is complete.

Если пользователь решит добавить новый сигнал e и зафиксировать обратный сигнал в z, необходимо проявить особую осторожность, чтобы добавить e также в список чувствительности.

  
  
module tb;
	reg a, b, c, d, e;
	reg x, y, z;
	
  // Add "e" also into sensitivity list
  always @ (a, b, c, d, e) begin
		x = a | b;
		y = c ^ d;
    	z = ~e;
	end
	
	initial begin
      $monitor ("T=%0t a=%0b b=%0b c=%0b d=%0b e=%0b x=%0b y=%0b z=%0b", 
                				$time, a, b, c, d, e, x, y, z);
      {a, b, c, d, e} <= 0;
	
      #10 {a, b, c, d, e} <= $random;
      #10 {a, b, c, d, e} <= $random;
      #10 {a, b, c, d, e} <= $random;
	end
endmodule

  
Журнал моделирования
ncsim> run
T=0 a=0 b=0 c=0 d=0 e=0 x=0 y=0 z=1
T=10 a=0 b=0 c=1 d=0 e=0 x=0 y=1 z=1
T=20 a=0 b=0 c=0 d=0 e=1 x=0 y=0 z=0
T=30 a=0 b=1 c=0 d=0 e=1 x=1 y=0 z=0
ncsim: *W,RNQUIE: Simulation is complete.

Verilog теперь позволяет заменить список конфиденциальности на * что является удобным сокращением, которое устраняет эти проблемы, добавляя все цепи и переменные, которые считываются оператором, как показано ниже.

  
  
module tb;
	reg a, b, c, d, e;
	reg x, y, z;
	
  // Use @* or @(*)
  always @ * begin
		x = a | b;
		y = c ^ d;
    	z = ~e;
	end
	
	initial begin
      $monitor ("T=%0t a=%0b b=%0b c=%0b d=%0b e=%0b x=%0b y=%0b z=%0b", 
                				$time, a, b, c, d, e, x, y, z);
      {a, b, c, d, e} <= 0;
	
      #10 {a, b, c, d, e} <= $random;
      #10 {a, b, c, d, e} <= $random;
      #10 {a, b, c, d, e} <= $random;
	end
endmodule

  
Журнал моделирования
ncsim> run
T=0 a=0 b=0 c=0 d=0 e=0 x=0 y=0 z=1
T=10 a=0 b=0 c=1 d=0 e=0 x=0 y=1 z=1
T=20 a=0 b=0 c=0 d=0 e=1 x=0 y=0 z=0
T=30 a=0 b=1 c=0 d=0 e=1 x=1 y=0 z=0
ncsim: *W,RNQUIE: Simulation is complete.

Управление событиями, зависящими от уровня

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

Оператор ожидания должен оценивать условие, и, если оно ложно, последующие процедурные операторы должны оставаться заблокированными до тех пор, пока условие не станет истинным.

  
  
module tb;
  reg [3:0] ctr;
  reg clk;
  
  initial begin
    {ctr, clk} <= 0;
    
    wait (ctr);
    $display ("T=%0t Counter reached non-zero value 0x%0h", $time, ctr);
    
    wait (ctr == 4) $display ("T=%0t Counter reached 0x%0h", $time, ctr);
    
    $finish;
  end
  
  always #10 clk = ~clk;
  
  always @ (posedge clk) 
    ctr <= ctr + 1;
  
endmodule

  
Журнал моделирования
ncsim> run
T=10 Counter reached non-zero value 0x1
T=70 Counter reached 0x4
T=90 Counter reached 0x5
T=170 Counter reached 0x9
Simulation complete via $finish(1) at time 170 NS + 1


Verilog

  1. Учебник Verilog
  2. Конкатенация Verilog
  3. Верилог Задания
  4. Блокировка и неблокировка Verilog
  5. Блоки управления Verilog
  6. Верилог-функции
  7. Верилог Задача
  8. Verilog Inter и внутренняя задержка назначения
  9. Задержка ворот Verilog
  10. Генератор часов Verilog