Forum: FPGA, VHDL & Co. Pipeline anhalten


von Michael S. (decimad)


Lesenswert?

Grüße!

Und zwar habe ich hier eine getaktete Pipeline, durch die Daten 
geschleust werden. Ich komme nun in die Situation, die Pipeline 
zeitweise anhalten zu müssen.
Nun ist es ja so, dass pro Informationsübertragung zwischen zwei Stufen 
im getakteten Fall immer (mindestens) ein Taktzyklus gebraucht wird. 
Dies gilt natürlich auch für einen rückgeführten "busy"- oder auch 
"ready"-Ausgang, der zur vorgeschalteten Einheit gerichtet ist. Mir sind 
jetzt auf Anhieb zwei Möglichkeiten bzw. eine Kombination beider 
eingefallen, um dem Abhilfe zu verschaffen:

1) Der rückgeführte Statuskanal ist kombinatorisch ausgelegt, also nicht 
getaktet. So bekommen im Idealfall N vorhergende Ebenen die Information, 
dass es im nächsten Takt nicht weitergeht.

2) Die Einheit vor einer Einheit, die nicht kombinatorisch zurückführt, 
hat einen Zwischenpuffer für Eingangsdaten, sodass sie einen Taktzyklus 
überbrücken kann, in dem sie keine Daten los wird.

Beide ließen sich natürlich auch kombinieren, wenn zum Beispiel der 
kombinatorische Pfad nach Ansatz 1 zu komplex wird, also zu lang 
braucht, um ausgewertet zu werden. Dann würde man einen Block nach 
Ansatz 2) zwischenschalten und von da wieder kombinatorisch 
weitermachen.

Wohlgemerkt ist das jetzt ein Ansatz, der mir so einfallen ist. Habt ihr 
bessere Lösungen parat? Sehe ich das Problem vielleicht vollkommen aus 
der falschen Perspektive oder verstehe die Sache falsch? Ich möchte auf 
jeden Fall, dass eine Einheit tief in der Pipeline dafür sorgen kann, 
dass die Pipeline angehalten wird, möglichst, ohne x Taktzyklen zu 
verplempern oder mit Speicher um mich zu schmeißen.
Würde mich über input sehr freuen!

Viele Grüße,
Deci

PS: Das Schicksal will es, dass hier zwei Michael S. unterwegs sind. 
Kann ich irgendwie dafür sorgen, dass im Forenindex mein Pseudonym 
angezeigt wird, sodass es zu keinen Verwechslungen kommt?

von Michael S. (decimad)


Lesenswert?

Kleiner Zwischenbericht:

Also ich habe es jetzt mal komplett kombinatorisch umgesetzt und komme 
damit auf 287mhz maximal von ~350mhz runter. Alles noch im grünen 
Bereich, weil ich bloß die 100 schaffen muss, aber wenn es besser geht, 
wäre das natürlich dennoch interessant ;)

Morgen erstmal weiter simulieren und bugs fixen, hehe.

von Duke Scarring (Gast)


Lesenswert?

Da kannst auch einen FIFO dranhängen, der die restlichen Werte, die in 
der Pipeline hängen aufsammelt. Das ist eine erweiterte Lösung zu 2.

Bei kleinen Sachen mag das ja mit der kombinatorischen Rückführung noch 
gehen, bei größeren wird es Dir regelmäßig das Timing zerschmeißen.

Duke

von Michael S. (decimad)


Lesenswert?

Ja genau, das mit dem kombinatorischen betrachte ich ja auch mit 
gewisser Skepsis gegenüber den negativen Auswirkungen bezüglich des 
Timings.
Der Fifo gefällt mir, weil man damit nicht in die Blöcke selber 
eingreift. Allerdings sehe ich auch Situationen, in denen die Daten in 
den echten Stages sein müssen, weil diese die Daten zu wiederum anderen 
Pfaden in Stage-spezifischer Art und Weise in Beziehung setzen.
Ein Allheilmittel wird es wohl da nicht geben, aber es ist natürlich 
praktisch, das gesamte Werkzeugarsenal zu kennen, um einen vernünftigen 
Kompromiss zu finden.
Danke für den Gedanken!

Viele Grüße,
Deci

von Fragender (Gast)


Lesenswert?

Kann man nicht an jedes Register ein enable hängen?

von Michael S. (decimad)


Lesenswert?

Ich kann Dir jetzt nicht so recht folgen. Kannst Du da evtl. noch ein 
bisschen ausholen?

von Fragender (Gast)


Lesenswert?

Register schalten Werte nur weiter, wenn das ena = 1 ist. Global 
abgeschaltet, wird die Pipeline um 1 cc verzögert.

von Michael S. (decimad)


Lesenswert?

Achso. Ja klar, für eine Pipeline-Stage rückwärts funktioniert das ja. 
Aber sagen wir Stage n und n+1 haben jeweils Kriterien, die zu einem 
Stall führen. n+1 kann sie auf n zurückführen, aber n-1 muss ja von n+1 
auch erfahren, dass es nicht weitergeht, und zwar im selben Takt. Also 
muss das Signal von n mit dem von n+1 kombinatorisch verbunden werden 
und dann zurückgeführt. So ergeben sich halt beliebig große (und auch 
räumlich "lange") kombinatorische Netze an den clock-enables der ersten 
Pipeline-Stufen. Und diese waren ja - zumindest von meiner Seite aus - 
Thema des Gesprächs.

von Schlumpf (Gast)


Lesenswert?

Wie wäre es, wenn du die gesamte Pipeline anhälst, wenn eine oder 
mehrere Stufen grad nicht hinterherkommen.
Dazu würde es doch reichen, wenn jede Stufe ein "Stop-Signal" auf ein OR 
mit n Eingängen gibt und der Ausgang dieses OR auf das Enable JEDER 
Pipeline-Stufe führt. Also eine "globale Reißleine". Damit sollte doch 
die Logiktiefe recht gering bleiben. Oder steh ich grad auf dem 
Schlauch?

von Michael S. (decimad)


Lesenswert?

Ja, das ist ja praktisch, was auch Fragender gesagt hat und praktisch 
mein Ansatz 1). Dieser Ansatz hat mich also von 350MHz runter auf 
maximal 290MHz gebracht, also das kombinatorische Stall-Signal (das auf 
den CEs liegt) ist komplexer als jede Pipeline-Stufe. Und darum fragte 
ich, ob es nicht Alternativen gibt, mit denen man es hinbekommt, dass 
ein Stall schaltungs- und geschwindigkeitstechnisch entschärft werden 
kann, wenn er den Rest der Schaltung ausbremst.

von Schlumpf (Gast)


Lesenswert?

Wenn der Stall-Ausgang jeder Pipelinestufe rein kombinatorisch aus dem 
Zustand der Stufe gebildet wird, dann hast du sicher recht.
Ist der Stall-Ausgang jeder Stufe aber ein Register, dann besteht deine 
"Bremse" doch eigentlich nur aus einem dicken OR und sollte meines 
Erachtens die Geschwindikeit nicht herabsetzen.

Wenn du das Stall-Signal kombinatorisch aus dem Zustand der 
Pipelinestufe bildest und dann noch einmal über ein Register führst, 
sollte also die Logiktiefe für das globale Stall recht schlank 
ausfallen.
Dabei verlierst du aber einen Takt.
Wenn du aber das Stall-Signal nicht aus dem Zustand der Pipelinestufe 
bildest, sondern anhand des aktuellen Zustandes der Stufe und den 
Eingängen erkennst, ob der nächste Zustand zu einem Stall führen wird, 
dann kommt dein Stall-Ausgang gleichzeitig, wie der Stall-Zustand in der 
Pipeline-Stufe eintritt UND du hast eine geringe Logiktiefe für das 
globale Stall-Signal..


Beispiel (Zustand 5 soll zu "stall" führen).

Wenn Zustand = 4 und Eingang = xy dann Zustand = 5
Wenn Zustand = 5 dann setze Stall_Register

--> das führt zu einem Takt Verzögerung am Stall

Wenn Zustand = 4 und Eingang = xy dann Zustand = 5
Wenn Zustand = 5 dann bilde kombinatorisch Stall_komb = 1

--> führt zu großer Logiktiefe

Wenn Zustand = 4 und Eingang = xy dann Zustand = 5 UND stall_Register = 
1

--> führt zu kleiner Logiktiefe und kein Takt wird "verschwendet"

Oder steh ich immer noch auf dem Schlauch? :-(

von Michael S. (decimad)


Lesenswert?

Moment mal, Du hast ja vollkommen Recht, oder? Warum ging ich denn bis 
eben so felsenfest davon aus, dass ich nichtmal lokal im stall'enden 
Knoten das Signal über einen Register in die Umwelt führen kann? O.O
Bleibt eigentlich nur der Nachteil, dass so "vom Ende bis zum Anfang der 
Pipeline" plus einige ORs innerhalb eines Taktes gehen muss und diese 
Zeit von der möglichen Berechnungzeit der ersten Stufe (von der ich 
jetzt ausgehe, dass sie auch örtlich am weitesten entfernt ist) abgeht.
Das könnte bei einem ausgesprochen großen Design bestimmt Auswirkungen 
haben? Irgendwie muss doch auch bei mir die sinkende Maximalfrequenz zu 
begründen sein. Hrmmm...
Auf jeden Fall keine Glanzstunde meines Hirns draufhau

von Christian R. (supachris)


Lesenswert?

Michael S. schrieb:
> Irgendwie muss doch auch bei mir die sinkende Maximalfrequenz zu
> begründen sein.

Ich denke das hat eher was mit der resultierenden etwas anderen 
Beschaltung des CLB mit benutztem CE zu tun. Ich glaube, da auch mal im 
Datenblatt was gesehen zu haben....

von Schlumpf (Gast)


Lesenswert?

Na ja, hau net so feste drauf, du brauchst es noch ;-)
Natürlich hast du recht, dass bei recht umfangreichen Pipelines die 
räumlich weit auseinanderliegen, die Laufzeit was ausmacht. Aber die 
Logiktiefe sollte recht gering sein.
Ich gehe mal davon aus, dass schon ein Unterschied bemerkbar sein 
müsste, ob du das Stall kombinatorisch aus dem erreichten Zustand 
bildest, oder ob du das Stall in einem Register ausgibst, welches eben 
zum Zeitpunkt des Erreichen des Stall-Zustandes gesetzt wird.
Die Logiktiefe deines Stall-Pfades umfasst so tatsächlich nur das OR. In 
dem anderen Fall kommen noch die Decoder hinzu, die den Zustand 
auscodieren, der den Stall erzeugt. Und die können u.U. recht 
umfangreich sein. Darin sehe ich auch die Reduktion der Maximalfrequenz 
bei einer rein kombinatorischen Verknüpfung des Stalls aus dem Zustand 
begründet.

Probier´s doch einfach mal aus. Sollte ja nicht sooo viel Umbauarbeit am 
Design sein, oder?

von Schlumpf (Gast)


Lesenswert?

Christian R. schrieb:
> Ich denke das hat eher was mit der resultierenden etwas anderen
> Beschaltung des CLB mit benutztem CE zu tun. Ich glaube, da auch mal im
> Datenblatt was gesehen zu haben....

Letztendlich wird die Synthese entscheiden, ob sie dann wirklich den 
EN-Eingang eines Registers verwendet, oder ob es schlauer ist, ein UND 
vor den Dateneingang des Registers zu schalten, was letztendlich logisch 
die gleiche Auswirkung hat.
Wie gesagt: Ich denke, da hilft nur noch "probieren".. Aber poste mal 
das Ergebnis, wenn du was hast, mich würde es auch interessieren..

von Schlumpf (Gast)


Lesenswert?

Ach ja, nochwas:
Gib der Synthese ein Constraint für die zu erreichende Frequenz vor und 
lass sie nicht einfach machen.
Ohne Vorgabe entscheidet sie sich nicht zwangsläufig immer für die 
schnellste Lösung, sondern eher für eine ausgewogene Lösung zwischen 
Speed und Area..

von Michael S. (decimad)


Lesenswert?

Oje, jetzt ist es schon wieder nach 1 :( Habe mich eben in der 
Spartan6-Doku festgelesen. :( Daher Ergebnisse frühestens morgen abend, 
wenn ich da nicht schon schlafe, grummel.
Vielen Dank auf jeden Fall euch beiden, hier vergeht kaum eine Minute, 
in der ich nichts lerne!

von Michael S. (decimad)


Angehängte Dateien:

Lesenswert?

Okay, jetzt ist mir wieder eingefallen, warum ich der Meinung war, dass 
ich busy nicht über ein Flipflop zurückführen kann. Anbei ein Bild 
meines Gedankenmodells. Sagen wir, t1 und t2 sind die Zeitpunkte von 
Takt 1 und Takt2. Das Busy-Flipflop schaltet zu Zeitpunkt t2 das 
Ergebnis der Busy-Berechnung der Eingangsdaten von t1. Zum Zeitpunkt 
t2+t_BusyDelay (Leitungsverzögerung) wird dann das Clock-Enable-Signal 
der Vorgängerstufe ankommen, oder anders ausgedrückt: Die Vorgängerstufe 
erfährt die Information nicht zum nächsten, sondern erst zum 
Übernächsten Takt, oder etwa nicht?

von Duke Scarring (Gast)


Lesenswert?

Michael S. schrieb:
> Die Vorgängerstufe
> erfährt die Information nicht zum nächsten, sondern erst zum
> Übernächsten Takt, oder etwa nicht?
Ja schon, aber Du kannst Deine resultierenden Daten in eine weitere 
FF-Stufe geben und mit einem 'valid'-Signal versehen. Dann passt es 
wieder.

Duke

von Schlumpf (Gast)


Lesenswert?

Zeichne es doch mal nicht als Blockdiagramm, sondern als Zeitdiagramm 
mit den Takten...

von Michael S. (decimad)


Lesenswert?

Hallo!

Okay, ich hatte mir das jetzt irgendwie so überlegt, dass wenn da schon 
prinzipbedingt FF's zwischen den Stufen sind, ich die halt auch gleich 
als den Zwischenspeicher für die beschäftigte Einheit nehmen kann, 
sodass ich dort nicht intern noch einen Puffer brauche. Dann darf aber 
natürlich die Vorgängereinheit keine neuen Daten produzieren... Mit 
Flipflops kann man ja nun nicht um sich schmeißen in einem FPGA und 
außerdem führt das ja alles zu mehr Latenz und in diesem Fall auch zu 
einer weiteren Steuerleitung mit Abfrage in jeder Einheit...
Zudem stelle ich mir das gerade schwierig vor, weil dann ja die erste 
Einheit trotzdem irgendwie noch ihren letzten Datensatz merken muss, 
damit sie den nochmal reingeben kann. Oder verstehe ich Dich da grade 
schlecht? Kannst Du da eine Art Minimalbeispiel angeben?

Viele Grüße,
Deci

von Schlumpf (Gast)


Lesenswert?

wie gesagt.. zeichne doch einfach mal einen Zeitrahl.
Oben den Takt, darunter die Zustände deiner Pipeline-Stufe und darunter 
dann das Stall-Signal..
Wenn du weisst, wie du es zeitlich gerne hättest, dann baust du es genau 
so zusammen..

von Fred Werkel (Gast)


Lesenswert?

Michael S. schrieb:
> Und zwar habe ich hier eine getaktete Pipeline, durch die Daten
> geschleust werden. Ich komme nun in die Situation, die Pipeline
> zeitweise anhalten zu müssen.

CE ist nicht die einzige Möglichkeit FF anzuhalten, man kann - 
Taktmultiplexer (BUFGMUX) vorausgesetzt - auch den Takt glitchfrei 
anhalten.

von Duke Scarring (Gast)


Lesenswert?

Michael S. schrieb:
> Mit
> Flipflops kann man ja nun nicht um sich schmeißen in einem FPGA und
> außerdem führt das ja alles zu mehr Latenz
Doch, kannst Du. Üblicherweise sind es nicht die FFs, die ein Projekt 
begrenzen, sonderen eher BRAM oder Multiplizierer.
Schon um das Routing zu entspannen, empfiehlt es sich bei jedem Modul an 
den Ein- und Ausgängen eine Registerstufe zu plazieren.

Du erhöhst zwar damit die Latenz bezogen auf die Taktzyklen, aber dafür 
kannst Du Dein Design auch schneller takten. Und ob z.B. ein Filter 925 
oder 1024 Takte Latenz hat ist oft unerheblich.

Duke

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.