LOGIQUE PROGRAMMABLE EN VERILOG
Chapitre 1. Introduction
Chapitre 2. Traitement combinatoire et syntaxe du langage
Chapitre 3. L'usage de l'outil QUARTUS II
Chapitre 4. Description comportementale
4.1. Le bloc always et le type reg
4.2. Les opérateurs conditionnels
4.3. La mémoire élémentaire
4.4. L'alternative multiple
4.5. Exemple de description par table de vérité
4.6. Traitement séquentiel par l'exemple
4.6.1. Bascule D
4.6.2. Compteur modulo 16
4.6.3. Compteur de 4 à 28
4.6.4. Compteur/décompteur modulo 16
4.6.5. Compteur modulo 16 avec entrée de validation et RAZ synchrone
4.6.6. Compteur modulo 16 à chargement asynchrone
4.6.7. Registre à décalage 6 bits (1 entrée série - 1 sortie parallèle)
4.6.8. Registre à décalage 6 bits (1 entrée série - 1 sortie série)
4.7. Exercices
4.8. Solutions des exercices
Chapitre 5. Projets : énoncés
Chapitre 6. Projets : vers la solution
Page d'accueil Table des matières Niveau supérieur Page précédente Bas de la page Page suivante

4.6.6. Compteur modulo 16 à chargement asynchrone

Ce type de compteur semble facile à réaliser mais c'est plus compliqué en réalité. C'est la conséquence de la simplicité des primitives disponibles pour décrire les comportements.

Remarque : on essaiera dans la mesure du possible de ne travailler qu’avec des éléments synchrones (pas d’états parasites). Par contre lorsque le traitement asynchrone est requis, sa mise en œuvre est plus délicate.

Le comportement du compteur a déjà été décrit. Un des premiers reflexes consiste à faire 2 blocs « always », un pour le compteur et un pour le chargement synchrone. Cette option est une grossière erreur. On a oublié qu'il est interdit d'affecter une même variable dans 2 blocs « always ».

La solution consiste à remarquer que 2 conditions sont nécessaires pour traiter un front sur l'horloge (le niveau 0 qui compte, le niveau 1 qui charge). Ce sera exprimé dans la condition de traitement du bloc « always ».

Le programme est :

module cptdecptmodulo16 (clk, load , A , N) ;

input clk , load ;

input [3 : 0] A ;

output[3 : 0] N ;

reg [3 : 0] N ;

always @ (posedge clk OR posedge load)

begin

if (load)

N = A ;

else

if (clk)

N = N + 1;

end

endmodule

Certains sont surement sceptiques sur la solution proposée. Ils auraient envisagés une solution qui ne donne pas satisfaction au niveau de la compilation, en écrivant :

always @ (posedge clk or load)

Il est obligatoire de ne pas mixter les conditions (fronts montant et descendant ou front et niveau). En fait, seuls 2 évènements doivent permettre d'envisager une modification de la valeur de N (un front montant sur clk et un niveau 1 sur load). Pour le front montant, il n'y a pas de discussion. Le problème c'est qu'un niveau n'est pas un front pour load. Avec notre solution, on entre dans le bloc always quand load passe à 1 (front), la sortie N se positionne et reste mémorisée. Si un clk survient, load étant traité en premier, le signal clk n'est pas pris en compte à condition que load soit resté à 1. Le comportement de la sortie N est identique à celle d'un circuit avec load réagissant sur niveau 1.

Page d'accueil Table des matières Niveau supérieur Page précédente Haut de la page Page suivante