Altifigence Academy

56 / 63 · Concetto

File di registri con due letture, una scrittura e bypass

Implementare letture indipendenti e scrittura sincrona verificando bypass, inizializzazione e valid.

Memoria che legge due valori insieme

Per A+B servono entrambi gli operandi nello stesso ciclo. Un file di registriRegistro Memorizza uno stato di più bit. I registri sincroni del corso acquisiscono gli ingressi specificati al fronte di clock. Approfondisci 2-read/1-write offre due indirizzi di lettura e uno di scrittura. Qui memorizza otto parole da sedici bit e registra entrambe le letture al fronte: indirizzi a tre bit, capacità 8×16=128 bit. L'indirizzo 0 è normale memoria, non un registro costante.

Ogni lettura ha enable e valid propri. Una può fermarsi mentre l'altra legge; possono anche leggere lo stesso indirizzo. Leggere due indirizzi simultanei ha un costo diverso dall'aumentare la capacità. Strutture piccole possono usare array di flip-flopFlip-flop Acquisisce al fronte di clock specificato e mantiene fino al successivo. Gli ingressi devono rispettare setup e hold. Approfondisci e due reti di selezione; con RAM si può replicare la memoria distribuendo le stesse scritture. La sola dichiarazione RTL non determina la risorsa.

Se si legge proprio il valore scritto

Il contratto risponde con il nuovo dato quando lettura e scrittura coincidono per indirizzo e fronte. Un bypass porta wr_data direttamente all'ingresso del registro di lettura, senza attendere l'array. Per la porta ii:

Hi=wr_en∧(wr_addr=rd_addri)H_i=\mathrm{wr\_en}\land(\mathrm{wr\_addr}=\mathrm{rd\_addr}_i)

Con rd_eni=1\mathrm{rd\_en}_i=1, la risposta è:

Ri+={wr_data,Hi=1M−[rd_addri],Hi=0R_i^{+}=\begin{cases} \mathrm{wr\_data}, & H_i=1\\ M^{-}[\mathrm{rd\_addr}_i], & H_i=0 \end{cases}

M−M^{-} è il contenuto precedente. HiH_i va confrontato indipendentemente per ogni porta. Inviare wr_data a entrambe per una sola collisione corrompe l'altro operando. Omettere wr_en causa bypass errati anche senza scrittura, solo perché wr_addr coincide.

SystemVerilog
module regfile8x16_2r1w (
  input  logic        clk, rst, wr_en,
  input  logic [2:0]  wr_addr,
  input  logic [15:0] wr_data,
  input  logic        rd_en0, rd_en1,
  input  logic [2:0]  rd_addr0, rd_addr1,
  output logic [15:0] rd_data0, rd_data1,
  output logic        rd_valid0, rd_valid1
);
  timeunit 1ns;
  timeprecision 1ps;
  logic [15:0] mem [0:7];

  always_ff @(posedge clk) begin
    if (rst) begin
      rd_valid0 <= 1'b0;
      rd_valid1 <= 1'b0;
    end else begin
      rd_valid0 <= rd_en0;
      rd_valid1 <= rd_en1;
      if (wr_en)
        mem[wr_addr] <= wr_data;
      if (rd_en0)
        rd_data0 <= (wr_en && wr_addr == rd_addr0)
                  ? wr_data : mem[rd_addr0];
      if (rd_en1)
        rd_data1 <= (wr_en && wr_addr == rd_addr1)
                  ? wr_data : mem[rd_addr1];
    end
  end
endmodule

Il bypass cambia la selezione d'ingresso, non elimina lo stadio registrato. Indirizzo e richiesta precedono il fronte, mentre la risposta lo segue; il consumatore successivo può acquisirla al prossimo fronte. Passare a lettura combinatoria cambia percorso e contratto temporale, non è una semplice abbreviazione del codice.

Esempio: collisione su una sola porta

Si siano scritti M[2]=12, M[5]=7. Prima di E0: entrambi gli enable attivi, rd_addr0=2, rd_addr1=5, wr_en=1, wr_addr=2, wr_data=20. Dopo E0, porta 0 dà 20 via bypass, porta 1 il vecchio 7. La somma valida è 27, diversa da 19 di read-first senza bypass.

E1 legge 2 da entrambe e vi scrive 30: entrambe danno 30. E2 ha wr_en=0, wr_addr=2, wr_data=99 e legge 2: entrambe devono dare 30. Rivela il bypass basato sulla sola uguaglianza. A E3, rd_en0=0, rd_en1=1 danno valid0=0, valid1=1.

Ogni colonna registra un fronte di salitaFronte di salita Passaggio del clock da 0 a 1, distinto dall’intero intervallo di livello CLK=1. Approfondisci. Gli ingressi sono quelli immediatamente precedenti; gli stati indicati con «after» sono quelli subito dopo l’aggiornamento. Le colonne indicano l’ordine dei campioni, non il ritardo fisico di propagazioneRitardo di propagazione Tempo dalla variazione d’ingresso all’assestamento corretto dell’uscita. Equivalenza logica e proprietà temporali sono distinte. Approfondisci. Sono già scritti M[2]=12, M[5]=7, entrambi gli enable sono sempre 1 e l'indirizzo di scrittura è 2. Nell'ultima colonna wr_data=99 non deve passare, perché wr_en=0.

Anche con la stessa scrittura, i due port scelgono indipendentemente
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
edge234E0 → E1 → E2
wr_en1.0
wr_data23420 → 30 → 99
rd_addr02..2
rd_addr123.5 → 2
out0 after23.20 → 30
out1 after23.7 → 30

Che cosa inizializzare

Reset sincrono active-high blocca scritture e azzera entrambi i valid, senza cancellare array o dati d'uscita. Vecchi valori sul bus dopo reset sono corretti con valid=0. Se il sistema permette solo nuovi lavori dopo reset, deve definirne separatamente l'inizializzazione.

Leggere insieme alla prima scrittura restituisce un valore nuovo definito grazie al bypass. Un indirizzo mai inizializzato e letto senza scrittura resta invece indeterminato. rd_valid marca il tempo di risposta, non è un initialized per indirizzo. Il riferimento deve verificare che il contenuto sia noto prima di prevedere una lettura normale e trattare il bypass a parte.

Provate le quattro combinazioni degli enable, indirizzi uguali/diversi, collisioni con nessuna/porta 0/porta 1/entrambe, scritture consecutive e priorità reset. Più porte di scrittura sono fuori ambito: richiedono anzitutto una priorità per scritture simultanee allo stesso indirizzo. Cambiare il numero di porte modifica sia il contratto sia le risorse.

Prova tu

M[1]=4, M[4]=9. Entrambe le letture attive su 1 e 4 mentre si scrive 13 a 4: quali risposte? Poi wr_en=0, wr_addr=1, wr_data=99, entrambe le letture=1: quali? Infine spiegate valid e consumo disabilitando solo porta 0.

Leggi la spiegazione

Prima (4,13): solo porta 1 collide e riceve il bypass. Poi (4,4): wr_en=0 esclude 99. Infine rd_valid0=0, rd_valid1=1. Porta 0 mantiene i dati, che non vanno consumati come risposta. Anche indirizzo 0 si legge e scrive normalmente.

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