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 procedure gebruiken in VHDL

Een procedure is een soort subprogramma in VHDL dat ons kan helpen herhalende code te voorkomen. Soms ontstaat de behoefte om op meerdere plaatsen in het ontwerp identieke bewerkingen uit te voeren. Hoewel het maken van een module misschien overkill is voor kleine bewerkingen, is een procedure vaak wat je wilt.

Procedures kunnen binnen elke declaratieve regio worden gedeclareerd. De reikwijdte van de procedure is beperkt tot waar het is gedeclareerd, architectuur, pakket of proces. Telkens wanneer u de procedure aanroept, zal deze zich gedragen alsof de code van de procedure is ingevoegd waar deze werd aangeroepen.

Een procedure retourneert geen waarde zoals een functie doet, maar u kunt waarden retourneren door out te declareren of inout signalen in de parameterlijst.

Deze blogpost maakt deel uit van de serie Basic VHDL Tutorials.

De basissyntaxis voor het maken van een procedure is:
procedure <procedure_name> (signal|variable|constant <name1> : in|out|inout <type>;
                            signal|variable|constant <name2> : in|out|inout <type>;
                            ... ) is
    <declarations_for_use_within_the_procedure>
begin
    <code_performed_by_the_procedure_here>
end procedure;

De parameterlijst van een procedure definieert zijn ingangen en uitgangen, een beetje zoals een minimodule. Het kan een signaal of een constante zijn, maar in tegenstelling tot een module kan het ook een variabele zijn. U kunt objecten declareren tussen de trefwoorden "is" en "begin" die alleen geldig zijn binnen de procedure. Dit kunnen constanten, variabelen, typen, subtypen en aliassen zijn, maar geen signalen.

In tegenstelling tot functies kunnen procedures wait-statements bevatten. Daarom worden ze vaak gebruikt in testbanken, zoals eenvoudige BFM's voor het simuleren van interfaces, of voor het controleren van de output van het te testen apparaat (DUT).

Oefening

In de vorige zelfstudie hebben we een timermodule gemaakt met behulp van geneste If-Then-Else-instructies. Elk niveau van Als-Dan-Anders binnen een ander Als-Dan-Anders voegt complexiteit toe aan het ontwerp en wordt het minder leesbaar. Op elk niveau van logica doen we in principe dezelfde bewerking op een andere reeks signalen. Is er geen betere manier om dit te doen?

In deze video-tutorial leren we hoe we een procedure in VHDL kunnen maken:

De definitieve code voor de procedure testbench :

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity T19_ProcedureTb is
end entity;

architecture sim of T19_ProcedureTb 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.T19_Timer(rtl)
    generic map(ClockFrequencyHz => ClockFrequencyHz)
    port map (
        Clk     => Clk,
        nRst    => nRst,
        Seconds => Seconds,
        Minutes => Minutes,
        Hours   => Hours);

    -- Process for generating 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 met behulp van een procedure:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity T19_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 T19_Timer is

    -- Signal for counting clock periods
    signal Ticks : integer;

    procedure IncrementWrap(signal   Counter   : inout integer;
                            constant WrapValue : in    integer;
                            constant Enable    : in    boolean;
                            variable Wrapped   : out   boolean) is
    begin
        Wrapped := false;
        if Enable then
            if Counter = WrapValue - 1 then
                Wrapped := true;
                Counter <= 0;
            else
                Counter <= Counter + 1;
            end if;
        end if;
    end procedure;

begin

    process(Clk) is
        variable Wrap : boolean;
    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

                -- Cascade counters
                IncrementWrap(Ticks, ClockFrequencyHz, true, Wrap);
                IncrementWrap(Seconds,             60, Wrap, Wrap);
                IncrementWrap(Minutes,             60, Wrap, Wrap);
                IncrementWrap(Hours,               24, Wrap, Wrap);

            end if;
        end if;
    end process;

end architecture;

Het golfvormvenster in ModelSim, ingezoomd op de tijdlijn waar de Minutes signaal wikkelt zich af:

Analyse

We kunnen aan de golfvorm zien dat het omwikkelen van signalen nog steeds werkt zoals in de vorige tutorial. Dat komt omdat we de functie op de module niet echt hebben veranderd, alleen de manier waarop deze is geïmplementeerd.

Het eerste item op de parameterlijst voor de IncrementWrap procedure is de Counter signaal. Het wordt gedeclareerd met richting inout zodat de procedure zowel de waarde ervan kan lezen als instellen.

Het tweede en derde item in de parameterlijst zijn constanten. Dit betekent dat de waarden die u hier invoert, als constanten in verschijnen van de procedure. De WrapValue invoer samen met de Enable invoer bepaalt of de Counter signaal wordt verhoogd of ingepakt.

Het laatste item op de parameterlijst is een variabele met richting out . Het doel van deze uitvoer is om de beller te informeren over de procedure die de teller heeft beëindigd. We gebruiken het hier als een retourwaarde.

In het hoofdproces hebben we vier aanroepen naar de IncrementWrap procedure. Elk van de volgende oproepen gebruikt de Wrap variabele om het tellen mogelijk te maken. Het zou niet hebben gewerkt als we een signaal hadden gebruikt in plaats van een variabele, omdat signaalwaarden alleen worden bijgewerkt als een proces in slaap valt. We hebben de uitvoerwaarde van de ene procedureaanroep nodig om te worden gebruikt als invoer voor een aanroep op de volgende regel. Het moet dus een variabele zijn.

Afhaalmaaltijden

  • Procedures kunnen worden gebruikt als minimodules om het kopiëren en plakken van code te voorkomen
  • Parameters (ingangen/uitgangen) voor een procedure kunnen signalen, variabelen of constanten zijn
  • In tegenstelling tot functies kunnen procedures wait-statements bevatten

Ga naar de volgende tutorial »


VHDL

  1. Procedureverklaring - VHDL-voorbeeld
  2. Hoe gebruiken we molybdeen?
  3. Een lijst met strings maken in VHDL
  4. Simulatie stoppen in een VHDL-testbench
  5. Een PWM-controller maken in VHDL
  6. Hoe willekeurige getallen te genereren in VHDL
  7. Een procedure gebruiken in een proces in VHDL
  8. Een onzuivere functie gebruiken in VHDL
  9. Een functie gebruiken in VHDL
  10. Een eindige-toestandsmachine maken in VHDL
  11. Hoe een snijmolen te gebruiken