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