Een timer maken in VHDL
In eerdere tutorials hebben we de wait for
. gebruikt verklaring om de tijd in de simulatie te vertragen. Maar hoe zit het met productiemodules? De wait for
verklaring kan daar niet voor worden gebruikt. Dat werkt alleen in simulatie omdat we de elektronen in een circuit niet zomaar kunnen vertellen dat ze een bepaalde tijd moeten pauzeren. Dus hoe kunnen we de tijd bijhouden in een ontwerpmodule?
Het antwoord is simpelweg klokcycli tellen. Elk digitaal ontwerp heeft toegang tot een kloksignaal dat oscilleert op een vaste, bekende frequentie. Als we dus weten dat de klokfrequentie 100 MHz is, kunnen we één seconde meten door honderd miljoen klokcycli te tellen.
Deze blogpost maakt deel uit van de serie Basic VHDL Tutorials.
Om seconden in VHDL te tellen, kunnen we een teller implementeren die het aantal klokperioden telt dat verstrijkt. Wanneer deze teller de waarde van de klokfrequentie bereikt, bijvoorbeeld 100 miljoen, weten we dat er een seconde is verstreken en dat het tijd is om nog een teller te verhogen. Laten we dit de secondenteller noemen.
Om minuten te tellen, kunnen we een andere Minuten-teller implementeren die oploopt wanneer 60 seconden zijn verstreken. Op dezelfde manier kunnen we een urenteller maken voor het tellen van uren, oplopend wanneer 60 minuten zijn verstreken.
We kunnen deze aanpak ook voor het tellen van dagen, weken en maanden voortzetten. We worden beperkt door de beschikbare fysieke middelen in de onderliggende technologie en de lengte van de teller versus de klokfrequentie.
Naarmate de lengte van de tellers toeneemt, verbruikt het uiteraard meer middelen. Maar het zal ook langzamer reageren omdat de keten van gebeurtenissen langer wordt.
Oefening
In deze video-tutorial leren we hoe we een timermodule in VHDL kunnen maken:
De laatste code voor de timer 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;
De laatste code voor de timer module :
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;
De golfvorm zoomde in op de Seconds
signaal:
De golfvorm zoomde in op de Minutes
signaal:
De golfvorm zoomde in op de Hours
signaal:
Analyse
Om een simulatie van 50 uur uit te voeren, gaven we het commando run 50 hr
in de ModelSim-console. Vijftig uur is een hele lange simulatie, en daarom moesten we de klokfrequentie in de testbank verlagen naar 10 Hz. Als we het op 100 MHz hadden gelaten, had de simulatie dagen geduurd. Dergelijke aanpassingen zijn soms nodig om een ontwerp te kunnen simuleren.
We hebben met de rechtermuisknop op de tijdlijn in de golfvorm geklikt en "Raster, tijdlijn en cursorbesturing" geselecteerd. Bij het veranderen van de tijdseenheid van ns naar seconden, minuten en uren, konden we zien dat de timer inderdaad in realtime werkte.
De timertijd wijkt enigszins af van de simulatietijd vanwege de reset van de module aan het begin van de simulatie. Het is zichtbaar in de eerste golfvorm waar de markering van 60 seconden op de tijdlijn iets eerder is dan wanneer het Seconden-signaal terugloopt naar 0.
Merk op dat in simulatie de tellerwaarden in nultijd worden bijgewerkt bij de stijgende flank van de klok. In de echte wereld zal de tellerwaarde enige tijd nodig hebben om zich te verspreiden van het eerste bit van de teller naar de laatste. Naarmate we de lengte van de tellers vergroten, verbruiken we de beschikbare tijd van een klokperiode.
Als de geaccumuleerde lengte van alle gecascadeerde tellers te lang wordt, wordt er na compilatie een fout geproduceerd in de plaats- en routestap. Hoe lang je een teller kunt implementeren voordat je de hele klokperiode verbruikt, hangt af van de FPGA- of ASIC-architectuur en kloksnelheid.
Een verhoogde kloksnelheid betekent dat de tellerketen langer zal zijn. Het betekent ook dat de klokperiode korter zal zijn, waardoor de tellerketen nog minder tijd heeft om te voltooien.
Afhaalmaaltijden
- Het meten van tijd in VHDL-modules wordt bereikt door klokcycli te tellen
- Het verlagen van de klokfrequentie in de testbank zal de simulatie versnellen
Ga naar de volgende tutorial »
VHDL
- Een lijst met strings maken in VHDL
- Hoe maak je een Tcl-gestuurde testbench voor een VHDL-codeslotmodule?
- Simulatie stoppen in een VHDL-testbench
- Een PWM-controller maken in VHDL
- Hoe willekeurige getallen te genereren in VHDL
- Hoe maak je een ringbuffer FIFO in VHDL
- Hoe maak je een zelfcontrolerende testbank aan
- Een gekoppelde lijst maken in VHDL
- Een procedure gebruiken in een proces in VHDL
- Een onzuivere functie gebruiken in VHDL
- Een functie gebruiken in VHDL