WieWo schrieb:
> Nabend!
> Ich habe eine (für die meisten wahrscheinlich ganz triviale) Frage:
>
> Wird VHDL sequentiell (zum Beispiel wie C) abgearbeitet oder nicht?
Falscher Ansatz. Klingt jetzt hart, ist aber sinnvoll ;-)
Ich nehme an, du möchtest Hardware synthetisieren. Hardware besteht aus
Schaltnetzen und Flipflops. Nun ist das ja so, dass Hardware eigentlich
kein 'nacheinander' kennt. Gut, hier und da etwas Laufzeit, aber die ist
praktisch klein. Deine Konstruktion wird hier und da etwas zappeln, wenn
sich Eingangssignale verändern, aber nach kurzer Zeit ist wieder Ruhe
und die Konstruktion gelangt in einen stabilen Zustand.
Das ist all jenes Zeug, was du in VHDL direkt hinschreiben kannst.
Zuweisungen, bedingte Zuweisungen, logische Operationen und so weiter.
Alles, was außerhalb von Prozessen steht. Völlig egal, in welcher
Reihenfolge du es notierst. Alles wird unmittelbar in irgendwelche
Logik-Gatter verschaltet; daran siehst du auch den Grund, warum ein
Signal nur an genau einer Stelle zugewiesen werden darf. Bei ehreren
Zuweisungen an dasselbe Signal hintereinander gilt nicht die letzte
Zuweisung, sondern es gibt sofort eine Fehlermeldung.
Prozesse sind ja vermutlich das, was dich gerade stutzig gemacht hat: Da
kann man 'if' und 'case' benutzen, mehrere Zuweisungen hintereinander
funktionieren wie in einer Programmiersprache. Das hat aber nichts damit
zu tun, dass da irgendetwas sequentiell läuft - auch Prozesse werden
strikt zu Logik-Gattern verschaltet!
Wie? So: VHDL funktioniert wie Papier und Bleistift. Ein Prozess in VHDL
bedeutet nur, dass du ein Blatt Papier hernimmst und die letzten
Zustände aller Signale aufschreibst. Das, was jetzt auf dem Papier
steht, heißt Eingangsvektor. Der Vektor hängt ja beispielsweise
irgendwie von den Eingangssignalen der gesamten Schaltung ab. Dann liest
du dir den Prozess von oben bis unten durch: Wo immer einem Signal ein
Wert zugewiesen wird, kritzelst du den Zustand durch und schreibst den
neuen daneben. Und wenn noch eine Zuweisung für dasselbe Signal kommt,
streichst du halt nochmals durch und notierst daneben. Und wenn ein
Signal in Abhängigkeit von einem anderen zugewiesen wird, ist diese
Abhängigkeit immer vom Eingangsvektor und nicht von deinem Gekritzel
(!). Wenn du fertig mit dem Prozess bist, guckst du dir den
Schmierzettel an. Da steht jetzt der Ergebnisvektor drauf. Und du
überlegst dir jetzt eine Logik-Schaltung, die den Eingangsvektor von
vorhin irgendwie zum Ergebnisvektor verknüpft. Fertig.
Ich habe oben von einer Abhängigkeit immer vom Eingangsvektor
geschrieben. Das hat eine wichtige Konsequenz: Es macht den
sequentiellen Charakter der Prozesse platt. Nimm folgendes Beispiel:
1 | signal a: STD_LOGIC := '0';
|
2 | signal b: STD_LOGIC := '0';
|
3 |
|
4 | process (a, b) is
|
5 | begin
|
6 | a <= '1';
|
7 | if a = '1' then
|
8 | b <= '1';
|
9 | end if;
|
10 |
|
11 | a <= '0';
|
12 | end process;
|
Hier werden die beiden Signale 'a' und 'b' immer '0' sein. Nach obigem
Schema, du schreibst dir zu Beginn den Eingangsvektor auf:
Erste Zeile durchdenken:
if-Anweisung durchdenken, wohl gemerkt: 'a' ist nicht das Gekritzel,
sondern nach wie vor der Eingangsvektor! 'a' ist '0', das if wird nicht
durchlaufen:
Letzte Zeile: '1' streichen und '0' daneben kritzeln:
'a' ist also am Ende immer '0' und 'b' hat sich nie verändert. Auf diese
Weise kannst du jeden Prozess platt machen in kombinatorische Logik,
damit erübrigt sich die Frage nach sequentiell oder nicht.