Altifigence Academy

30 / 37 · Concetto

Ready/valid e buffer elastico da un posto

Progettare trasferimenti senza perdite o duplicazioni e ingressi/uscite simultanei con arresti.

Trasferimento: valid e ready allo stesso fronte

Il mittente alza valid con dati validi; il destinatario alza ready quando può accettare. Il trasferimento si decide campionandoli insieme al fronte.

transferk=validk∧readyk\mathrm{transfer}_k=\mathrm{valid}_k\land\mathrm{ready}_k

Con valid=1, ready=0 il mittente deve mantenere dati e valid. Attendere sempre ready prima di alzare valid può creare deadlock secondo le regole dell'altra parte. Qui tutti i segnali condividono il dominio di clock; 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. non risolve la CDC.

Trasmettere una sola volta i dati in attesa

Le colonne sono i cicli di campionamento 0–5, con valori appena prima del fronte di salitaFronte di salita Passaggio del clock da 0 a 1, distinto dall’intero intervallo di livello CLK=1. Approfondisci. A attende nei cicli 1 e 2 con valid=1, ready=0, mantenendo dati e valid. Al fronte 3 si accetta A, al 4 B. L'allineamento illustra il contratto, non i tempi setup/holdSetup Tempo minimo prima del fronte di acquisizione in cui i dati devono essere stabili. Una violazione rende non garantito il valore memorizzato. Approfondisci.

Ready/valid: attesa e trasferimenti consecutivi
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
clkp.....
valid01...0
ready10.1..
transfer0..1.0
datax3..4xA → B

Più cicli di valid=1 non significano un solo trasferimento: ogni fronte anche con ready=1 è un trasferimento distinto.

Costruire un buffer da un elemento

Se il buffer è vuoto o può consegnare l'elemento attuale a questo fronte, può riceverne uno nuovo.

in_ready=¬out_valid∨out_ready\mathrm{in\_ready}=\neg\mathrm{out\_valid}\lor\mathrm{out\_ready}
SystemVerilog
module elastic_buffer (
    input  logic       clk,
    input  logic       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 [7:0] out_data
);
    assign in_ready = !out_valid || out_ready;

    always_ff @(posedge clk) begin
        if (rst) begin
            out_valid <= 1'b0;
        end else if (in_ready) begin
            out_valid <= in_valid;
            if (in_valid) out_data <= in_data;
        end
    end
endmodule

Ricevendo a vuoto, out_valid e out_data cambiano dopo il fronte. Senza bypass combinatorio, il nuovo dato non conta già come uscita allo stesso fronte. Durante reset non si contano trasferimenti; con out_valid=0 il dato è privo di significato. Il registro datiRegistro Memorizza uno stato di più bit. I registri sincroni del corso acquisiscono gli ingressi specificati al fronte di clock. Approfondisci non deve quindi necessariamente essere resettatoReset Controllo che riporta allo stato iniziale specificato. Occorre definirne sincronicità e priorità rispetto agli altri controlli. Approfondisci.

Sostituire anche quando è pieno

Stato precedenteout_readyin_validAzione al fronte
Vuoto0 o 11Salva ingresso, valid=1
Pieno00 o 1Mantiene dati e valid
Pieno10Consegna e svuota
Pieno11Consegna il vecchio e salva il nuovo insieme

L'ultima riga permette un elemento per ciclo dopo il riempimento. Una latenza non dimezza automaticamente il throughputThroughput Numero di operazioni accettate o completate per unità di tempo. Una pipeline può aumentarlo senza ridurre la latenza del singolo lavoro. Approfondisci.

Modello per verificare l'ordine

Usate una queue lunga al massimo uno. Decidete uscita e accettazione dai valori precedenti al fronte. Confrontate prima l'uscita con la testa, poi accodate il nuovo ingresso. Dequeue ed enqueue possono coesistere: esplicitatene l'ordine nel modello.

0≤Naccepted−Ndelivered≤10\le N_{\mathrm{accepted}}-N_{\mathrm{delivered}}\le1

L'invariante vale nell'intervallo ricominciato dal reset. Verificate anche dati stabili nello stall, ordine preservato e assenza di duplicati. Il solo conteggio non prova i valori.

Lunghe catene ready combinatorie possono allungare il percorso inverso. Collegandole, controllate anche l'assenza di anelli combinatori.

Per approfondire: AMD UG934 — READY/VALID Handshake

Prova tu

Il buffer contiene A e B attende con in_valid=1. Prima out_ready=0, al fronte seguente 1. Cosa accade e fino a quando mantenere B?

Leggi la spiegazione

Prima in_ready=0: A resta, B non è accettato e il mittente mantiene B e valid. Poi in_ready=1: A viene consegnato e B salvato insieme. Dopo il fronte B è all’uscita ma non è ancora trasferito; servirà un fronte successivo con out_valid=out_ready=1.

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