30 / 37 · Concetto
Ready/valid e buffer elastico da un posto
Progettare trasferimenti senza perdite o duplicazioni e ingressi/uscite simultanei con arresti.
Le lezioni sono gratuite. Iscriviti per salvare i progressi.
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.
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.
Mostra i dati della forma d’onda
| Segnale | Forma d’onda | Valori del bus |
|---|---|---|
| clk | p..... | |
| valid | 01...0 | |
| ready | 10.1.. | |
| transfer | 0..1.0 | |
| data | x3..4x | A → 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.
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
endmoduleRicevendo 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 precedente | out_ready | in_valid | Azione al fronte |
|---|---|---|---|
| Vuoto | 0 o 1 | 1 | Salva ingresso, valid=1 |
| Pieno | 0 | 0 o 1 | Mantiene dati e valid |
| Pieno | 1 | 0 | Consegna e svuota |
| Pieno | 1 | 1 | Consegna 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.
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.