Forum: FPGA, VHDL & Co. Sequentiell oder nicht?


von WieWo (Gast)


Lesenswert?

Nabend!
Ich habe eine (für die meisten wahrscheinlich ganz triviale) Frage:

Wird VHDL sequentiell (zum Beispiel wie C) abgearbeitet oder nicht?

Denn wenn Ja; Wie macht man das dann z.B. mit einem 
Ripple-Carry-Addierer. Würde hier alles parallel berechnet, dann sind 
die ganzen Carry-Bits der vorherigen Volladdierer ja noch gar nicht 
"fertig" o.O

Vielen Dank für die Erhellung..

von Dussel (Gast)


Lesenswert?

Gute Frage.
Du musst das taktweise betrachten. Zwischen zwei Taktflanken wird 
parallel abgearbeitet, aber während der Taktperiode sequentiell. Bei dem 
Ripple-Carry legst du das Ergebnis an und nach einem Takt ist das 
Ergebnis berechnet. Allerdings läuft die Kette nacheinander durch.
Das ist auch der begrenzende Faktor für den Takt. Alle 'gleichzeitig' 
ablaufenden Prozesse müssen während einer Taktperiode abgearbeitet 
werden können.

von Klaus (Gast)


Lesenswert?


von Hmm (Gast)


Lesenswert?

>Wird VHDL sequentiell (zum Beispiel wie C) abgearbeitet oder nicht?

Weder noch!

Aber wenn man mal ausser acht lässt, das VHDL nicht "abgearbeitet" wird, 
in dem Sinne wie ein Programmtext durch einen Interpreter interpretiert 
wird dann muss die Antwort wohl

Sowohl als auch!

lauten.

Das wird Dich vielleicht zum lachen bringen aber dennoch ein wenig 
frustrieren.

Der Punkt ist, das Du in VHDL Schaltungsstrukturen beschreibst. Als 
solche sind per se alle Schaltungsteile gleichzeitig aktiv und reagieren 
gleichzeitig auf die jeweiligen Änderungen ihrer Eingangssignale.

Durch die Anordnung der Elemente erhälst Du gewisse sinnreiche Folgen 
von Verarbeitungsschritten.

Eine Vereinfachung eines komplexen Ablaufes, wie er durch die 
Signallauf- und Verarbeitungszeiten entsteht, kann erreicht werden (und 
wird auch dringend empfohlen, aber auch darin gibt es Kontroversen) 
indem man die Gesamtaufgabe zeitlich in Teilschritte zerlegt, und über 
Register und Flip-Flops jeweisl Teilresultate an nachfolgende 
Kombinatorische Teile weiterreicht. In diesem letzteren Sinne, aber 
wohlgemerkt aufgrund der Befolgung einer Empfehlung, erfolgen Aktionen 
nacheinander.

Von einer "Verarbeitung" zur Laufzeit des FPGA kann aber eindeutig nicht 
die Rede sein.

Dein Beispiel eines Ripple-Ripple-Carry-Addiererdas Paradebeispiel einer 
Struktur die dieser zuletzt erwähnten Empfehlung nicht folgt. Wie Du 
richtig erkannt hast:

>Würde hier alles parallel berechnet, dann sind die ganzen Carry-Bits der 
>vorherigen Volladdierer ja noch gar nicht "fertig"

gibt es nach der Änderung der Eingangssignale eine Zeitlang ungültige 
Ergebnisse. Genauso richtig, qualifizierst Du diese "Zeitlang" als den 
bis alle "vorherigen" Volladerer "fertig" sind.

An und für sich (die erwähnte Kontroverse zwischen den "Synchronen 
Menschen" und den Asynchronen Menschen" erstmal ausser acht gelassen) 
ist das nicht weiter negativ.
Man muss es nur wissen und beachten, in dem man die Durchlaufzeit von 
den Eingängen des ersten Addierers bis zu den Ausgängen des letzten 
Addierers abwartet bevor man das Ergebnis abliest.

Das prinzipiell analoge Bild ergibt sich auch bei einem 
Parallel-Addierer. Auch hier muss eine gewisse Zeit abgewartet werden 
bis das Ergebnis gültig ist. Aufgrund der Struktur, die logisch völlig 
zu dem Ripple-Addierer identisch ist (und sein muss, sonst wäre es keine 
Addierer), ist aber diese Zeit deutlich kürzer. Wesentlich aber ist, das 
die Zeit nicht mehr von der Anzahl der Stellen abhängt.

von WieWo (Gast)


Lesenswert?

Vielen Dank!

von Sven P. (Gast)


Lesenswert?

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:
1
a  0 |
2
b  0 |

Erste Zeile durchdenken:
1
a  0 | 1
2
b  0 |

if-Anweisung durchdenken, wohl gemerkt: 'a' ist nicht das Gekritzel, 
sondern nach wie vor der Eingangsvektor! 'a' ist '0', das if wird nicht 
durchlaufen:
1
a  0 | 1
2
b  0 |

Letzte Zeile: '1' streichen und '0' daneben kritzeln:
1
a  0 | (1) 0
2
b  0 |

'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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Sven P. schrieb:
> Ich habe oben von einer Abhängigkeit immer vom Eingangsvektor
> geschrieben. Das hat eine wichtige Konsequenz: Es macht den
> sequentiellen Charakter der Prozesse platt.
Jetzt warte ich gespannt auf die Variablen, die sich ja "sofort" ändern, 
und deshalb so gern von ehemaligen Softwareprogrammierern verwendet 
werden...    ;-)

WieWo schrieb:
> Wird VHDL sequentiell (zum Beispiel wie C) abgearbeitet oder nicht?
Ja.
> Denn wenn Ja; Wie macht man das dann z.B. mit einem
> Ripple-Carry-Addierer. Würde hier alles parallel berechnet, dann sind
> die ganzen Carry-Bits der vorherigen Volladdierer ja noch gar nicht
> "fertig" o.O
Es dauert ein paar hundert ps, bis die komplette Carry-Chain durchlaufen 
ist, aber das kommt nicht daher, dass die "Befehle" nacheinander 
"abgearbeitet" werden, sondern daher, dass die Logik der Carry-Kette und 
die Verdrahtung zwischen den Addierern eine gewissen Laufzeit haben und 
somit das Carry durch die Addiererkette einfach "durchrieselt" (daher 
kommt auch der Name "to ripple"). Aber der komplette Addierer existiert 
parallel in Hardware, er wird nicht Bit für Bit berechnet...

von Sven P. (Gast)


Lesenswert?

Lothar Miller schrieb:
> Sven P. schrieb:
>> Ich habe oben von einer Abhängigkeit immer vom Eingangsvektor
>> geschrieben. Das hat eine wichtige Konsequenz: Es macht den
>> sequentiellen Charakter der Prozesse platt.
> Jetzt warte ich gespannt auf die Variablen, die sich ja "sofort" ändern,
> und deshalb so gern von ehemaligen Softwareprogrammierern verwendet
> werden...    ;-)
This page was intentionally left blank...

von Hmm (Gast)


Lesenswert?

>Es dauert ein paar hundert ps...
Picosekunden? Ich will auch so'n FPGA!!!

von Sven P. (Gast)


Lesenswert?

Weiso? Ein paar Hundert Pikosekunden sind ne halbe Nanosekunde. Ist doch 
realistisch.

von Hmm (Gast)


Lesenswert?

Ach. Ich schlag mich gerade mit einem rum, für den 10ns pro Gatter schon 
Turbo sind.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hmm schrieb:
>>Es dauert ein paar hundert ps...
> Picosekunden? Ich will auch so'n FPGA!!!
Für die Durchlaufzeit durch eine LUT (bzw. einen CLB) findest du in den 
Datenblättern Zeiten zwischen 200ps und 700ps...
Dazu kommt natürlich noch die Verdrahtung. Aber gerade bei der 
Carry-Chain kannst du sicher sein, dass sie effizient implementiert ist, 
denn jeder Zähler braucht diese Kette.

Hmm schrieb:
> Ach. Ich schlag mich gerade mit einem rum, für den 10ns pro Gatter schon
> Turbo sind.
Welche Technologie?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.