Een betrouwbare timer in VHDL bouwen: klokcycli tellen tot uren
In eerdere tutorials gebruikten we de wait for-statement om tijd in simulatie te vertragen. Echter, wait for kan niet in productieontwerpen gebruikt worden omdat een echt circuit niet kan worden geïnstrueerd om te pauzeren. De praktische manier om tijd in een VHDL-module te meten is door klokcycli te tellen.
Elk digitaal ontwerp heeft toegang tot een stabiel kloksignaal dat oscilleert op een bekende frequentie. Als de klok op 100 MHz draait, is één seconde gelijk aan 100 miljoen klokpulsen. Door deze pulsen te tellen kunnen we betrouwbaar seconden, minuten, uren en meer genereren.
Dit artikel is onderdeel van de Basic VHDL Tutorials-reeks.
We implementeren een teller die op elke stijgende flank van de klok incrementeert. Wanneer de teller de klokfrequentie-waarde bereikt, is er één seconde verstreken en wordt een secundaire "Seconds"-teller geïncrementeerd. Een vergelijkbare aanpak wordt gebruikt voor minuten (increment na 60 seconden) en uren (increment na 60 minuten). Extra tellers kunnen gekoppeld worden voor dagen, weken of maanden, beperkt alleen door FPGA/ASIC-resources en de benodigde tellerbreedte.
Hoewel langere tellers meer logica-resources consumeren, verhogen ze ook de propagatievertraging. Het kritieke pad door de tellerketen moet binnen de klokperiode passen, anders zal synthetiseren falen.
Oefening: De timer implementeren
De volgende VHDL-testbench demonstreert een eenvoudige 10 Hz klok om de simulatiетijd redelijk te houden. De DUT is een timer die Seconds, Minutes en Hours signalen uitvoert.
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 -- Trage klok voor snelle simulatie 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 -- 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); -- Klokgenerator Clk <= not Clk after ClockPeriod / 2; -- Testbench-sequentie process is begin wait until rising_edge(Clk); wait until rising_edge(Clk); -- Reset vrijgeven nRst <= '1'; wait; end process; end architecture;
Hieronder is de timermodule zelf. Het telt ticks, seconden, minuten en uren, en reset alle tellers wanneer de negatieve reset (nRst) geactiveerd wordt.
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; -- Negatieve reset Seconds : inout integer; Minutes : inout integer; Hours : inout integer); end entity; architecture rtl of T18_Timer is -- Tel klokperiodes signal Ticks : integer; begin process(Clk) is begin if rising_edge(Clk) then if nRst = '0' then Ticks <= 0; Seconds <= 0; Minutes <= 0; Hours <= 0; else if Ticks = ClockFrequencyHz - 1 then Ticks <= 0; if Seconds = 59 then Seconds <= 0; if Minutes = 59 then Minutes <= 0; 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;
Golven bevestigen de correcte werking: Seconds incrementeert elke tick, Minutes na 60 seconden, en Hours na 60 minuten.
In simulatie voerden we een 50-uurs test uit met run 50 hr in ModelSim, met een 10 Hz klok om de runtime beheersbaar te houden. Het aanpassen van de klokfrequentie in de testbench is een veelvoorkomende strategie om verificatie te versnellen.
In echte hardware moet de tellerketen binnen één klokperiode klaar zijn. Naarmate de tellerbreedte groeit, neemt de propagatievertraging toe, wat potentiëel de periode kan overschrijden en timing-violaties veroorzaken. De exacte limiet hangt af van de FPGA/ASIC-familie en kloksnelheid.
Belangrijkste opmerkingen
- Tijdmeting in VHDL wordt bereikt door klokcycli te tellen.
- Het verlagen van de testbench-klokfrequentie versnelt simulatie zonder het ontwerp te wijzigen.
Ga door naar de volgende tutorial voor geavanceerde timer-functies.
VHDL
- Dynamische string-lijsten in VHDL: Best Practices & Voorbeeld
- Een Tcl-gedreven testbench maken voor een VHDL code-lock module
- Een VHDL-testbench netjes beëindigen: methoden en best practices
- Een PWM-controller implementeren in VHDL: Ontwerp, Simulatie en FPGA-demo
- Willekeurige getallen genereren in VHDL: Van Uniform naar OSVVM
- Ontwerpen van een robuuste VHDL-ringbuffer FIFO in blok-RAM
- Een self-checking testbench in VHDL bouwen – Een praktische gids
- Een dynamische gelinkte lijst in VHDL implementeren met protected types en access pointers
- In-process procedures benutten voor schonere VHDL FSM-ontwerpen
- Impure functies in VHDL gebruiken: FSM-leesbaarheid en onderhoudbaarheid verbeteren
- VHDL-functies onder de knie krijgen: een praktische gids voor efficiënt ontwerp