VHDL-Kurs

[ASICs]  [Chip Typen]  [Chip Aufbau]  [Entwicklung ]  [Schnittstellen]  [Glossar]
 
     [Modellierung]  [Strategie]  [Synthese]  [ASIC Test]  [VHDL-Kurs] [Beispiel]
 
        
[VHDL-Typen]  [VHDL-Libraries]  [VHDL-Hierarchie]  [VHDL-Struktur]

VHDL-Kurs, Strukturelle Sprachelemente

Es folgen nun die VHDL-Sprachelemente, mit denen man innerhalb einer architecture (Hierarchie), einer procedure oder einer function das Verhalten des VHDL-Modells (entity + architecture + configuration) beschreibt. Viele dieser Elemente sind - wenn auch andere Schlüsselwörter und/oder eine etwas andere Syntax benutzt wird - aus den herkömmlichen Programmiersprachen aus dem Software-Bereich bekannt.

process_name : process (sensitivity list)
  [Deklarationen, z.B. constant, signal,
   component, function, procedure, ...]
  begin
   ...
  end process process_name;
 

sig_a <= sig_b and sig_c;

Der Prozeß ist das wichtigste Element in VHDL. Er ist eine eigenständige Einheit, die parallel zu allen anderen Prozessen agiert, die einkommenden Signale verarbeitet und die Werte für seine Ausgangssignale erzeugt.
Auch eine einzelne Zeile einer Signalzuweisung (wie im Beispiel links unten) auf Ebene der Prozesse ist selber ein Prozeß. Hier sind sig_b und sign_c die Eingangssignale und sig_a das Ausgangssignal.
 

procedure procedure_name (interface list) is
  [Deklarationen, z.B. constant, signal,
   component, function, procedure, ...]
  begin
   ...
  end procedure_name;

Mit einer Prozedur können Befehlsfolgen, die an mehreren Stellen im Design oder innerhalb eines Prozesses benutzt werden, an einer Stelle zusammengefaßt werden. Dieses Vorgehen erhöht die Übersichtlichkeit des VHDL-Codes. Die Prozedur kann auf lokale Prozeßvariablen zugreifen, aber auch auf Signale.
Die Interface Liste ist eine Sammlung von Parametern, die beim Aufruf der Prozedur an diese übergeben werden.
Die Prozedur liefert keinen Ergebniswert (wenn man mal von den Änderungen übergeordneter Variablen oder Signale absieht).
 

function function_name (interface list)
           return result_type is
  [Deklarationen, z.B. constant, signal,
   component, function, procedure, ...]
  begin
   ...
   return result;
  end function_name;

Eine Funktion ist wie eine Prozedur aufgebaut und hat die gleichen Zugriffsmechanismen auf Signale und übergeordnete Variablen. Hinzu kommt, daß die Funktion einen Wert an die Stelle des Aufrufs zurück gibt, der durch das letzte aufgerufene return-Kommando festgelegt wird. Ein Beispiel für einen Funktionsaufruf ist:
sig_a <= connect(mode, sig_b, sig_c);
 

if condition_1 then
  [true_block_1];
elsif condition_2 then
  [true_block_2];
else
  [else_block];
end if;

Die if ... then ... else Struktur wird in jeder Programmiersprache benutzt und muß daher an dieser Stelle nicht ausführlich vorgestellt werden. In der condition werden auch hier Aussagen auf ihren Wahrheitsgehalt hin untersucht (true oder false). Abhängig von dem Ergebnis wird der true-Block ausgeführt oder die nächste condition überprüft. Wird keine der Bedingungen erfüllt, wird der else-Block ausgeführt.
Die elsif und else Blöcke sind optional.
 

case Ausdruck is
  when value_1 => [block_1];
  ...
  when value_n => [block_n];
  when v1, v2, v3 => [block_v123];
  when others => [block_others];
end case;

Mit der case Anweisung kann eine VHDL Simulation entsprechend des in ausdruck berechneten Wertes in einen für diesen Wert definierten Ausführungsblock verzweigen. Dieses ließe sich auch mit einer längeren if ... then ... else Struktur nachbilden, ist aber nicht so elegant. In der Ausführung beider Möglichkeiten werden keine Unterschiede auftreten, jedoch gibt es bei einigen Synthese-Werkzeugen u.U. Unterschiede der erzeugten Netzliste in Hinblick Größe und Geschwindigkeit.
Die Selektion zu einem Ausführungsblock kann auch aufgrund mehrerer Werte erfolgen. In diesem Fall können die einzelnen Werte jeweils durch Komma getrennt werden, z.B.:
when 1,2,3 => [block_123];
 

for index in value_start to/downto value_end
  loop
   ...
  end loop;

In einer Schleife wird der in der Schleife enthaltene Code gesteuert durch eine Indexvariable mehrfach durchlaufen. Der Indexwert beginnt beim ersten Durchlauf mit value_start und endet beim letzten Durchlauf mit value_end. Die Richtung +1 oder -1 wird entweder durch to oder downto vorgegeben.
Der Inkrementwert ist normalerweise 1 bzw. -1, kann aber über die Erweiterung step x auf ein anderes Inkrement gesetzt werden.
 

process_name : process;
  begin
   wait until
clk´event and clk = `1´;
   ...
  end process process_name;

 

 

process_name : process (clk, reset)
  begin
   if reset = `0´ then
     ...
   elsif clk´event and clk = `1´ then
     ...
   end if;
  end process process_name;

Im Allgemeinen werden Ausdrücke in if ... then ... else, loop oder case Strukturen in kombinatorische Logik, also als logische Verknüpfungen synthetisiert. Die auch als sequentielle Logik bezeichneten FlipFlops können über zwei besondere Statements bzw. Prozeßstrukturen (links) erzeugt werden:

  • wait until Statement
    Alle Signale, denen im Prozeß ein Wert zugewiesen wird, werden mit einem FlipFlop realisiert.
  • Sensitivity List
    s. 2. Beispiel:
    Alle Signale, denen im Prozeß ein Wert zugewiesen wird, werden mit einem FlipFlop realisiert.
    Über diese Struktur können die FlipFlops mit einem asynchronen Reset ausgestattet werden.

Wird in keinem der möglichen if-Zweige (hier in `...´ nicht extra aufgeführt) einem Signal ein neuer Wert zugewiesen, wird der alte Wert behalten.
 

Logische Operationen
Mit den logischen Operatoren and, or, not und exor können boolsche Ausdrücke aufgebaut werden, deren Wert true oder false ergeben kann. Diese sind die Basis für if ... then ... else ... end if; Strukturen. Diese Operatoren können auch auf Bits und Bitvektoren angewendet werden. Beispiele sind:

  • out_bool <= in_bool and (not enable);
  • out_bit <= in_bit exor bit_invert;
  • if (state1 = go) and ((state2 = idle) or (state2 /= start)) then ...

 

top 

[Home] [ASICs] [Selbstmanagement] [Inselmeer] [Spiele]
[Ich über mich] [Links] [SiteMap] [Disclaimer]