VHDL - Befehlsauswahl
(EN google-translate)
(PL google-translate)
VHDL ist eine sehr reiche, sehr umfangrteiche Sprache, die im Rahmen dieser Lehrveranstaltung nur in einem kleinen Ausschnitt behandelt werden kann.
Es gilt einen vernünftigen Ausschnitt zu finden, der es erlaubt eine Vielzahl mechatronischer Anwendungen zu realisieren und in sich ein "geschlossenes" System bildet. So macht es Sinn bei einem Einstieg von Innen nach außen zu gehen: Die direkte Verbindung nach Außen haben die Port-Ein- und Ausgänge. Signale dienen zur Realiserung innerer Zustände, können aber direkt auf Ein- und Ausgänge gemapt werden. Variablen sind zur Realisierung "innerer" Programmstrukturen teilweise effizienter, erfordern aber Konvertierungen, um nach außen wirksam zu werden (und es wird auf deren Darstellung hier weitgehend verzichtet).
Wie VHDL-Programme strukturiert sind, insbesondere die Repräsentation konkurrenter Strukturen mit VHDL, wurde anhand einer Vielzahl an Beispielen eingeführt.
Die nachfolgende Darstellung verzichtet darauf, dies erneut zu präsentieren. Hier soll es lediglich darum gehen, den verwendeten Sprachschatz ein wenig in systematischer Weise zu ergänzen. Es ist eine Art "Vokabelseite", weniger eine "Syntaxdarstellung".
Ergänzend lohnt aber auch ein Blick in folgende VHDL-Übersichten zur Syntax:
VHDL-Tutorium auf de.wikibooks.org
VHDL Syntax Referenz von José Nelson Amaral, Department of Computing Science University of Alberta.
VHDL - Mini - Referenz bei www.eng.auburn.edu.
FPGA-Programmierung mit VHDL bei www.fpga4fun.com.
Ein- und Ausgänge, Signale und Variablen
|
x <= y;
Code 0-1: Zuweisung bei Signalen
x := y;
Code 0-2: Zuweisung bei Variablen
Bis auf Weiteres werden Variablen hier nicht behandelt.
Konvertierungen
Neben Signalen vom Typ Standard-Logik, gibt es u.a. in VHDL auch noch U-Standard-Logik und Bit-Vektoren.
Auf U-Standard-Logik und Bit-Vektoren wird im Rahmen der Vorlesung verzichtet.
Es gibt entsprechende Konvertierungs-Methoden zwischen diesen Datentypen, die aber in dieser Vorlesung keine Anwendung finden:
HIER NICHT RELEVANT: to_bit,to_bitvector,to_StdULogic, to_StdULogic,to_StdLogicVector,to_StdLogicVector, to_StdULogicVector,to_X01,to_X01Z,to_UX01 und ev. weitere.
Dagegen sind folgende Konvertierungsmethoden relevant und teilweise bereits aufgetaucht:
wort <= conv_std_logic_vector(kleinerzaehler,VIERBIT'length);
Code 0-3: Beispiel zur Umwandlung eines Signals vom Typ INTEGER nach STD_LOGIC_VECTOR.
Konstanten
constant MAXIMALWERT: integer := 1000; constant MINIMALWERT: integer := 10;
Code 0-4: Beispiel zur Definition von Konstanten Werten
Operatoren
Operator | Bedeutung |
---|---|
|
Logisch UND |
|
Logisch ODER |
|
Logisch NICHT |
|
Logisch ANTIVALENZ (ungleich) |
|
Logisch ÄQUIVALENZ (gleich) |
|
Logisch NICHT-UND |
|
Logisch NICHT-ODER |
Tabelle 0-1: Logische Operatoren
&-Operator
Der &-Operator kann zur Verbindung logischer Wörter verwendet werden.
signal wort1 : std_logic_vector(3 downto 0) := "1010"; signal wort2 : std_logic_vector(3 downto 0) := "1110"; signal wort3 : std_logic_vector(7 downto 0) := "10101111"; -- .... -- .... --Verknüpfung zweier Vierbit-Worte zu einem 8-Bit-Wort wort3 <= wort1 & wort2; --Wiederholung eines Vierbit-Wortes wort3 <= wort1 & wort1; --Bitshift um eine Stelle nach links wort3 <= wort3(6 downto 0) & '0'; --Bitshift um zwei Stelle nach rechts wort3 <= "00" & wort3(7 downto 2); --Rotation nach links wort3 <= wort3(6 downto 0) & wort3(7);
Code 0-5: Beispiele zur Verknüpfung logischer Wörter, um bestimmte Operationen zu realisieren.
Alternativ existieren auch unmittelbar Shift- und Rotationsbefehle (sll,slr,rol,ror,..). Auf deren Behandlung wird hier verzichtet.
Operator | Bedeutung |
---|---|
|
Addition |
|
Subtraktion |
|
Multiplikation |
|
Division |
|
Potenzieren |
|
Betrag |
|
Modulodivision auch für negative Zahlen (Restdivision, in C-Syntax %) |
|
wie mod, bildet aber bei negativen Zahlen vorher den Betrag. |
Tabelle 0-2: Integer-Operatoren.
7 mod 3 liefert 1 (-7) mod 3 liefert 2 (so oft 3 zu 7 addieren bis positiv, dann Modulo bilden) 7 mod (-3) liefert -2 ("Symmetrie" zu obigen Beispielen) (-7) mod (-3) liefert -1 ("Symmetrie" zu obigen Beispielen) 7 rem 3 liefert 1 (wie mod) (-7) rem 3 liefert -1 (Betrag von -7, dann Modulo bilden, Ergebnis negativ) 7 rem (-3) liefert 1 (-7) rem (-3) liefert -1
Code 0-6: Beispiele zu mod und rem
Zahlendarstellung
Beispiel | Datentyp | Erläuterungen |
---|---|---|
|
integer | -231 bis 231-1 |
|
integer | |
|
integer | Basis#Ziffern#, Basis ganze Zahl 2..16 |
|
integer | |
|
integer | |
|
integer | |
|
integer | Binärzahl mit Unterstrich-Trennern zur besseren Lesbarkeit. |
|
integer | Oktalzahl |
|
integer | Hexadezimalzahl |
|
std_logic | |
|
std_logic | |
|
std_logic_vector(3 downto 0) | 4-Bit, Beginn mit MSB |
|
std_logic_vector(7 downto 0) |
Tabelle 0-3: Einige Möglichkeiten Zahlen in VHDL darzustellen.
Nicht behandelt: float, natural, positive, character, time.
Zustand | Bedeutung |
---|---|
'1' | Logisch 1 / true |
'0' | Logisch 0 / false |
'H' | schwache logische 1 |
'L' | schwache logische 0 |
'U' | nicht initialisiert |
'X' | unbekannt |
'Z' | fließend |
'-' | nicht von Belang |
Tabelle 0-4: Mögliche Zustände von std_logic und deren Bedeutung.
HINWEIS: Dagegen gibt es in der Bit-Logik nur '0' und '1'.
a <= '1'; a <= '0';
Code 0-7: HINWEIS: Toleriert, wenn a vom Typ std_logic, nicht toleriert, wenn a vom Typ std_ulogic.
Erläuterung: Anders als in C-Code sind beide Befehle als "concurrent" anzusehen. Ein Signal dem zweimal Werte zugewiesen werden, wird vom Compiler bei std_ulogic als widersprüchlich angesehen werden, bei std_logic nicht.
Kontrollstrukturen
if (zaehler<59999) then zaehler <= zaehler+1; elsif (zaehler<100000) then zaehler <= zaehler-1; else zaehler <= 0; end if;
Code 0-8: if...elsif...else...end if
Vergleich | Beschreibung |
---|---|
a < b | a kleiner b |
a <= b | a kleiner oder gleich b |
a > b | a größer b |
a >= b | a größer oder gleich b |
a = b | a gleich b (Achtung, einfaches Gleich statt doppeltes wie in C) |
a /= b | a ungleich b |
Tabelle 0-5: Logische Vergleichsoperatoren
Signal-Bedingungen | Beschreibung |
---|---|
meinsignal'event | wahr, wenn ein Pegrelwechsel auftritt |
meinsignal'active | wahr, wenn das Signal high ist |
meinsignal'transaction | Toggelt bei jeder Signalveränderung |
meinsignal'last_value | dem aktuellen Zustand vorangehender Wert des Signals |
meinsignal'last_event | Liefert den Zeitpunkt an dem das Signal sich zuletzt geändert hat |
meinsignal'last_active | Liefert den Zeitpunkt an dem das Signal zuletzt aktiv war |
meinsignal'delayed(T) | Wert des Signals vor T Zeiteinheiten |
meinsignal'stable(T) | wahr, wenn das Signal sich nicht in den letzten T Zeiteinheiten geändert hat |
meinsignal'quiet(T) | wahr, wenn das Signal in den letzten T Zeiteinheiten Null war |
Tabelle 0-6: Signal-Bedingungen.
if (CLOCK_6MHZ'event and CLOCK_6MHZ='1') then ... ... ... end if;
Code 0-9: Signal-Bedingungen - Beispiel.
Ebenfalls als Alternative interessant und bereits verwendet:
rising_edge(meinsignal) falling_edge(meinsignal)
Code 0-10: Methoden liefern wahr bei steigender, bzw. fallender Flanke des betreffenden Signals.