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

Générateur d'horloge Verilog

Les horloges sont fondamentales pour la construction de circuits numériques car elles permettent à différents blocs d'être synchronisés les uns avec les autres.

Propriétés d'une horloge

Les principales propriétés d'une horloge numérique sont sa fréquence qui détermine la période d'horloge , son cycle de service et la phase d'horloge par rapport aux autres horloges.

Période d'horloge

La fréquence indique combien de cycles peuvent être trouvés dans une certaine période de temps. Et par conséquent, la période d'horloge est le temps nécessaire pour terminer 1 cycle.

Cycle d'utilisation de l'horloge

La durée pendant laquelle l'horloge est élevée par rapport à sa période de temps définit le rapport cyclique.

Phase d'horloge

Si un cycle d'une horloge peut être considéré comme un cercle complet avec 360 degrés, une autre horloge peut être relativement placée à un endroit différent dans le cercle qui occupe une phase différente. Par exemple, une autre horloge de la même période qui est décalée vers la droite d'1/4 de sa période peut être considérée comme ayant une différence de phase de 90 degrés.

Générateur d'horloge Verilog

Les simulations doivent fonctionner sur une échelle de temps donnée qui a une précision limitée comme spécifié par la directive sur les échelles de temps. Il est donc important que la précision de l'échelle de temps soit suffisamment bonne pour représenter une période d'horloge. Par exemple, si la fréquence de l'horloge est fixée à 640000 kHz, alors sa période d'horloge sera de 1,5625 ns pour laquelle une précision d'échelle de temps de 1ps ne suffira pas car il y a un point supplémentaire à représenter. Par conséquent, la simulation arrondira le dernier chiffre pour s'adapter à la précision de l'échelle de temps à 3 points. Cela augmentera la période d'horloge à 1,563, ce qui représente en fait 639795 kHz !

Le module générateur d'horloge Verilog suivant a trois paramètres pour ajuster les trois propriétés différentes comme indiqué ci-dessus. Le module dispose d'une entrée d'activation qui permet de désactiver et d'activer l'horloge selon les besoins. Lorsque plusieurs horloges sont contrôlées par un signal d'activation commun, elles peuvent être mises en phase relativement facilement.

  
  
`timescale 1ns/1ps

module clock_gen (	input      enable,
  					output reg clk);
  
  parameter FREQ = 100000;  // in kHZ
  parameter PHASE = 0; 		// in degrees
  parameter DUTY = 50;  	// in percentage 
  
  real clk_pd  		= 1.0/(FREQ * 1e3) * 1e9; 	// convert to ns
  real clk_on  		= DUTY/100.0 * clk_pd;
  real clk_off 		= (100.0 - DUTY)/100.0 * clk_pd;
  real quarter 		= clk_pd/4;
  real start_dly     = quarter * PHASE/90;
  
  reg start_clk;
  
  initial begin    
    $display("FREQ      = %0d kHz", FREQ);
    $display("PHASE     = %0d deg", PHASE);
    $display("DUTY      = %0d %%",  DUTY);
    
    $display("PERIOD    = %0.3f ns", clk_pd);    
    $display("CLK_ON    = %0.3f ns", clk_on);
    $display("CLK_OFF   = %0.3f ns", clk_off);
    $display("QUARTER   = %0.3f ns", quarter);
    $display("START_DLY = %0.3f ns", start_dly);
  end
  
  // Initialize variables to zero
  initial begin
    clk <= 0;
    start_clk <= 0;
  end
  
  // When clock is enabled, delay driving the clock to one in order
  // to achieve the phase effect. start_dly is configured to the 
  // correct delay for the configured phase. When enable is 0,
  // allow enough time to complete the current clock period
  always @ (posedge enable or negedge enable) begin
    if (enable) begin
      #(start_dly) start_clk = 1;
    end else begin
      #(start_dly) start_clk = 0;
    end      
  end
  
  // Achieve duty cycle by a skewed clock on/off time and let this
  // run as long as the clocks are turned on.
  always @(posedge start_clk) begin
    if (start_clk) begin
      	clk = 1;
      
      	while (start_clk) begin
      		#(clk_on)  clk = 0;
    		#(clk_off) clk = 1;
        end
      
      	clk = 0;
    end
  end 
endmodule

  

Banc de test avec différentes fréquences d'horloge

  
  
module tb;
  wire clk1;
  wire clk2;
  wire clk3;
  wire clk4;
  reg  enable;
  reg [7:0] dly;
  
  clock_gen u0(enable, clk1);
  clock_gen #(.FREQ(200000)) u1(enable, clk2);
  clock_gen #(.FREQ(400000)) u2(enable, clk3);
  clock_gen #(.FREQ(800000)) u3(enable, clk4);
  
  initial begin
    enable <= 0;
    
    for (int i = 0; i < 10; i= i+1) begin
      dly = $random;
      #(dly) enable <= ~enable;      
      $display("i=%0d dly=%0d", i, dly);
      #50;
    end
    
    #50 $finish;
  end
endmodule

  
Journal de simulation
xcelium> run
FREQ      = 100000 kHz
PHASE     = 0 deg
DUTY      = 50 %
PERIOD    = 10.000 ns
CLK_ON    = 5.000 ns
CLK_OFF   = 5.000 ns
QUARTER   = 2.500 ns
START_DLY = 0.000 ns
FREQ      = 200000 kHz
PHASE     = 0 deg
DUTY      = 50 %
PERIOD    = 5.000 ns
CLK_ON    = 2.500 ns
CLK_OFF   = 2.500 ns
QUARTER   = 1.250 ns
START_DLY = 0.000 ns
FREQ      = 400000 kHz
PHASE     = 0 deg
DUTY      = 50 %
PERIOD    = 2.500 ns
CLK_ON    = 1.250 ns
CLK_OFF   = 1.250 ns
QUARTER   = 0.625 ns
START_DLY = 0.000 ns
FREQ      = 800000 kHz
PHASE     = 0 deg
DUTY      = 50 %
PERIOD    = 1.250 ns
CLK_ON    = 0.625 ns
CLK_OFF   = 0.625 ns
QUARTER   = 0.312 ns
START_DLY = 0.000 ns
i=0 dly=36
i=1 dly=129
i=2 dly=9
i=3 dly=99
i=4 dly=13
i=5 dly=141
i=6 dly=101
i=7 dly=18
i=8 dly=1
i=9 dly=13
Simulation complete via $finish(1) at time 1110 NS + 0

Banc de test avec différentes phases d'horloge

  
  
module tb;
  wire clk1;
  wire clk2;
  reg  enable;
  reg [7:0] dly;
  
  clock_gen u0(enable, clk1);
  clock_gen #(.FREQ(50000), .PHASE(90)) u1(enable, clk2);
  
  initial begin
    enable <= 0;
    
    for (int i = 0; i < 10; i=i+1) begin
      dly = $random;
      #(dly) enable <= ~enable;      
      $display("i=%0d dly=%0d", i, dly);
    end
    
    #50 $finish;
  end

endmodule

  
Journal de simulation
xcelium> run
FREQ      = 100000 kHz
PHASE     = 0 deg
DUTY      = 50 %
PERIOD    = 10.000 ns
CLK_ON    = 5.000 ns
CLK_OFF   = 5.000 ns
QUARTER   = 2.500 ns
START_DLY = 0.000 ns
FREQ      = 100000 kHz
PHASE     = 90 deg
DUTY      = 50 %
PERIOD    = 10.000 ns
CLK_ON    = 5.000 ns
CLK_OFF   = 5.000 ns
QUARTER   = 2.500 ns
START_DLY = 2.500 ns
FREQ      = 100000 kHz
PHASE     = 180 deg
DUTY      = 50 %
PERIOD    = 10.000 ns
CLK_ON    = 5.000 ns
CLK_OFF   = 5.000 ns
QUARTER   = 2.500 ns
START_DLY = 5.000 ns
FREQ      = 100000 kHz
PHASE     = 270 deg
DUTY      = 50 %
PERIOD    = 10.000 ns
CLK_ON    = 5.000 ns
CLK_OFF   = 5.000 ns
QUARTER   = 2.500 ns
START_DLY = 7.500 ns
i=0 dly=36
i=1 dly=129
i=2 dly=9
i=3 dly=99
i=4 dly=13
i=5 dly=141
i=6 dly=101
i=7 dly=18
i=8 dly=1
i=9 dly=13
Simulation complete via $finish(1) at time 1110 NS + 0

Banc de test avec différents cycles de service

  
  
module tb;
  wire clk1;
  wire clk2;
  wire clk3;
  wire clk4;
  reg  enable;
  reg [7:0] dly;
  
  clock_gen u0(enable, clk1);
  clock_gen #(.DUTY(25)) u1(enable, clk2);
  clock_gen #(.DUTY(75)) u2(enable, clk3);
  clock_gen #(.DUTY(90)) u3(enable, clk4);
  
  initial begin
    enable <= 0;
    
    for (int i = 0; i < 10; i= i+1) begin
      dly = $random;
      #(dly) enable <= ~enable;      
      $display("i=%0d dly=%0d", i, dly);
      #50;
    end
    
    #50 $finish;
  end
endmodule

  
Journal de simulation
xcelium> run
FREQ      = 100000 kHz
PHASE     = 0 deg
DUTY      = 50 %
PERIOD    = 10.000 ns
CLK_ON    = 5.000 ns
CLK_OFF   = 5.000 ns
QUARTER   = 2.500 ns
START_DLY = 0.000 ns
FREQ      = 100000 kHz
PHASE     = 0 deg
DUTY      = 25 %
PERIOD    = 10.000 ns
CLK_ON    = 2.500 ns
CLK_OFF   = 7.500 ns
QUARTER   = 2.500 ns
START_DLY = 0.000 ns
FREQ      = 100000 kHz
PHASE     = 0 deg
DUTY      = 75 %
PERIOD    = 10.000 ns
CLK_ON    = 7.500 ns
CLK_OFF   = 2.500 ns
QUARTER   = 2.500 ns
START_DLY = 0.000 ns
FREQ      = 100000 kHz
PHASE     = 0 deg
DUTY      = 90 %
PERIOD    = 10.000 ns
CLK_ON    = 9.000 ns
CLK_OFF   = 1.000 ns
QUARTER   = 2.500 ns
START_DLY = 0.000 ns
i=0 dly=36
i=1 dly=129
i=2 dly=9
i=3 dly=99
i=4 dly=13
i=5 dly=141
i=6 dly=101
i=7 dly=18
i=8 dly=1
i=9 dly=13
Simulation complete via $finish(1) at time 1110 NS + 0

Activer/Désactiver pour démarrer/arrêter les horloges

La forme d'onde ci-dessous montre que les horloges sont arrêtées lorsque l'activation est faible et les horloges sont démarrées lorsque l'activation est définie sur haut.


Verilog

  1. Tutoriel Verilog
  2. Concaténation Verilog
  3. Affectations Verilog
  4. Verilog bloquant et non bloquant
  5. Fonctions Verilog
  6. Tâche Verilog
  7. Fonctions mathématiques Verilog
  8. Format d'heure Verilog
  9. Portée de l'échelle de temps Verilog