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.