Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Industrial programming >> Verilog

Contrôle des délais Verilog

Il existe deux types de contrôles de synchronisation dans Verilog - retard et événement expressions. Le retard control est juste un moyen d'ajouter un délai entre le moment où le simulateur rencontre l'instruction et le moment où il l'exécute réellement. L'expression d'événement permet de retarder l'instruction jusqu'à l'occurrence d'un événement de simulation qui peut être un changement de valeur sur un réseau ou une variable (événement implicite ) ou un événement explicitement nommé qui est déclenché dans une autre procédure.

Le temps de simulation peut être avancé par l'une des méthodes suivantes.

Les portes et les réseaux qui ont été modélisés pour avoir des retards internes font également avancer le temps de simulation.

Contrôle du délai

Si l'expression de retard est évaluée à une valeur inconnue ou à haute impédance, elle sera interprétée comme un retard nul. S'il est évalué à une valeur négative, il sera interprété comme un entier non signé en complément à 2 de la même taille qu'une variable de temps.

  
  
`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

  

Notez que la précision de l'échelle de temps est en 1ps et donc $realtime est nécessaire pour afficher la valeur de précision de l'instruction avec une expression de délai (a+b)*10ps.

Journal de simulation
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.

Contrôle des événements

Les changements de valeur sur les réseaux et les variables peuvent être utilisés comme un événement de synchronisation pour déclencher l'exécution d'autres instructions procédurales et sont implicites un événement. L'événement peut également être basé sur la direction du changement comme vers 0 ce qui en fait un negedge et un changement vers 1 en fait un posedge .

Une transition du même état au même état n'est pas considérée comme un front. Un événement de front comme posedge ou negedge ne peut être détecté que sur le LSB d'un signal vectoriel ou d'une variable. Si une expression donne le même résultat, elle ne peut pas être considérée comme un événement.

  
  
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

  
Journal de simulation
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.

Événements nommés

Le mot-clé event peut être utilisé pour déclarer un named événement qui peut être déclenché explicitement. Un event ne peut contenir aucune donnée, n'a pas de durée et peut se produire à tout moment. Un événement nommé est déclenché par le -> opérateur en le préfixant avant le handle d'événement nommé. Un événement nommé peut être attendu en utilisant le @ opérateur décrit ci-dessus.

  
  
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

  

Les événements nommés peuvent être utilisés pour synchroniser deux ou plusieurs processus exécutés simultanément. Par exemple, le always bloc et le second initial bloc sont synchronisés par a_event. Les événements peuvent être déclarés sous forme de tableaux comme dans le cas de b_event qui est un tableau de taille 5 et l'index 3 est utilisé à des fins de déclenchement et d'attente.

Journal de simulation
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.

Événement ou opérateur

Le or L'opérateur peut être utilisé pour attendre jusqu'à ce que l'un des événements répertoriés soit déclenché dans une expression. La virgule , peut également être utilisé à la place du or opérateur.

  
  
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

  
Journal de simulation
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.

Liste d'expressions d'événements implicites

La liste de sensibilité ou la liste d'expressions d'événements est souvent une cause fréquente d'un grand nombre d'erreurs fonctionnelles dans la RTL. En effet, l'utilisateur peut oublier de mettre à jour la liste de sensibilité après avoir introduit un nouveau signal dans le bloc procédural.

  
  
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

  
Journal de simulation
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.

Si l'utilisateur décide d'ajouter un nouveau signal e et de capturer l'inverse dans z, une attention particulière doit être portée pour ajouter e également dans la liste de sensibilité.

  
  
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

  
Journal de simulation
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 permet désormais de remplacer la liste de sensibilité par * qui est un raccourci pratique qui élimine ces problèmes en ajoutant tous les réseaux et variables qui sont lus par l'instruction comme indiqué ci-dessous.

  
  
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

  
Journal de simulation
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.

Contrôle des événements sensibles au niveau

L'exécution d'une instruction procédurale peut également être retardée jusqu'à ce qu'une condition devienne vraie et peut être accomplie avec le wait mot-clé et est un contrôle sensible au niveau.

L'instruction d'attente évaluera une condition et si elle est fausse, les instructions procédurales qui la suivent resteront bloquées jusqu'à ce que la condition devienne vraie.

  
  
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

  
Journal de simulation
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. Tutoriel Verilog
  2. Concaténation Verilog
  3. Affectations Verilog
  4. Verilog bloquant et non bloquant
  5. Blocs de contrôle Verilog
  6. Fonctions Verilog
  7. Tâche Verilog
  8. Délai Verilog Inter et Intra Affectation
  9. Délai de porte Verilog