Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Industrial programming >> VHDL

So erstellen Sie einen Timer in VHDL

In früheren Tutorials haben wir den wait for verwendet Anweisung, um die Zeit in der Simulation zu verzögern. Aber was ist mit Produktionsmodulen? Die wait for Aussage kann dafür nicht verwendet werden. Das funktioniert nur in der Simulation, weil wir den Elektronen in einem Stromkreis nicht einfach sagen können, dass sie für eine bestimmte Zeit pausieren sollen. Wie können wir also die Zeit in einem Designmodul im Auge behalten?

Die Antwort ist einfach das Zählen von Taktzyklen. Jedes digitale Design hat Zugriff auf ein Taktsignal, das mit einer festen, bekannten Frequenz schwingt. Wenn wir also wissen, dass die Taktfrequenz 100 MHz beträgt, können wir eine Sekunde messen, indem wir hundert Millionen Taktzyklen zählen.

Dieser Blogpost ist Teil der Reihe Basic VHDL Tutorials.

Um Sekunden in VHDL zu zählen, können wir einen Zähler implementieren, der die Anzahl der verstreichenden Taktperioden zählt. Wenn dieser Zähler den Wert der Taktfrequenz erreicht, beispielsweise 100 Millionen, wissen wir, dass eine Sekunde vergangen ist und es Zeit ist, einen weiteren Zähler zu erhöhen. Nennen wir dies den Sekundenzähler.

Um die Minuten zu zählen, können wir einen weiteren Minutenzähler implementieren, der nach Ablauf von 60 Sekunden hochzählt. Auf ähnliche Weise können wir einen Stundenzähler zum Zählen von Stunden erstellen, der nach Ablauf von 60 Minuten erhöht wird.

Wir können diesen Ansatz auch zum Zählen von Tagen, Wochen und Monaten fortsetzen. Wir sind durch die verfügbaren physischen Ressourcen in der zugrunde liegenden Technologie sowie durch die Länge des Zählers im Verhältnis zur Taktfrequenz begrenzt.

Je länger die Zähler werden, desto mehr Ressourcen werden natürlich verbraucht. Aber es wird auch langsamer reagieren, weil die Ereigniskette länger wird.

Übung

In diesem Video-Tutorial lernen wir, wie man ein Timer-Modul in VHDL erstellt:

Der endgültige Code für die 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;

Der endgültige Code für das Timer-Modul :

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;

Die Wellenform wurde auf Seconds vergrößert Signal:

Die Wellenform wurde auf Minutes vergrößert Signal:

Die Wellenform wurde auf Hours vergrößert Signal:

Analyse

Um eine 50-Stunden-Simulation auszuführen, haben wir den Befehl run 50 hr gegeben in der ModelSim-Konsole. 50 Stunden sind eine wirklich lange Simulation, und deshalb mussten wir die Taktfrequenz in der Testbench auf 10 Hz senken. Hätten wir es bei 100 MHz belassen, hätte die Simulation Tage gedauert. Solche Anpassungen sind manchmal notwendig, damit wir ein Design simulieren können.

Wir haben mit der rechten Maustaste auf die Zeitleiste in der Wellenform geklickt und „Grid, Timeline &Cursor Control“ ausgewählt. Als wir die Zeiteinheit von ns auf Sekunden, Minuten und Stunden änderten, konnten wir sehen, dass der Timer tatsächlich in Echtzeit arbeitete.

Die Zeit des Timers ist wegen des Zurücksetzens des Moduls zu Beginn der Simulation leicht von der Simulationszeit versetzt. Es ist in der ersten Wellenform sichtbar, wo die 60-Sekunden-Markierung auf der Zeitachse kurz vor dem Übergang des Sekundensignals auf 0 liegt.

Beachten Sie, dass in der Simulation die Zählerwerte in Nullzeit an der steigenden Flanke der Uhr aktualisiert werden. In der realen Welt benötigt der Zählerwert einige Zeit, um sich vom ersten Bit des Zählers bis zum letzten auszubreiten. Wenn wir die Länge der Zähler erhöhen, verbrauchen wir die verfügbare Zeit einer Taktperiode.

Wenn die kumulierte Länge aller kaskadierten Zähler zu lang wird, wird nach der Kompilierung ein Fehler im Place-and-Route-Schritt erzeugt. Wie lange ein Zähler implementiert werden kann, bevor er die gesamte Taktperiode verbraucht, hängt von der FPGA- oder ASIC-Architektur und der Taktrate ab.

Eine erhöhte Taktgeschwindigkeit bedeutet, dass die Zählerkette länger wird. Es bedeutet auch, dass die Taktperiode kürzer ist, wodurch die Zählerkette noch weniger Zeit zum Abschließen hat.

Imbiss

Weiter zum nächsten Tutorial »


VHDL

  1. So erstellen Sie eine Liste von Zeichenfolgen in VHDL
  2. So erstellen Sie eine Tcl-gesteuerte Testbench für ein VHDL-Code-Sperrmodul
  3. So stoppen Sie die Simulation in einer VHDL-Testbench
  4. So erstellen Sie einen PWM-Controller in VHDL
  5. So generieren Sie Zufallszahlen in VHDL
  6. So erstellen Sie einen Ringpuffer-FIFO in VHDL
  7. So erstellen Sie eine selbstüberprüfende Testbench
  8. So erstellen Sie eine verknüpfte Liste in VHDL
  9. So verwenden Sie eine Prozedur in einem Prozess in VHDL
  10. So verwenden Sie eine Funktion in VHDL