Exercices sur la logique séquentielle synchrone

Bascule D avec enable

module dff_en ( input  logic clk, // l'horloge
                input  logic en,  // l'enable
                input  logic D,   // L'entrée donnée
                output logic Q ); // La sortie

 always@(posedge clk)
    if (en)
      Q <= D;
   // Sinon Q garde sa valeur précédente

endmodule

Compteurs

Compteur modulo 256

module cpt_mod ( input  logic clk,       // l'horloge
                 output logic [7:0] Q ); // La sortie

 always@(posedge clk)
      Q <= Q + 1;

endmodule

Compteur modulo 256 avec remise à zéro

Remise à zéro asynchrone

module cpt_srt ( input  logic clk,       // l'horloge
                 input  logic nrst,      // remise à zéro
                 output logic [7:0] Q ); // La sortie

 always@(posedge clk or negedge nrst)
   if (!nrst)
      Q <= '0;
   else
      Q <= Q + 1;

endmodule

Remise à zéro synchrone

module cpt_srt ( input  logic clk,       // l'horloge
                 input  logic nrst,      // remise à zéro
                 output logic [7:0] Q ); // La sortie

 always@(posedge clk)
   if (!nrst)
      Q <= '0;
   else
      Q <= Q + 1;

endmodule

Compteur/Décompteur avec entrée d'activation et remise à zéro synchrone

module cpt_srt ( input  logic clk,       // l'horloge
                 input  logic nrst,      // remise à zéro
                 input  logic en,        // actif ou stopé
                 input  logic up,
                 output logic [7:0] Q ); // La sortie

 always@(posedge clk)
   if (!nrst)
      Q <= '0;
   else
   if (en)
    begin
      if (up)
        Q <= Q + 1;
      else
        Q <= Q - 1;
    end
    // sinon on ne change pas d'état

endmodule

Compteur jusqu'à 13 avec remise à zéro synchrone

... puis on re-part à zéro

module cpt_13_zero ( input  logic clk,       // l'horloge
                     input  logic nrst,      // remise à zéro
                     output logic [7:0] Q ); // La sortie

 always@(posedge clk)
   if (!nrst)
      Q <= '0;
   else
     if(Q!=13)
      Q <= Q + 1;
     else
      Q <= 0;

endmodule

... et on s'arrête

module cpt_13 (  input  logic clk,       // l'horloge
                 input  logic nrst,      // remise à zéro
                 output logic [7:0] Q ); // La sortie

 always@(posedge clk)
   if (!nrst)
      Q <= '0;
   else
     if(Q!=13)
      Q <= Q + 1;

endmodule

Détecteur de fronts montants

module front( input  logic clk,
              input  logic key,
              output logic top
              );

   // on sauvegarde l'état de key dans un registre
   // à décallage de deux bits car on a besoin de
   // comparer l'état actuel à l'état précédent
   logic [1:0]key_s;

   always @(posedge clk)
   begin
     key_s[0] <= key;
     key_s[1] <= key[0];
   end

   // On a un front montant si l'état actuel (0) est à 1
   // et que l'état précédent (1) est encore à 0
   always@(*)
     top <= key_s[0] & !key_s[1];
endmodule

Parallélisation

module parallel ( input  logic clk,
                  input  logic nrst,
                  input  logic data_in,
                  input  logic en_in,
                  output logic [3:0]data_out,
                  output logic en_out );

  // un registre à décalage
  always@(posedge clk)
   if(en_in)
    data_out <= {data_out[2:0],data_in};

  // On compte les bits reçus
  logic [1:0] cpt;

  always@(posedge clk or negedge nrst)
   if (!nrst)
   begin
    cpt    <= '0;
    en_out <= 0;
   end
   else if (en_in)
   begin
    en_out <= (cpt == 2'b11);
    cpt <= cpt + 1;
   end
endmodule

 

Sérialisation

module serial (input logic clk,
               input logic nrst,
               input logic en_in,
               input logic [3:0] data_in,
               output logic en_out,
               output logic data_out );

     // Ne fonctionne que si la période enter deux  en_in est
     // supérieure à 4

     logic [3:0] data;

     always@(posedge clk)
      if(en_in)
       data <= data_in;
      else
       data <= {data[2:0],1'b0};
     // on commence par le bit de poids fort
     always@(*)
       data_out <= data[3];

     logic [3:0] shift;

     always@( posedge clk or negedge nrst)
     if (!nrst)
      shift <= '0;
     else
      shift <= {shift{2:0],en_in};

     always@(*)
       en_out <= shift[3] | shift[2] | shift[1] | shift[0];
endmodule

PWM: Pulse Width Modulation

module pwm ( input logic clk,
             input logic[7:0] consigne,
             output logic pwm );

    logic [7:0] cpt;

    // Un compteur modulo 256
    always @(posedge clk)
    begin
      cpt <= cpt + 1;
    end

    // la sortie vaut 1 si la valeur du compteur est
    // supérieure à la consigne
    always@(*)
      pwm <= (cpt > consigne);

endmodule