[AUDIO_VIDE] Bonjour. Nous allons continuer le cours sur les enseignes et afficheurs à LED. Aujourd'hui nous allons aborder les circuits logiques séquentiels en VHDL. Dans cette séquence, nous aborderons les Process qui sont des boucles infinies qui recommencent à la fin du code et nécessitent donc des instructions de contrôle. Par la suite, nous allons vous proposer la synthèse des bascules, des compteurs et des registres. Les instructions séquentielles en VHDL permettent de modéliser des comportements procéduraux. À l'image des langages de haut niveau, ils sont constitués d'une suite d'actions à exécuter en séquence. Les instructions séquentielles ne peuvent être utilisées que dans un Process ou dans un sous-programme. Les instructions séquentielles en VHDL sont très évoluées à l'image des langages de haut niveau. Leur déroulement se fait suivant l'ordre d'écriture des instructions. Plusieurs process peuvent s'exécuter en parallèle dans une même architecture. Un processus peut contenir des parties combinatoires et des parties séquentielles. Un Process est activé lors d'un changement d'état d'un de ces signaux dits sensibles, qui sont sur sa liste de sensibilité. Les instructions utilisables dans un Process sont spécifiques, c'est-à-dire les instructions concurrentes sont interdites à l'intérieur d'un Process. Et il faut noter que les signaux sont mis à jour uniquement à la fin du processus. Le fonctionnement d'un processus est régi par les règles suivantes : un Process est une boucle infinie et recommence automatiquement à la fin du code. Un Process est synchronisé par des points d'arrêt qui sont soit une liste de sensibilité, ici nous avons la syntaxe Process avec deux signaux sensibles, ou bien par des instructions Wait. Alors ici lorsqu'il y a un changement au niveau d'un de ces signaux, le Process est relancé automatiquement, ou bien on peut avoir des points d'arrêt ici utilisant l'instruction Wait. L'instruction Wait peut prendre plusieurs formes. Nous avons la forme Wait on, qui permet d'attendre l'activation d'un signal. Nous avons Wait for, qui permet d'attendre un délai. Wait until qui permet d'attendre une condition ou bien la forme la plus générale qui utilise un signal, le changement d'un signal, une condition ou éventuellement un temps. Les syntaxes d'utilisation de ces différentes formes sont présentées ici. Wait on, nous avons S1, S2. Donc là l'attente est liée par rapport à un changement sur ces deux signaux, ou bien par rapport à un délai, ou bien par rapport à une condition, ici ck égale 1, ou bien une forme qui associe les deux ou éventuellement les trois. Nous avons l'instruction IF qui permet de tester une expression, if expression then action, sinon expression 2 then action 2, sinon action 3. Il faut juste noter qu'une instruction IF est toujours fermée par un end if. L'instruction CASE...IS permet de sélectionner une séquence, les séquences d'instructions sont là, en fonction de la valeur de l'expression testée. Ici nous avons un sélecteur au niveau de la syntaxe qui peut prendre plusieurs conditions différentes. Et à chaque condition est associée une série d'instructions. Donc ici si sélecteur vaut condition 1, c'est-à-dire ici si le sélecteur est égal aux conditions 1, eh bien la série d'instructions 1 est exécutée. Si le sélecteur valide la condition 2, la série d'instructions 2 est exécutée, sinon dans tous les autres cas WHEN OTHERS, tous les cas doivent être traités. En ce moment-là, c'est les instructions N qui seront exécutées. Il faut noter que l'instruction se termine par un END CASE. Ces instructions CASE...IS sont utilisées dans la descriptions des machines d'état ou toute forme de table de vérité. Les instructions de boucle en VHDL utilisent le mot clé LOOP. Nous avons trois formes d'utilisations de l'instruction LOOP. Soit elle est utilisée avec FOR, avec WHILE ou bien la forme générale. L'instruction FOR permet d'avoir un nombre d'itérations fini. Ici nous avons 100 itérations, donc le i va de 1 à 100. L'instruction WHILE s'exécute tant que la condition est valable, et l'instruction LOOP s'exécute de manière infinie. Alors les instructions de boucle peuvent utiliser également l'instruction Next ou l'instruction Exit. L'instruction Next permet d'arrêter l'itération courante et de passer à l'itération suivante. L'instruction Exit permet de sortir complètement de la boucle. Au niveau de la sortie de la porte E, nous avons Sr qui est égale à R si Ck vaut 1. Et Ss qui est égal à S si Ck vaut 1, et au niveau de la sortie de la porte, nous avons ici Qa qui sont des signaux internes, qui est égal à Sr ou Qb le tout barre. Et nous avons ici au niveau de Qb S ou Qa le tout barre. Alors à partir de ces équations, nous pouvons synthétiser la bascule RS. Alors donc nous allons synthétiser cette bascule activée sur front montant de l'horloge Ck. Alors au niveau de l'entité de la bascule, donc l'entité ici s'appelle bascule RS, nous avons les trois entrées, les trois ports d'entrée, le clock, l'entrée de mise à 0 et l'entrée de mise à 1 et nous avons la sortie. Au niveau de l'architecture, nous avons déclaré ici les quatre signaux internes : Sr, Ss, Qa et Qb, et au niveau du Process, nous avons les trois signaux sensibles, Ck, R et S qui permettent de réactiver le Process à chaque changement. Ici Ck'event est une fonction de type booléen qui renvoie un trou lorsqu'un événement est détecté sur Ck. Lorsqu'on l'associe avec Ck égal 1, ça veut dire que Ck est passé de 0 à 1, comme c'est une variable logique. Donc cette association permet de détecter des fronts montants. En VHDL, on aurait pu utiliser la fonction rising_edge qui permet de détecter les fronts montants. Si on voulait détecter des fronts descendants, on aurait pu aussi utiliser falling_edge. Donc si je résume, à chaque front montant de l'horloge, nous allons affecter R à Sr, S à Ss, et évaluer Qa et Qb en fonction des équations que nous avons déclinées tout à l'heure, et à la fin du process, les signaux sont mis à jour ici. Le Q ne prend la valeur de Qa qu'à la fin du process. La deuxième bascule que nous vous proposons est la bascule D dont la sortie Q prend la valeur de l'entrée à chaque front montant de l'horloge. Pour l'entité de cette bascule D, nous avons les trois ports, les deux entrées Ck et D et la sortie Q. Au niveau de l'architecture de cette bascule, nous avons déclaré un signal interne Qa, et au niveau du Process, nous avons les deux signaux de la liste de sensibilité, Ck et D. Donc le Process est sensible à ces deux signaux. Et à chaque front montant de l'horloge, la sortie, le signal interne Qa prend la valeur de D sinon la sortie est inchangée. Et la sortie est mise à jour à la fin du Process ici. Donc Q va prendre la valeur de Qa à la fin du Process. Nous allons maintenant introduire une entrée de forçage à 1 et une entrée de forçage à 0. Ces entrées sont représentées ici au niveau de l'architecture de la bascule par l'entrée R de remise à 0 et l'entrée S de mise à 1. Donc nous avons les deux entrées, Ck et D et les deux entrées de forçage à 0 et 1, et nous avons la sortie Q qui est là. Alors l'architecture de cette bascule D. Nous avons déclaré ici un signal interne au début de l'architecture et au niveau du Process nous avons quatre signaux sensibles. Donc ce Process est sensible à l'horloge à l'entrée D et aux deux entrées de forçage. Les deux entrées de forçage R et S sont prioritaires sur le fonctionnement normal de la bascule. Cela veut dire que si l'une des deux entrées est activée, l'horloge n'est pas prise en compte. Si R = 1, c'est-à-dire R activé, la sortie Qa vaut zéro. Si S est activé, la sortie Qa vaut 1, et si les deux entrées ne sont pas activées, à ce moment, la prise en compte de l'horloge peut se faire, et à ce moment-là la sortie Qa prend la valeur de D. Sinon, aucun changement. Et à la fin du processus, on met à jour les signaux, c'est-à-dire que la sortie Q va prendre la valeur de Qa. Nous allons maintenant proposer la synthèse de la bascule JK à partir de sa table de vérité. J = 0 et K = 0, la sortie reste inchangée. Si les deux entrées J et K sont différentes, la sortie suit J. Et si les deux entrées sont égales à 1, la sortie est opposée, c'est-à-dire que la sortie bascule entre 0 et 1, la sortie précédente est opposée. Pour la synthèse de la bascule JK, nous avons ici l'entité de cette bascule avec ses trois entrées et la sortie, et au niveau de l'architecture, nous avons déclaré ici un signal interne, les trois signaux sensibles, à chaque front montant de l'horloge, si J = K = 0, la sortie reste inchangée. Si J et K sont différents, la sortie suit J, et sinon, c'est-à-dire J = 1 et K = 1, la sortie est opposée, c'est-à-dire que la sortie prend l'état de la sortie précédente et inversée. Et à la fin du process, les signaux sont mis à jour, c'est-à-dire que Qa est affectée à Q. Nous allons maintenant synthétiser un compteur modulo 10. Un compteur est un système séquentiel qui permet de dénombrer des impulsions de l'horloge appliquées sur son entrée. Pour la synthèse de ce compteur modulo 10, nous avons l'entité qui est appelée ici compteur, les deux entrées, le Clock dont on va compter le nombre d'impulsions, une entrée de remise à zéro et la sortie qui est ici représentée par un vecteur de bits, 3 downto 0, c'est-à-dire constitué de quatre bits qui permettent de représenter les valeurs de 0 à 9. Au niveau de l'architecture, nous avons ici un signal interne Qa qui est aussi un vecteur de bits 3 downto 0. Et au niveau du process, nous avons les deux signaux sensibles, Ck et R. Si R = 0, l'entrée de remise à zéro est activée ici niveau bas. A ce moment-là, la sortie vaut zéro, sinon à chaque front montant de l'horloge, on va incrémenter Qa. Qa = Qa + 1. Si Qa = 9, on réinitialise le compteur. A la fin du process, les signaux sont mis à jour, c'est-à-dire que Qa est affecté à Q. Les systèmes numériques qui permettent de réaliser ce comptage évoluent souvent à des fréquences très élevées. Si nous voulons apprécier la fréquence de comptage de notre compteur, c'est-à-dire qu'un être humain puisse apprécier la fréquence de comptage, il faudrait envisager une division de la fréquence, c'est-à-dire compter à une fréquence très faible. Si nous supposons ici que nous avons un système qui fonctionne à 50 MHz, et que nous voulons compter à 5 Hz, cela veut dire que nous devons diviser notre fréquence par 10 000 000. Pour représenter 10 000 000, il nous faut 24 bits. Au niveau de l'entité de notre compteur, nous avons les deux signaux ici d'entrée, Ck et R, et nous avons introduit un signal de sortie, Qh qui va nous permettre de décompter le nombre d'impulsions pouvant atteindre 10 000 000 avant de pouvoir compter sur notre compteur Q. Et au niveau de l'architecture, nous avons déclaré deux signaux internes, Qa et Qha. Au niveau du process, nous avons les deux signaux sensibles. Si R = 1, on remet à zéro le compteur. Sinon, à chaque front montant de l'horloge, on va compter le nombre d'impulsions de l'horloge. Qha = Qha + 1. Et si Qha atteint la valeur qui correspond à 10 000 000, si le compteur atteint la valeur maximale, on réinitialise, sinon on compte sur le vrai compteur qui va compter à la fréquence désirée, et à la fin du process, les signaux sont mis à jour. Nous allons maintenant passer en compteur modulo N. Nous vous proposons ici un compteur modulo 1 000, c'est-à-dire que l'objectif est de compter de 0 à 999. Il nous faut donc trois chiffres, trois digits, Q0, Q1 et Q2 qui représentent les trois chiffres qui sont représentés. Chaque chiffre est représenté sur quatre bits ici. Nous avons toujours nos deux entrées au niveau de l'entité. Au niveau de l'architecture, nous avons déclaré les trois signaux. Au niveau du process, nous avons les deux entrées Ck et R, et nous avons déclaré une variable Qh qui varie de 0 à 50 000 000. Si R = 1, on réinitialise les trois digits, sinon à chaque front montant de l'horloge on incrémente Qh et si Qh = 50 000 000, on incrémente Qa0 et si Qa0 = 9, on incrémente Qa1 et on réinitialise Qa0. Si Qa1 = 9, on incrémente Qa2 et on réinitialise Qa1. Question ici, quelle est la fréquence de comptage de ce compteur? A la fin du processus, les signaux sont mis à jour, c'est-à-dire Qa0 est mis dans Q0, Qa1 est mis dans Q1, et Qa2 est mis dans Q2. Réponse à ma question, ici nous avons une fréquence de 1 Hz. Nous allons maintenant aborder le registre à décalage série parallèle. Nous vous proposons cette structure ici faite à partir de bascules D. Nous avons ici un registre de quatre bits, donc quatre bascules D, et l'entrée série. Et nous avons des sorties parallèles, et nous avons ici une sortie SS, sortie série. Les quatre bascules sont synchronisées sur l'horloge Ck. Nous avons déclaré ici quatre signaux internes, Qa, Qb, Qc et Qd, donc des signaux qui ne sortent pas du composant. Comme la structure est faite à partir de bascules D, nous avons repris ici juste la synthèse de la bascule D comme précédemment. Et à partir de la bascule D, nous avons ici notre entité registre série parallèle qui dispose de deux entrées, Ck et ES entrée série et de deux sorties, SS sortie série et SP sortie parallèle qui est représenté ici sur quatre bits, donc 0 TO 3. Les bits sont disposés du LSB au MSB. Nous avons déclaré ici au niveau de l'architecture un composant BasculeD et à partir de l'architecture ici, nous avons quatre signaux internes, les quatre signaux Qa, Qb, Qc et Qd. Et pour la première unité, nous avons ici instancié le composant BasculeD avec PORT MAP, et nous lui donnons ici des signaux, Ck pour l'horloge, l'entrée série qu'on donne pour la première unité et la sortie est mise ici au niveau de Qa. Et pour la deuxième unité, l'entrée c'est la sortie de la première unité, c'est-à-dire Qa et la sortie est mise ici dans Qb. La sortie Qb de l'unité 2 est mise dans l'entrée de l'unité 3 et la sortie de l'unité 3 est Qc, qui est remise dans l'entrée de l'unité 4, et la sortie est mise ici dans Qd. Et ici, nous allons mettre sur la sortie parallèle les signaux Qa sur SP(0) Qb sur SP(1), Qc sur SP(2) et Qd sur SP(3). Nous venons d'aborder le circuit logique séquentielle en VHDL, nous avons vu ensemble les process et les instructions de contrôles associées, nous avons pu synthétiser à partir des process les bascules, les compteurs et les registres. Ces éléments seront utilisés dans la commande de matrices à LED.