Comment créer une minuterie en VHDL
Dans les tutoriels précédents, nous avons utilisé le wait for
déclaration pour retarder le temps dans la simulation. Mais qu'en est-il des modules de production ? Le wait for
la déclaration ne peut pas être utilisée pour cela. Cela ne fonctionne qu'en simulation car nous ne pouvons pas simplement dire aux électrons d'un circuit de s'arrêter pendant un temps donné. Alors, comment pouvons-nous garder une trace du temps dans un module de conception ?
La réponse est simplement de compter les cycles d'horloge. Chaque conception numérique a accès à un signal d'horloge qui oscille à une fréquence fixe et connue. Par conséquent, si nous savons que la fréquence d'horloge est de 100 MHz, nous pouvons mesurer une seconde en comptant cent millions de cycles d'horloge.
Cet article de blog fait partie de la série de didacticiels VHDL de base.
Pour compter les secondes en VHDL, on peut implémenter un compteur qui compte le nombre de périodes d'horloge qui passent. Lorsque ce compteur atteint la valeur de la fréquence d'horloge, 100 millions par exemple, on sait qu'une seconde s'est écoulée et qu'il est temps d'incrémenter un autre compteur. Appelons cela le compteur des secondes.
Pour compter les minutes, nous pouvons implémenter un autre compteur de minutes qui s'incrémente lorsque 60 secondes se sont écoulées. De même, nous pouvons créer un compteur d'heures pour compter les heures, en incrémentant lorsque 60 minutes se sont écoulées.
Nous pouvons également continuer cette approche pour compter les jours, les semaines et les mois. Nous sommes limités par les ressources physiques disponibles dans la technologie sous-jacente ainsi que par la longueur du compteur par rapport à la fréquence d'horloge.
À mesure que la longueur des compteurs augmente, cela consomme évidemment plus de ressources. Mais il réagira également plus lentement car la chaîne d'événements s'allongera.
Exercice
Dans ce didacticiel vidéo, nous allons apprendre à créer un module de minuterie en VHDL :
Le code final pour le minuteur testbench :
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity T18_TimerTb is end entity; architecture sim of T18_TimerTb is -- We're slowing down the clock to speed up simulation time constant ClockFrequencyHz : integer := 10; -- 10 Hz constant ClockPeriod : time := 1000 ms / ClockFrequencyHz; signal Clk : std_logic := '1'; signal nRst : std_logic := '0'; signal Seconds : integer; signal Minutes : integer; signal Hours : integer; begin -- The Device Under Test (DUT) i_Timer : entity work.T18_Timer(rtl) generic map(ClockFrequencyHz => ClockFrequencyHz) port map ( Clk => Clk, nRst => nRst, Seconds => Seconds, Minutes => Minutes, Hours => Hours); -- Process for generating the clock Clk <= not Clk after ClockPeriod / 2; -- Testbench sequence process is begin wait until rising_edge(Clk); wait until rising_edge(Clk); -- Take the DUT out of reset nRst <= '1'; wait; end process; end architecture;
Le code final pour le module de la minuterie :
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity T18_Timer is generic(ClockFrequencyHz : integer); port( Clk : in std_logic; nRst : in std_logic; -- Negative reset Seconds : inout integer; Minutes : inout integer; Hours : inout integer); end entity; architecture rtl of T18_Timer is -- Signal for counting clock periods signal Ticks : integer; begin process(Clk) is begin if rising_edge(Clk) then -- If the negative reset signal is active if nRst = '0' then Ticks <= 0; Seconds <= 0; Minutes <= 0; Hours <= 0; else -- True once every second if Ticks = ClockFrequencyHz - 1 then Ticks <= 0; -- True once every minute if Seconds = 59 then Seconds <= 0; -- True once every hour if Minutes = 59 then Minutes <= 0; -- True once a day if Hours = 23 then Hours <= 0; else Hours <= Hours + 1; end if; else Minutes <= Minutes + 1; end if; else Seconds <= Seconds + 1; end if; else Ticks <= Ticks + 1; end if; end if; end if; end process; end architecture;
La forme d'onde zoomée sur le Seconds
signal :
La forme d'onde zoomée sur le Minutes
signal :
La forme d'onde zoomée sur le Hours
signal :
Analyse
Pour exécuter une simulation de 50 heures, nous avons donné la commande run 50 hr
dans la console ModelSim. Cinquante heures, c'est une très longue simulation, et nous avons donc dû baisser la fréquence d'horloge du banc d'essai à 10 Hz. Si nous l'avions laissé à 100 MHz, la simulation aurait pris des jours. De telles adaptations sont parfois nécessaires pour nous permettre de simuler une conception.
Nous avons cliqué avec le bouton droit de la souris sur la chronologie dans la forme d'onde et sélectionné "Grille, chronologie et contrôle du curseur". En changeant l'unité de temps de ns en secondes, minutes et heures, nous avons pu voir que la minuterie fonctionnait en effet en temps réel.
Le temps de temporisation est légèrement décalé par rapport au temps de simulation en raison de la réinitialisation du module au début de la simulation. Il est visible dans la première forme d'onde où la marque des 60 secondes sur la chronologie est légèrement avant lorsque le signal des secondes revient à 0.
A noter qu'en simulation, les valeurs des compteurs sont mises à jour en temps zéro sur le front montant de l'horloge. Dans le monde réel, la valeur du compteur aura besoin d'un certain temps pour se propager du premier bit du compteur au dernier. Au fur et à mesure que nous augmentons la longueur des compteurs, nous consommons du temps disponible d'une période d'horloge.
Si la longueur cumulée de tous les compteurs en cascade devient trop longue, une erreur sera produite dans l'étape de placement et de routage après la compilation. La durée pendant laquelle vous pouvez implémenter un compteur avant de consommer toute la période d'horloge dépend de l'architecture FPGA ou ASIC et de la vitesse d'horloge.
Une vitesse d'horloge accrue signifie que la chaîne de comptage sera plus longue. Cela signifie également que la période d'horloge sera plus courte, ce qui donnera encore moins de temps à la chaîne de compteurs pour se terminer.
À emporter
- La mesure du temps dans les modules VHDL est obtenue en comptant les cycles d'horloge
- Diminuer la fréquence d'horloge dans le banc d'essai accélérera la simulation
Aller au tutoriel suivant »
VHDL
- Comment créer une liste de chaînes en VHDL
- Comment créer un banc d'essai piloté par Tcl pour un module de verrouillage de code VHDL
- Comment arrêter la simulation dans un testbench VHDL
- Comment créer un contrôleur PWM en VHDL
- Comment générer des nombres aléatoires en VHDL
- Comment créer un tampon circulaire FIFO en VHDL
- Comment créer un banc d'essai d'auto-vérification
- Comment créer une liste chaînée en VHDL
- Comment utiliser une procédure dans un processus en VHDL