Allgemeines
Ein process
hat folgende Eigenschaften:
- Er besteht aus sequentiellen Anweisungen.
- Eine Sensitivity List definiert die Signale, bei deren Änderung die Anweisungen ausgewertet werden.
- Die "Ausführung" läuft parallel zu allen anderen
process
Statements - Der
process
selbst enthält keine nebenläufige Statements - Es erlaubt eine funktionale Beschreibung ähnlich zu einer Programmiersprache
Prozess für kombinatorische Schaltungen
Bei kombinatorischen Schaltungen gibt es keine speichernden Elemente. Die Ausgänge sind direkt von den Eingängen abhängig.
Beispiel
half_adder_sum: process (a_i, b_i) begin carry_o <= a_i and b_i; end process;
Dieser Prozess wertet den Ausdruck a_i and b_i
aus und weist das Ergebnis carry_o
zu. Diese Auswertung geschieht sobald sich a_i
oder b_i
ändert.
Einen kombinatorischen Prozess zeichnet aus, dass bei der Auswertung nur die Pegel der Signale ausgewertet werden.
Das obige Beispiel entspricht genau der folgenden nebenläufigen Anweisung:
carry_o <= a_i and b_i;
Prozess für sequentielle Schaltungen
Sequentiellen Schaltungen werden mittels speichernden Elementen (Register) realisiert. Bei synchronen Schaltungen arbeiten alle Register mit einem globalen Takt und reagieren auf die gleiche Taktflanke. Typischerweise wird die steigende Taktflanke gewählt, prinzipiell lässt sich aber auch die fallende Taktflanke wählen.
Erkennung einer Takflanke
Um eine Taktflanke erkennen zu können ist es notwendig, das Taktsignal in der Sensitivitätsliste hinzuzufügen. Damit wird der Prozess ausgewertet, wenn sich am Taktsignal etwas ändert.
Im folgenden Beispiel wird die Verwendung der Funktion rising_edge
gezeigt, um auf eine steigende Flanke an clk
zu reagieren:
Beispiel
library ieee ; use ieee.std_logic_1164.all; entity dff is port( clk: in std_ulogic; data_i: in std_ulogic; data_o: out std_ulogic ); end entity; architecture behave of dff is begin process(clk) begin if rising_edge(clk) then data_o <= data_i; end if; end process; end architecture;
Statt der Funktion rising_edge
lässt sich auch folgendes Konstrukt verwenden:
process(clk) begin if clk'event and clk='1' then data_o <= data_i; end if; end process;
Anweisung innerhalb eines Prozesses
if
-Anweisung
Die if
-Answeisung wertet die Bedingung aus und entsprechend dann den Wahr Zweig oder gegebenenfalls den Falsch Zweig (else
) oder eine andere Bedingung aus (elsif
). Die if
Anweisung wird mit endif;
beendet.
Beispiel
process(clear, load, input, counter) begin if clear='1' then result <= (others => '0'); elsif load='1' then result <= input else result <= counter + 1; end if; end process;
case
-Anweisung
Die case
-Anweisung überprüft den Zustand eines Signals und führt davon abhängig eine Anweisung aus.
Beispiel
process(digit_i) begin case digit_i is when "0000" => segments_o <= "0000001"; -- display 0 when "0001" => segments_o <= "1001111"; -- display 1 when "0010" => segments_o <= "0010010"; -- display 2 -- ... when others => segments_o <= "1111111"; end case; end process;
for
-Schleife
Die for
Schleife erlaubt den vielfachen Aufbau eines Schaltungsteils.
Beispiel
process(clk) begin if rising_edge(clk) then for i in range 1 to 7 loop shift_reg(i) <= shift_i(i-1); end loop; shift_reg(0) <= '0'; end if; end process;
Die Laufvariable i
muss nicht eigens definiert werden. Der Typ für i
ergibt sich aus den Elementen des Bereichs.