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
- Procedureverklaring - VHDL-voorbeeld
- Hoe gebruiken we molybdeen?
- Een lijst met strings maken in VHDL
- Simulatie stoppen in een VHDL-testbench
- Een PWM-controller maken in VHDL
- Hoe willekeurige getallen te genereren in VHDL
- Een procedure gebruiken in een proces in VHDL
- Een onzuivere functie gebruiken in VHDL
- Een functie gebruiken in VHDL
- Een eindige-toestandsmachine maken in VHDL
- Hoe een snijmolen te gebruiken