Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Industrial programming >> VHDL

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

  1. Een lijst met strings maken in VHDL
  2. Hoe maak je een Tcl-gestuurde testbench voor een VHDL-codeslotmodule?
  3. Simulatie stoppen in een VHDL-testbench
  4. Een PWM-controller maken in VHDL
  5. Hoe willekeurige getallen te genereren in VHDL
  6. Hoe maak je een ringbuffer FIFO in VHDL
  7. Hoe maak je een zelfcontrolerende testbank aan
  8. Een gekoppelde lijst maken in VHDL
  9. Een procedure gebruiken in een proces in VHDL
  10. Een onzuivere functie gebruiken in VHDL
  11. Een functie gebruiken in VHDL