Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Industrial programming >> Verilog

Verilog-vertragingsregeling

Er zijn twee soorten timingcontroles in Verilog - vertraging en evenement uitdrukkingen. De vertraging controle is slechts een manier om een ​​vertraging toe te voegen tussen het moment waarop de simulator de instructie tegenkomt en wanneer deze deze daadwerkelijk uitvoert. De gebeurtenisuitdrukking staat toe dat de verklaring wordt uitgesteld tot het optreden van een simulatiegebeurtenis die een waardeverandering op een net of variabele kan zijn (impliciete gebeurtenis ) of een expliciet genoemde gebeurtenis die in een andere procedure wordt geactiveerd.

De simulatietijd kan op een van de volgende manieren worden vervroegd.

Poorten en netten waarvan is gemodelleerd dat ze interne vertragingen hebben, verlengen ook de simulatietijd.

Vertragingsregeling

Als de vertragingsexpressie resulteert in een onbekende of hoge impedantiewaarde, wordt deze geïnterpreteerd als nulvertraging. Als het een negatieve waarde oplevert, wordt het geïnterpreteerd als een geheel getal zonder teken van een 2-complement van dezelfde grootte als een tijdvariabele.

  
  
`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

  

Merk op dat de precisie van de tijdschaal in 1ps is en dus $realtime is vereist om de precisiewaarde voor de instructie weer te geven met een vertragingsexpressie (a+b)*10ps.

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

Gebeurtenisbeheer

Waardeveranderingen op netten en variabelen kunnen worden gebruikt als een synchronisatiegebeurtenis om de uitvoering van andere procedurele instructies te activeren en is een impliciete evenement. De gebeurtenis kan ook gebaseerd zijn op de richting van de verandering, zoals naar 0, waardoor het een negedge . wordt en een verandering naar 1 maakt het een posedge .

  • Een negedge is wanneer er een overgang is van 1 naar X, Z of 0 en van X of Z naar 0
  • Een posedge is wanneer er een overgang is van 0 naar X, Z of 1 en van X of Z naar 1

Een overgang van dezelfde toestand naar dezelfde toestand wordt niet als een rand beschouwd. Een randgebeurtenis zoals posedge of negedge kan alleen worden gedetecteerd op de LSB van een vectorsignaal of variabele. Als een uitdrukking hetzelfde resultaat oplevert, kan deze niet als een gebeurtenis worden beschouwd.

  
  
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

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

Genoemde evenementen

Het trefwoord event kan worden gebruikt om een ​​named . te declareren gebeurtenis die expliciet kan worden geactiveerd. Een event kan geen gegevens bevatten, heeft geen tijdsduur en kan op een bepaald moment plaatsvinden. Een benoemde gebeurtenis wordt geactiveerd door de -> operator door het voor de benoemde gebeurtenishandle te plaatsen. Op een benoemde gebeurtenis kan worden gewacht met behulp van de @ hierboven beschreven 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

  

Benoemde gebeurtenissen kunnen worden gebruikt om twee of meer gelijktijdig lopende processen te synchroniseren. Bijvoorbeeld de always blok en de tweede initial blok worden gesynchroniseerd door a_event. Gebeurtenissen kunnen worden gedeclareerd als arrays, zoals in het geval van b_event, een array van grootte 5 en de index 3 wordt gebruikt voor trigger- en wachtdoeleinden.

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

Evenement of operator

De or operator kan worden gebruikt om te wachten totdat een van de vermelde gebeurtenissen in een expressie wordt geactiveerd. De komma , kan ook worden gebruikt in plaats van de or telefoniste.

  
  
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

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

Lijst met impliciete gebeurtenisuitdrukkingen

De gevoeligheidslijst of de gebeurtenisexpressielijst is vaak een veelvoorkomende oorzaak van veel functionele fouten in de RTL. Dit komt omdat de gebruiker kan vergeten de gevoeligheidslijst bij te werken nadat hij een nieuw signaal in het procedureblok heeft ingevoerd.

  
  
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

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

Als de gebruiker besluit een nieuw signaal e toe te voegen en de inverse in z vast te leggen, moet er extra op worden gelet dat e ook aan de gevoeligheidslijst wordt toegevoegd.

  
  
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

  
Simulatielogboek
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 staat nu toe dat de gevoeligheidslijst wordt vervangen door * wat een handige afkorting is die deze problemen elimineert door alle netten en variabelen toe te voegen die worden gelezen door de verklaring zoals hieronder weergegeven.

  
  
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

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

Niveaugevoelige gebeurteniscontrole

De uitvoering van een procedurele verklaring kan ook worden uitgesteld totdat een voorwaarde waar wordt en kan worden bereikt met de wait zoekwoord en is een niveaugevoelig besturingselement.

De wait-instructie evalueert een voorwaarde en als deze onwaar is, blijven de procedurele instructies die erop volgen geblokkeerd totdat de voorwaarde waar wordt.

  
  
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

  
Simulatielogboek
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-zelfstudie
  2. Verilog-aaneenschakeling
  3. Verilog-opdrachten
  4. Verilog blokkeren en niet-blokkeren
  5. Verilog-besturingsblokken
  6. Verilog-functies
  7. Verilog-taak
  8. Verilog Inter- en intratoewijzingsvertraging
  9. Verilog Gate-vertraging
  10. Verilog-klokgenerator
  11. Verilog wiskundige functies