61 / 63 · Konzept
Stoppbare Pipeline und Backpressure
Stufen-ready berechnen, um bei Stopps und gleichzeitigem Vorrücken Verluste, Duplikate und Neuberechnung zu vermeiden.
Lektionen sind frei lesbar. Schreibe dich ein, um deinen Fortschritt zu speichern.
Wenn der Empfänger nicht jeden Zyklus bereit ist
Voraussetzungen: Ready/valid-EinplatzpufferHandshake Transfervertrag: valid des Senders und ready des Empfängers sind an derselben Flanke 1. Dazu gehören Regeln zum Halten wartender Daten. Mehr erfahren und Pipeline-AusrichtungPipeline Teilt Berechnungen durch Register in Stufen und verarbeitet mehrere Eingaben überlappend. Daten, valid und Steuersignale müssen stufengerecht ausgerichtet sein. Mehr erfahren.
Nur out_ready an eine feste Pipeline anzufügen genügt nicht. Stoppt die volle letzte Stufe, dürfen vordere Stufen ihre Daten nicht überschreiben. BackpressureBackpressure Der Empfänger meldet fehlende Annahmebereitschaft und stoppt so den Datenfluss. Noch nicht übertragene Daten müssen dabei erhalten bleiben. Mehr erfahren muss den Stopp zum Eingang weitergeben.
Jede der zwei Stufen speichert ein Datum und ein valid-Bit. Stufe 2 kann annehmen, wenn sie leer ist oder ausgeben darf; für Stufe 1 gilt dieselbe Regel.
in_ready ist r1. Selbst bei r2=0 kann eine leere erste Stufe einen Eingang annehmen. Das nutzt Platz besser als pauschales Ablehnen aller Eingänge bei gestoppter Ausgabe.
Jede Stufe aktualisiert nur mit Erlaubnis
Für unsignedUnsigned Interpretation einer Bitfolge als nichtnegative Ganzzahl. Der n-Bit-Bereich ist 0 bis 2^n−1 und kann sich von der signed-Interpretation derselben Bits unterscheiden. Mehr erfahren 8-Bit-x berechnet das Beispiel y=2(x+1). Stufe 1 speichert x+1 in neun Bit, Stufe 2 verschiebt in zehn Bit um eins. Selbst x=255 ergibt exakt 512.
module stallable_pipeline (
input logic clk, rst,
input logic in_valid,
output logic in_ready,
input logic [7:0] in_data,
output logic out_valid,
input logic out_ready,
output logic [9:0] out_data
);
logic v1, v2, r1, r2;
logic [8:0] d1;
logic [9:0] d2;
assign r2 = !v2 || out_ready;
assign r1 = !v1 || r2;
assign in_ready = r1;
assign out_valid = v2;
assign out_data = d2;
always_ff @(posedge clk) begin
if (rst) begin
v1 <= 1'b0;
v2 <= 1'b0;
end else begin
if (r2) begin
v2 <= v1;
if (v1) d2 <= {d1, 1'b0};
end
if (r1) begin
v1 <= in_valid;
if (in_valid) d1 <= {1'b0, in_data} + 9'd1;
end
end
end
endmoduleWegen nonblockingNonblocking Sequenzielle RTL-Zuweisung mit <=. Nach Auswertung der rechten Seite wird die Aktualisierung geplant, sodass Register derselben Flanke den alten Zustand verwenden. Mehr erfahren erhält Stufe 2 das alte d1, nicht das gerade neu berechnete. r1=0 hält v1, d1; r2=0 hält v2, d2. Nur valid festzuhalten und Daten weiter zu ändern wäre falsch.
Zwei volle Stufen verfolgen
Anfangs enthält v2 das Ergebnis A, v1 den Zwischenwert B und C wartet am Eingang.
| out_ready | in_ready | Flankenaktion |
|---|---|---|
| 0 | 0 | A, B halten; C nicht annehmen |
| 0 | 0 | A, B halten; C nicht annehmen |
| 1 | 1 | A ausgeben, B nach Stufe 2, C annehmen |
Der Sender hält C und in_valid bis zur Annahme. Wer nach der ersten Stoppflanke irrtümlich zum nächsten Wert wechselt, verliert C.
Spalten zeigen Werte vor der steigenden FlankeSteigende Flanke Übergang des Takts von 0 auf 1. Nicht zu verwechseln mit dem gesamten hohen Pegelintervall CLK=1. Mehr erfahren. Anfangs A hinten, B vorn, C wartend. E2 gibt A aus und nimmt C an; unmittelbar vor E3 steht B am Ausgang.
Wellenformdaten anzeigen
| Signal | Wellenform | Buswerte |
|---|---|---|
| edge | 2345 | E0 → E1 → E2 → E3 |
| out_ready | 0.1. | |
| out_valid | 1... | |
| out_data | 2..3 | A → B |
| in_valid | 1... | |
| in_ready | 0.1. | |
| in_data | 2..3 | C → D |
Erhaltung prüfen
Für seit Reset angenommene Eingänge Nin und übertragene Ausgänge Nout gilt folgende Belegung. An Resetflanken werden keine Übertragungen gezählt.
Korrekte Zählung könnte doppeltes A und verlorenes B übersehen. Prüfen Sie Werte und Reihenfolge mit einer Queue. Variieren Sie input valid und output ready unabhängig; schließen Sie lange Stopps, kontinuierliche Arbeit und Leeren durch Reset ein.
Auch ready ist ein Timing-Pfad
Viele Stufen verlängern den rückwärts gerichteten kombinatorischen Pfad r2→r1. Ein Register zur ready-Verzögerung kann zusätzlichen Speicher für bereits zugesagte Eingaben erfordern. Nur ein Flipflop in ready einzufügen, ohne Platz und Protokoll mitzudenken, ist keine sichere Timing-Optimierung.
Selbst ausprobieren
v1=0, v2=1, out_ready=0, in_valid=1: Kann angenommen werden? Können bei weiterhin out_ready=0 weitere Werte folgen?
Erklärung lesen
Zunächst r2=0, aber r1=1: Ein Wert füllt Stufe 1. Danach v1=v2=1 und r1=r2=0; weitere Annahmen sind unmöglich. Dies nutzt tatsächlich beide Speicherplätze.