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 : Guide de Conception et d'Implémentation

Les horloges sont fondamentales pour construire des circuits numériques car elles permettent à différents blocs d'être synchronisés entre eux.

Propriétés d'une horloge

Les propriétés clés d'une horloge numérique sont sa fréquence qui détermine la période d'horloge, son cycle de travail (duty cycle) 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 donc la période d'horloge est le temps pris pour compléter 1 cycle.

Cycle de Travail (Duty Cycle)

La quantité de temps pendant laquelle l'horloge est haute comparée à sa période définit le cycle de travail.

Phase d'Horloge

Si un cycle d'horloge peut être vu 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 décalée vers la droite par 1/4 de sa période peut être dite à 90 degrés de différence de phase.

Générateur d'Horloge Verilog

Les simulations sont requises pour opérer sur un timescale donné qui a une précision limitée comme spécifié par la directive timescale. Il est donc important que la précision du timescale soit assez 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 de timescale de 1ps ne suffira pas car il y a un chiffre supplémentaire à représenter. Donc la simulation arrondira le dernier chiffre pour s'adapter à la précision de timescale à 3 points. Cela fera passer 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 discutées ci-dessus. Le module a une entrée enable qui permet à l'horloge d'être désactivée et activée selon les besoins. Quand plusieurs horloges sont contrôlées par un signal enable commun, elles peuvent être relativement phasées facilement.

`timescale 1ns/1ps
module clock_gen (
  input enable,
  output reg clk
);
  parameter FREQ = 100000; // en kHZ
  parameter PHASE = 0;     // en degrés
  parameter DUTY = 50;     // en pourcentage
  real clk_pd = 1.0/(FREQ * 1e3) * 1e9; // convertir en 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
  // Initialiser les variables à zéro
  initial begin
    clk <= 0;
    start_clk <= 0;
  end
  // Quand l'horloge est activée, retarder le pilotage de l'horloge à 1 afin
  // d'atteindre l'effet de phase. start_dly est configuré au
  // délai correct pour la phase configurée. Quand enable est 0,
  // permettre assez de temps pour compléter la période d'horloge courante
  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
  // Atteindre le cycle de travail par un temps d'allumage/extinction d'horloge décalé et laisser
  // cela tourner aussi longtemps que les horloges sont allumées.
  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, clk2, clk3, 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, 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 travail

module tb;
  wire clk1, clk2, clk3, 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

Basculer enable pour démarrer/arrêter les horloges

La forme d'onde ci-dessous montre que les horloges sont arrêtées quand enable est bas et démarrées quand enable est mis haut.

Verilog

  1. Maîtriser Verilog : Tutoriel complet pour la conception de circuits numériques
  2. Maîtriser la concaténation Verilog : Guide pratique
  3. Comprendre les affectations Verilog : Types, Syntaxe et Bonnes Pratiques
  4. Verilog Blocking vs Non-Blocking : Différences Clés Expliquées
  5. Maîtriser les Fonctions Verilog pour une Conception RTL Efficace
  6. Comprendre les Tasks Verilog : Fonctions vs Tasks, Syntaxe et Utilisation
  7. Maîtriser les Fonctions Mathématiques Verilog pour une Conception Matérielle Efficace
  8. Maîtriser Verilog $timeformat : Contrôle de Précision et d'Affichage
  9. Comprendre et Afficher les Timescales Verilog à Toute Portée