/*
   _===_ _           _                  ______ _     _             _ _ _
  |  ___| |         | |                 | ___ (_)   | |           (_) | |
  | |__ | | ___  ___| |_ _ __ ___ ______| |_/ /_  __| | ___  _   _ _| | | ___ _   _ _ __
  |  __|| |/ _ \/ __| __| '__/ _ \______| ___ \ |/ _` |/ _ \| | | | | | |/ _ \ | | | '__|
  | |___| |  __/ (__| |_| | | (_) |     | |_/ / | (_| | (_) | |_| | | | |  __/ |_| | |
  \____/|_|\___|\___|\__|_|  \___/      \____/|_|\__,_|\___/ \__,_|_|_|_|\___|\__,_|_|

 *  
 * Compteur 00-99 incrémentant à une vitesse de 5 Hz.
 * File:    Test_Affichage_FPGA_Verilog.v
 * Author:  Bertrand, Électro-Bidouilleur, electro@bidouilleur.ca
 * Created: 5 Février 2019
 * Target:  FPGA Intel Cyclone IV - EP4CE6E22C8
 * Environment: Quartus Prime Lite
*/

module Test_Affichage_FPGA_Verilog  (clk_50M,digit0_sel,digit1_sel,dataout);

// Les broches d'entrées et soties
input clk_50M;     			// L'oscillateur 50 MHZ
output[6:0] dataout;   		// Les segments "a" à "g" des affichages à LED
output digit0_sel;			// Signal qui allume le chiffre des unités    
output digit1_sel;			// Signal qui allume le chiffre des  dizaines  


// Les registres
reg[23:0] counter;      	// Le compteur incrémentant à 50 MHZ - Valeur maximale de 16 millions (2^24)
reg clk_mux = 0;				// L'horloge de multiplexage de l'affichage
reg clk_5hz;					// L'horloge d'incrémentation du compte de l'affichage
reg[6:0] dataout;				// Les segments "a" à "g" des affichages à LED
reg[3:0] BCD;					// La valeur décimale (forme binaire) du chiffre à afficher
reg digit0_sel = 0;
reg digit1_sel = 1;
reg[3:0] digit0 = 0;			// Compteur des unités (affichage)
reg[3:0] digit1 = 0;			// Compteur des dizaines (affichage)

// Les constantes
parameter DIVISOR = 10000000; // Constante pour diviser le compteur par 10 millions

// La logique

// Logique activée sur les fronts montants de l'horloge 50 MHz
always @ ( posedge clk_50M )
 begin
  // Gestion du compteur incrémentant à 50 MHz
  counter = counter + 1;
  if(counter > (DIVISOR-1)) counter = 0;		// Maximum 9999999, sinon remise à zéro
  
  // Production de l'horloge 5 Hz pour incrémenter le compte de l'affichage
  if (counter < (DIVISOR/2)) clk_5hz = 0;
  else clk_5hz = 1;

  // Production de l'horloge 381 Hz de multiplexage de l'affichage
  clk_mux = counter[16];  	// Horloge de multiplexage crééeavec le bit 16 du compteur 50 MHz

   // gestion du multiplexage des 2 chiffres de l'affichage
  if (clk_mux) 			// Si niveau haut
  begin 					
   digit1_sel = 0;			// Éteint l'affichage des dizaines
   BCD = digit0;				// Transfert la valeur des unités au décodeur d'affichage
   digit0_sel = 1;			// Allume l'affichage des unités
  end
  else begin					// Niveau bas.
   digit0_sel = 0;			// Éteint l'affichage des unités
   BCD = digit1;				// Transfert la valeur des dizaines au décodeur d'affichage
   digit1_sel = 1;			// Allume l'affichage des dizaines
  end

  // Décodeur de BCD à affichage 7 segments
  case (BCD)
  0: dataout = 7'b1000000;  
  1: dataout = 7'b1111001;
  2: dataout = 7'b0100100;  
  3: dataout = 7'b0110000;
  4: dataout = 7'b0011001;
  5: dataout = 7'b0010010;  
  6: dataout = 7'b0000010; 
  7: dataout = 7'b1111000;
  8: dataout = 7'b0000000;
  9: dataout = 7'b0010000;
  endcase
 end

// Logique activée par un front montant de l'horloge 5 Hz
// pour incrémenter le compte de l'affichage.
 always @ ( posedge clk_5hz )
 begin
  digit0 = digit0 + 1;		// Incrémente les unités
  if (digit0 == 10) 			// Si unités atteignent 10
  begin
   digit0 = 0;					// remettre à zéro
   digit1 = digit1 + 1;		// incrémenter les dizaines
  end
  if (digit1 == 10)			// Si dizaines = 10
  begin
	digit0 = 0;					// remettre unités à zéro
	digit1 = 0;					// remettre dizaines à zéro
  end
 end
 
 endmodule

