Buffer VGA FPGA. Come leggere e scrivere?


8

Ho una scheda Altera DE2 e sto provando a disegnare sprite. Sto riscontrando problemi nell'implementazione di un buffer dello schermo.

Ho un'entità di visualizzazione che a una velocità di 25 MHZ genera pixel per la visualizzazione VGA.

Speravo di implementare un buffer in SDRAM. L'idea originale era quella di caricare i pixel del pixel successivo a una velocità di 25 MHZ dalla SDRAM. Funziona, ma non posso scrivere pixel su SDRAM a questo ritmo, né posso cancellare lo schermo abbastanza velocemente per ogni nuovo fotogramma. Mi servono 2 orologi per scrivere i dati e la mia scheda funziona a 50 MHZ, quindi ho abbastanza tempo per fare una lettura completa.

Suppongo che sto facendo qualcosa di terribilmente, terribilmente sbagliato. Come viene normalmente implementata una tale tela da disegno in VHDL?

La cosa più vicina che potrei trovare è usare una combinazione di colori 2-3-3 (RGB) per recuperare ogni pixel e scrivere sul ram della tela durante il tempo VGA "portico" (oscuramento). Ciò significa che in ciascuno degli orologi da 25mhz posso solo aggiornare il 15% dello schermo e in qualche modo ho bisogno del mio circuito per sapere quale 15% sta aggiornando?

Non riesco a capire come usare il doppio buffering perché non riesco a capire come scrivere i dati in memoria durante la lettura. C'è un modo per evitare il bit-bang del protocollo? Come fa questo ragazzo?

inserisci qui la descrizione dell'immagine



@davidcary, con alcuni dettagli su come affrontare il doppio buffering hai risposto alla domanda. Mi rendo conto che richiede tempo e non posso lanciare pietre come una che spesso fa una battuta rapida come commento per aiutare l'utente con il loro problema fino a quando qualcuno non può scrivere una risposta di alta qualità.
Kortuk,

3
Quando dici "Esiste un modo per evitare il bit-bang del protocollo?", Presumo che ciò significhi che non hai scritto tu stesso il controller SDRAM. Consiglio di farlo, è un buon esercizio e capirai di più su come funziona SDRAM e su come sfruttarne i tempi.
mng

Risposte:


3

Un paio di approcci che possono essere utili per alcuni stili di visualizzazione è quello di dividere il pannello di visualizzazione in riquadri e

  1. limitare ogni riquadro all'utilizzo di un piccolo set di colori, consentendo l'uso di meno di 8 bit per pixel, oppure
  2. utilizzare uno o due byte per ogni riquadro per selezionare una posizione da cui leggere i dati bitmap.
Il primo approccio potrebbe ridurre la velocità con cui i dati dovevano essere letti dalla memoria del display. Ad esempio, se uno utilizzava riquadri 16x16 e ciascuno di essi poteva avere quattro colori scelti tra un set di 256, quindi senza utilizzare RAM aggiuntiva nell'FPGA si poteva ridurre il numero di letture di memoria per 16 pixel a otto (quattro valori di colore, più quattro byte per la bitmap). Se si aggiungessero 160 byte di buffering / RAM (*) all'FPGA, si potrebbe ridurre il numero di letture di memoria per 16 pixel a quattro, usando 160 letture extra ogni 16 linee di scansione per leggere il prossimo set di colori delle tessere. Se si volessero 16 colori per riquadro, il secondo approccio richiederebbe 640 byte extra di RAM a meno che non si ponessero delle restrizioni sul numero di diverse tavolozze che potrebbero esistere su una linea.

Il secondo approccio probabilmente aumenterebbe anziché ridurre la larghezza di banda di memoria totale richiesta per produrre un display, ma ridurrebbe la quantità di memoria che dovrebbe essere aggiornata per cambiare il display - si potrebbe cambiare un byte o due per aggiornare un 8x8 o 16x16 area dello schermo. A seconda di ciò che si sta tentando di visualizzare, può essere utile quando si utilizza questo stile di approccio per utilizzare un dispositivo di memoria per contenere le forme delle tessere e un altro per contenere la selezione delle tessere. Ad esempio, si potrebbe usare una RAM 32Kx8 veloce per contenere un paio di mappe di tile 80x60 con due byte per tile. Se l'FPGA non avesse alcun buffering, dovrebbe leggere un byte ogni quattro pixel; anche con una RAM statica da 40 ns, ciò lascerebbe molto tempo alla CPU per aggiornare il display (un intero schermo sarebbe solo 9600 byte).

Per inciso, se uno non volesse aggiungere una RAM 32Kx8 ma potesse aggiungere 320 byte di buffering / RAM (**) all'FPGA, si potrebbe usare un approccio a tessera mappa ma avere la CPU o il DMA che alimentano 160 byte al visualizza ogni 8 righe di scansione. Ciò appesantirebbe leggermente il controller anche quando non cambiava nulla sul display, ma potrebbe semplificare i circuiti.

(*) Il buffer potrebbe essere implementato come RAM o come sequenza di 32 registri a scorrimento da 40 bit e più logica di controllo.

(**) Il buffer potrebbe essere implementato come due RAM da 160 byte o come due gruppi di sedici registri shift a 80 bit.


5

Gli sprite non vengono normalmente eseguiti con un frame buffer (come ho capito la parola). Invece si confrontano le coordinate xey con xmin, ymin e xmax, ymax dello sprite. Se la posizione di scansione corrente rientra nello sprite, emette il colore rilevante dalla memoria dello sprite.

Se stai cercando di visualizzare un frame buffer, prendi il cuore. Questo è stato il mio primo grande progetto FPGA. SDRAM non dovrebbe essere un problema a 100 MHz (l'ho fatto per la prima volta circa un decennio fa, e il silicio è ora più veloce), quindi moltiplica il tuo clock a 50 MHz. Scrivere il tuo controller sarà educativo :)

Questo ti dà molta larghezza di banda con cui giocare, puoi quindi raddoppiare il buffer, nessun problema. La VGA a 60Hz richiede una media di 18 MPixel / sec. Se si dispone di un dispositivo largo a 16 bit, si dispone di 200 MByte / sec di larghezza di banda di picco. Anche se riesci solo ad essere efficiente al 50% (il che dovrebbe essere fattibile) è 100Mpixels / sec @ 16 bit per pixel o 50Mpixels / sec @ 32 bit per pixel.

Ad esempio, è possibile che la RAM abbia bisogno di 60 ns per impostare una lettura, ma dopo può scoppiare 8 parole in 80 ns, ovvero 8 byte in ~ 140 ns. Se riesci a far scoppiare più a lungo la RAM, ciò contribuirebbe ad ammortizzare il costo di impostazione della lettura.

In base al tuo commento che si tratta di una RAM lato byte, che è un po 'più di 50 MByte / sec, solo 16 MPixel / sec @ 24 bit per pixel :( Non hai abbastanza larghezza di banda per fare un display truecolour, anche su VGA. potrebbe fare 8 bit per pixel abbastanza rapidamente, ma sono solo 2 o 3 bit per colore - il che potrebbe essere OK per la tua applicazione, non lo so. Oppure potresti fare una tabella di ricerca a 256 colori come ai vecchi tempi - dopo leggendo dal frame buffer si usa quindi il valore per cercare in un clock RAM interno per ottenere i 24 bit (o 18 bit, che si adatterebbero perfettamente in un BRAM) di colore per l'output sul monitor.

Il doppio buffering funziona ancora:

Visualizza un frame dall'indirizzo 0 (basta leggere a turno tutti i pixel, mettendo in pausa le letture durante gli intervalli di blanking).

Scrivi il tuo prossimo frame in un'altra posizione. Per questo doppio buffering, il controller DRAM dovrà stabilire le priorità tra le esigenze concorrenti dei canali di lettura e scrittura. Suggerimento, dai la priorità alle letture poiché sono critiche dal punto di vista temporale :)


È generalmente meglio dare la priorità alle letture o è meglio leggere i dati in un FIFO, dare priorità alle scritture quando una certa quantità di dati si trova nel FIFO e dare priorità alle letture quando il livello FIFO diventa troppo basso? Ho scoperto che almeno quando si guidano gli LCD che hanno un segnale di clock, è utile consentire che i tempi di lettura siano abbastanza "lenti", a condizione che tutti i dati vengano trasferiti in tempo.
supercat

Grazie per il tuo post, potrei dare un'occhiata al buffering. Ma penso che mi servano 2 clock (1/50 MHZ) per leggere i dati e ho anche un dispositivo a 8 bit.
Mikhail,

@supercat: sì, questa è una soluzione più avanzata che potrebbe essere necessaria se si sta spingendo la larghezza di banda.
Martin Thompson,

1
@Misha: ci vuole un po 'di tempo per impostare una lettura dei dati, ma puoi scoppiare a leggere grandi quantità contemporaneamente.
Martin Thompson,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.