Altifigence Academy

61 / 63 · Concetto

Pipeline arrestabile e backpressure

Calcolare ready per stadio evitando perdite, duplicazioni e ricalcoli durante stop e avanzamenti simultanei.

Se il destinatario non può ricevere ogni ciclo

Prerequisiti: buffer ready/validHandshake Contratto che conferma il trasferimento quando valid del mittente e ready del destinatario valgono 1 allo stesso fronte. Include il mantenimento dei dati in attesa. Approfondisci da un posto e allineamento di pipelinePipeline Divide i calcoli in stadi separati da registri elaborando più ingressi sovrapposti. Dati, valid e controlli devono essere allineati per stadio. Approfondisci.

Aggiungere solo out_ready a una pipeline fissa non basta. Quando l'ultimo stadio pieno si ferma, quelli anteriori non devono sovrascrivere dati. La backpressureBackpressure Il destinatario segnala temporanea impossibilità di ricevere, fermando il flusso. I dati non consegnati devono restare conservati. Approfondisci deve propagare lo stop verso l'ingresso.

Ogni stadio conserva un dato e un valid. Il secondo accetta se è vuoto o può consegnare; il primo segue la stessa regola.

r2=¬v2∨out_ready,r1=¬v1∨r2r_2=\neg v_2\lor\mathrm{out\_ready},\qquad r_1=\neg v_1\lor r_2

in_ready è r1. Anche con r2=0, il primo stadio vuoto può ricevere un dato. Usa meglio lo spazio che rifiutare sempre ogni ingresso quando l'uscita è ferma.

Aggiornare ogni stadio solo quando autorizzato

L'esempio calcola y=2(x+1) per x unsignedUnsigned Interpretazione dei bit come intero non negativo. Il campo a n bit è 0–2^n−1 e può differire dalla lettura signed degli stessi bit. Approfondisci a otto bit. Lo stadio 1 conserva x+1 su nove bit, il secondo sposta di uno su dieci. Anche x=255 produce esattamente 512.

SystemVerilog
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
endmodule

Con nonblockingNonblocking Assegnazione RTL sequenziale con <=. Valuta il membro destro e pianifica l’aggiornamento, permettendo ai registri dello stesso fronte di usare lo stato precedente. Approfondisci, il secondo stadio riceve il vecchio d1, non quello appena calcolato. r1=0 mantiene v1, d1; r2=0 mantiene v2, d2. Fermare solo valid continuando ad aggiornare i dati è errato.

Seguire due stadi pieni

All'inizio v2 contiene il risultato A, v1 l'intermedio B e C attende all'ingresso.

out_readyin_readyAzione al fronte
00Mantiene A, B; C non accettato
00Mantiene A, B; C non accettato
11Consegna A, sposta B al secondo, accetta C

Il mittente mantiene C e in_valid fino all'accettazione. Passare al dato seguente credendo C inviato al primo fronte fermo perde C.

Le colonne sono valori prima del fronte di salitaFronte di salita Passaggio del clock da 0 a 1, distinto dall’intero intervallo di livello CLK=1. Approfondisci. A è in fondo, B davanti, C attende. E2 consegna A e accetta C; prima di E3 l'uscita è B.

Backpressure con entrambi gli stadi pieni
Mostra i dati della forma d’onda
Dati della forma d’onda: ogni carattere è un intervallo; il punto mantiene lo stato precedente; p è un ciclo di clock.
SegnaleForma d’ondaValori del bus
edge2345E0 → E1 → E2 → E3
out_ready0.1.
out_valid1...
out_data2..3A → B
in_valid1...
in_ready0.1.
in_data2..3C → D

Verificare la conservazione

Con Nin ingressi accettati e Nout uscite trasferite dopo reset, l'occupazione è la seguente. Non si contano trasferimenti sul fronte reset.

Nin−Nout=v1+v2,0≤Nin−Nout≤2N_{\mathrm{in}}-N_{\mathrm{out}}=v_1+v_2,\qquad 0\le N_{\mathrm{in}}-N_{\mathrm{out}}\le2

Il conteggio corretto può nascondere A duplicato e B perso: verificate valori e ordine con una queue. Variate valid e ready indipendentemente includendo stop lunghi, flusso continuo e svuotamento tramite reset.

Anche ready è un cammino temporale

Molti stadi allungano il percorso combinatorio inverso r2→r1. Registrare ready può richiedere spazio aggiuntivo per ingressi già promessi durante il ritardo. Inserire soltanto un flip-flop senza considerare memoria e protocollo non è un'ottimizzazione temporale sicura.

Prova tu

v1=0, v2=1, out_ready=0, in_valid=1: si può accettare? Con out_ready ancora 0 si possono ricevere altri dati?

Leggi la spiegazione

All’inizio r2=0 ma r1=1: un dato riempie il primo stadio. Poi v1=v2=1 e r1=r2=0: niente ulteriori accettazioni. Così si utilizzano entrambi i posti.

La scelta vale per questo browser. Puoi modificarla in qualsiasi momento dal piè di pagina.