Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Industrial programming >> Verilog

Verilog-Verzögerungssteuerung

Es gibt zwei Arten von Zeitsteuerungen in Verilog - Verzögerung und Ereignis Ausdrücke. Die Verzögerung control ist nur eine Möglichkeit, eine Verzögerung zwischen dem Zeitpunkt hinzuzufügen, zu dem der Simulator auf die Anweisung trifft, und wenn er sie tatsächlich ausführt. Der Ereignisausdruck ermöglicht es, die Anweisung bis zum Auftreten eines Simulationsereignisses zu verzögern, das eine Wertänderung in einem Netz oder einer Variablen sein kann (implizites Ereignis ) oder ein explizit benanntes Ereignis, das in einer anderen Prozedur ausgelöst wird.

Die Simulationszeit kann durch eine der folgenden Methoden verlängert werden.

Tore und Netze, die so modelliert wurden, dass sie interne Verzögerungen haben, beschleunigen auch die Simulationszeit.

Verzögerungssteuerung

Wenn der Verzögerungsausdruck einen unbekannten oder hochohmigen Wert ergibt, wird er als Nullverzögerung interpretiert. Wenn sie einen negativen Wert ergibt, wird sie als vorzeichenlose Ganzzahl im Zweierkomplement mit der gleichen Größe wie eine Zeitvariable interpretiert.

  
  
`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

  

Beachten Sie, dass die Genauigkeit der Zeitskala in 1 ps liegt und daher $realtime ist erforderlich, um den Genauigkeitswert für die Anweisung mit einem Verzögerungsausdruck (a+b)*10ps anzuzeigen.

Simulationsprotokoll
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.

Ereignissteuerung

Wertänderungen an Netzen und Variablen können als Synchronisationsereignis verwendet werden, um die Ausführung anderer prozeduraler Anweisungen auszulösen, und sind implizit Veranstaltung. Das Ereignis kann auch auf der Änderungsrichtung basieren, z. B. in Richtung 0, was es zu einer negedge macht und eine Änderung in Richtung 1 macht es zu einem posedge .

Ein Übergang vom gleichen Zustand zum gleichen Zustand wird nicht als Kante betrachtet. Ein Flankenereignis wie Posedge oder Negedge kann nur am LSB eines Vektorsignals oder einer Variablen erkannt werden. Wenn ein Ausdruck dasselbe Ergebnis liefert, kann er nicht als Ereignis betrachtet werden.

  
  
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

  
Simulationsprotokoll
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.

Benannte Ereignisse

Das Schlüsselwort event kann verwendet werden, um einen named zu deklarieren Ereignis, das explizit ausgelöst werden kann. Ein event kann keine Daten enthalten, hat keine Zeitdauer und kann zu einem bestimmten Zeitpunkt ausgeführt werden. Ein benanntes Ereignis wird durch -> ausgelöst -Operator, indem Sie ihn vor das benannte Ereignishandle voranstellen. Auf ein benanntes Ereignis kann mit @ gewartet werden oben beschriebenen Operator.

  
  
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

  

Benannte Ereignisse können verwendet werden, um zwei oder mehr gleichzeitig laufende Prozesse zu synchronisieren. Zum Beispiel always Block und der zweite initial Block werden von a_event synchronisiert. Ereignisse können als Arrays deklariert werden, wie im Fall von b_event, das ein Array der Größe 5 ist und der Index 3 für Trigger- und Wartezwecke verwendet wird.

Simulationsprotokoll
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.

Ereignis oder Operator

Die or -Operator kann verwendet werden, um zu warten, bis eines der aufgelisteten Ereignisse in einem Ausdruck ausgelöst wird. Das Komma , kann auch anstelle des or verwendet werden Betreiber.

  
  
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

  
Simulationsprotokoll
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.

Implizite Ereignisausdrucksliste

Die Sensitivitätsliste oder die Ereignisausdrucksliste ist oft eine häufige Ursache für viele Funktionsfehler in der RTL. Dies liegt daran, dass der Benutzer möglicherweise vergisst, die Empfindlichkeitsliste zu aktualisieren, nachdem er ein neues Signal in den Verfahrensblock eingefügt hat.

  
  
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

  
Simulationsprotokoll
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.

Wenn der Benutzer beschließt, ein neues Signal e hinzuzufügen und das Inverse in z zu erfassen, muss besonders darauf geachtet werden, e auch in die Empfindlichkeitsliste aufzunehmen.

  
  
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

  
Simulationsprotokoll
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 erlaubt jetzt, dass die Vertraulichkeitsliste durch * ersetzt wird Dies ist eine bequeme Abkürzung, die diese Probleme beseitigt, indem alle Netze und Variablen hinzugefügt werden, die von der Anweisung gelesen werden, wie unten gezeigt.

  
  
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

  
Simulationsprotokoll
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.

Ebenenabhängige Ereignissteuerung

Die Ausführung einer prozeduralen Anweisung kann auch verzögert werden, bis eine Bedingung wahr wird, und kann mit wait ausgeführt werden Schlüsselwort und ist ein pegelabhängiges Steuerelement.

Die Wait-Anweisung wertet eine Bedingung aus, und wenn sie falsch ist, bleiben die ihr folgenden Prozeduranweisungen blockiert, bis die Bedingung wahr wird.

  
  
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

  
Simulationsprotokoll
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-Tutorial
  2. Verilog-Verkettung
  3. Verilog-Aufgaben
  4. Verilog-Blockierung und Nicht-Blockierung
  5. Verilog-Kontrollblöcke
  6. Verilog-Funktionen
  7. Verilog-Aufgabe
  8. Verilog Inter- und Intra-Auftragsverzögerung
  9. Verilog-Gate-Verzögerung
  10. Verilog-Taktgenerator