Sommario:

Sistema di miglioramento dell'immagine Zynq: 7 passaggi
Sistema di miglioramento dell'immagine Zynq: 7 passaggi

Video: Sistema di miglioramento dell'immagine Zynq: 7 passaggi

Video: Sistema di miglioramento dell'immagine Zynq: 7 passaggi
Video: Multicore debug e trace su Xilinx Zynq UltraScale con TRACE32 e Ultra96 2024, Novembre
Anonim
Sistema di miglioramento dell'immagine Zynq
Sistema di miglioramento dell'immagine Zynq
Sistema di miglioramento dell'immagine Zynq
Sistema di miglioramento dell'immagine Zynq

Come probabilmente potresti capire dal titolo, lo scopo di questo progetto è realizzare un sistema di miglioramento delle immagini utilizzando ZYNQ ApSOC. Più specificamente, desideriamo costruire un sistema in grado di eliminare la nebbia da immagini o video. Questo sistema prenderà dati visivi in cattive condizioni come input, li elaborerà utilizzando tecniche di miglioramento dell'immagine e quindi produrrà il risultato.

Il progetto è stato realizzato e testato sulla scheda Digilent Zybo, ma dovrebbero funzionare anche altri dispositivi ZYNQ.

Divideremo questo progetto in 3 parti:

1) INGRESSO = Immagine in ingresso via Ethernet da computer/fotocamera

2) PROCESS = Elabora l'immagine

3) OUTPUT = emette l'immagine tramite un'interfaccia HDMI

In un modo molto controintuitivo inizieremo con la parte di output del progetto (questo ci darà migliori possibilità di debug lungo il percorso), continueremo con l'input e finiremo con la parte di elaborazione.

Passaggio 1: materiali

Materiali
Materiali

Per completare questo progetto avrai bisogno di:

HARDWARE

- qualsiasi scheda ZYNQ con HDMI ed Ethernet dovrebbe funzionare / Sto usando Digilent Zybo

- Cavo USB da USB A a micro B

- Cavo HDMI

- Cavo Ethernet

- Display con ingresso HDMI

SOFTWARE

- Xilinx Vivado

- Xilinx SDK

Passaggio 2: USCITA - Controller VGA Parte 1

USCITA - Controller VGA Parte 1
USCITA - Controller VGA Parte 1

Emetteremo i nostri dati visivi utilizzando la porta HDMI presente sulla scheda. La porta HDMI è collegata al lato PL (Programmable Logic = FPGA) di ZYNQ e dovremo progettare un controller in VHDL per questo. Se hai mai progettato un controller VGA, lo troverai molto simile. I tempi per HDMI e VGA sono in realtà gli stessi, infatti puoi costruire su un controller VGA esistente per ottenere un controller HDMI.

Per una migliore comprensione di ciò che sta realmente accadendo, progetteremo prima un controller VGA

Vogliamo visualizzare con una risoluzione di 1920x1080.

Il controller VGA è responsabile della trasmissione dei dati pixel (in formato RGB) in sequenza, pixel per pixel al display. Al di fuori dell'area di visualizzazione effettiva di 1920x1080 ci sono anche alcune aree "di confine", vale a dire: portico anteriore, portico posteriore e ritraccia. Le dimensioni in pixel di queste aree sono standard e specifiche per ogni risoluzione. Queste aree NON appaiono effettivamente sullo schermo ma sono obbligatorie e il colore dei pixel in quest'area deve essere nero. Una domanda valida sarebbe perché sono necessarie queste aree extra. Questa domanda sfida lo scopo di questo istruibile, ma se sei curioso ti incoraggio a fare ulteriori ricerche online.

Questo è un buon video che spiega l'interfaccia VGA

Nel nostro caso vogliamo visualizzare con una risoluzione di 1920*1080, e questi sono i tempi:

Area di visualizzazione orizzontale = 1920 pixel

Portico frontale orizzontale = 88 pixel

Portico posteriore orizzontale = 148 pixel

Ritraccia orizzontale =44 pixel

Area di visualizzazione verticale = 1080 pixel

Portico anteriore verticale = 4 pixel

Portico posteriore verticale = 36 pixel

Ritraccia verticale = 5 pixel

(Qui puoi trovare gli orari per altre risoluzioni

Quindi la nostra risoluzione effettiva sarà 2200 x 1125. Vogliamo 60 fps (fotogrammi al secondo) quindi il nostro pixel clock sarà 60*2200*1125 = 148,5 MHz. Sulla Zybo Board è previsto un clock a 125 Mhz. Useremo un IP MMCM per generare il Pixel Clock a 148,5 MHz di cui abbiamo bisogno.

Passaggio 3: USCITA - Controller VGA parte 2

USCITA - Controller VGA parte 2
USCITA - Controller VGA parte 2

Con lo sfondo teorico del passaggio precedente dovresti essere in grado di progettare il tuo controller VGA. Ti fornirò un progetto Vivado che lo faccia, ma ti consiglio di provare almeno a farcela da solo prima.

La maggior parte delle porte VGA non fornisce 8 bit per canale colore per pixel (vedi immagine sopra), quindi dovrai adattare il design al numero di pin per colore fornito dalla scheda (questo non è un problema per l'HDMI).

Il Design dipingerà l'intero schermo di blu, ad eccezione del pixel in alto a sinistra che sarà rosso. Va notato che questo progetto utilizza i vincoli per la ZYBO Board. Quindi, se vuoi eseguire questo progetto su un'altra scheda, dovresti aggiornare il file dei vincoli e adattare il numero di pin per colore.

Dai un'occhiata alla figura nr. 2. Ricorda che mentre il nostro controller VGA emette 5/6 bit per colore, questi bit vengono convertiti in un segnale analogico per ogni canale di colore (rosso, verde e blu) prima di passare attraverso il cavo.

Passaggio 4: USCITA - Controller HDMI Parte 1

OUTPUT - Controller HDMI Parte 1
OUTPUT - Controller HDMI Parte 1

Ora che sappiamo come funziona il controller VGA e abbiamo un design funzionante, possiamo continuare con il controller HDMI. Il controller HDMI utilizzerà effettivamente tutto il codice che abbiamo sviluppato nel controller VGA. HDMI e VGA utilizzano gli stessi tempi e gli stessi segnali. La differenza appare sui pin di uscita.

Mentre VGA utilizza un filo per ogni colore e trasmette un segnale analogico attraverso di esso, l'HDMI trasmette i dati digitalmente 1 bit alla volta per ciascun colore e utilizza la segnalazione differenziale. Segnalazione differenziale significa che per ogni bit l'HDMI ha 2 pin uno opposto all'altro. Quindi, se volessimo trasmettere un segnale '1', trasmetteremmo '1' su un filo e '1' negato sull'altro filo. Ciò garantisce l'integrità del segnale e puoi leggere di più al riguardo qui https://goo.gl/6CPCzB. Abbiamo uno di questi canali per ogni colore, ROSSO, VERDE e BLU e uno per l'orologio. A causa delle specifiche della segnalazione differenziale, i segnali che stiamo inviando tramite hdmi devono essere bilanciati DC, il che significa che il numero di 1 e 0 deve essere approssimativamente uguale in una certa finestra di tempo. Per fare ciò utilizzeremo la codifica 8b/10b. Puoi imparare molto su come funzionano la segnalazione differenziale e la codifica 8b/10b dalle specifiche DVI qui https://goo.gl/hhh8Ge (DVI e HDMI usano gli stessi segnali video).

Passaggio 5: OUTPUT - Controller HDMI Parte 2

OUTPUT - Controller HDMI Parte 2
OUTPUT - Controller HDMI Parte 2

Basta teoria, passiamo al nostro progetto. Mentre nel Controller VGA ce la siamo cavata con un clock di 148,5 MHz, qui dovremo fornire 10 volte quella frequenza perché vogliamo trasmettere 8 bit per ogni colore e utilizzando la codifica 8b/10b che si traduce in 10 bit per pixel e 10 *148,5 MHz = 1485 MHz. Questa è un'enorme frequenza che non può essere ottenuta sulla Zybo Board. Fortunatamente abbiamo qualche asso nella manica. Possiamo gestire 5*148,5 MHz = 742,5 MHz e utilizzeremo un IP OSERDES (serializzatore) per trasmettere i dati sia sul fronte di salita che di discesa del clock a 742,5 Mhz, quindi otterremo effettivamente i dati trasmessi a 1485 MHz. Vivado ci darà alcuni avvisi di temporizzazione e potresti sempre optare per una risoluzione più bassa con un clock più piccolo, ma dal momento che funziona, per ora non ci importa molto (gli avvisi sono legati al fatto che i buffer di clock non supporta frequenze superiori a 464MHz).

Quindi quello che dobbiamo fare è codificare i dati dall'uscita del nostro controller VGA in formato 8b/10b e quindi serializzarli come menzionato sopra. Sarà inoltre necessario aggiungere un altro MMCM al progetto per generare il clock a 742,5 MHz per la serializzazione.

Ho allegato sotto i file vhdl per l'encoder e il serializzatore. È necessario prima codificare i canali RGB e poi serializzarli.

Esempio per il canale rosso:

TMDS_encoder_RED: TMDS_encoder

mappa delle porte (clk148, red_channel_8bits, c_red, video_on, encoded_red_10bits);

Serialiser_RED: Serialiser10_1

mappa delle porte (clk148, clk742, encoded_red_10bits, reset, red_serial_1bit);

L'input "c" al codificatore TMDS è "00" per rosso e verde e "vsync e hsync" per blu (questo fa parte della specifica DVI

Passaggio 6: visualizzazione di immagini dalla RAM

Visualizzazione di immagini dalla RAM
Visualizzazione di immagini dalla RAM

Lo scopo del controller HDMI è visualizzare le immagini elaborate. Ora, con il controller implementato e pronto all'uso, dovremmo pensare di alimentare questo controller con i dati. Dato che gran parte del processo di miglioramento dell'immagine avrà luogo nel PS (Sistema di elaborazione = Processore ARM) e le immagini risultanti risiederanno nella RAM DDR. Quindi abbiamo bisogno di un modo per trasferire i dati dalla RAM al controller HDMI.

Per fare ciò avrai bisogno di 3 IP:

1) VDMA (accesso diretto alla memoria video)

2) VTC (controllore di temporizzazione video)

3) Stream to Video Out (d'ora in poi lo chiameremo S2VO)

S2VO fornirà effettivamente un segnale RGB 24BIT all'uscita e i segnali HSYNC e VSYNC necessari. Quindi possiamo lasciare fuori quella parte del controller HDMI.

Dovresti aggiungere questi IP al tuo progetto, configurarli ed effettuare le connessioni appropriate.

Alla fine dovresti ottenere qualcosa che assomigli allo schema sopra.

Passaggio 7: OUTPUT - FINE SDK

USCITA - FINE SDK
USCITA - FINE SDK

Con tutto l'hardware configurato e pronto per l'uso, ora dobbiamo creare il software nella PS. Esporteremo l'hardware e il flusso di bit e lanceremo l'SDK.

1) File -> Esporta -> Esporta hardware -> Seleziona Includi Bitstream e premi OK

2) File -> Avvia SDK

Nell'SDK creare un nuovo progetto di applicazione.

3) File -> Nuovo -> Progetto applicazione

4) Scegli un nome per il tuo progetto e premi Avanti

5) Seleziona il modello "Hello World" e premi Fine

L'applicazione nell'SDK dovrà programmare il VDMA. Ci sono alcune funzioni standard utilizzate per realizzare ciò (entrerò nei dettagli quando avrò tempo).

Per testare il nostro design utilizzeremo la funzione SDK Restore (Xilinx Tools -> Dump/Restore) per inserire un'immagine nella memoria RAM DDR e visualizzarla utilizzando il nostro controller HDMI. Puoi caricare l'immagine dove vuoi (tranne alcune piccole aree ristrette all'inizio della memoria). Per il nostro esempio abbiamo scelto l'indirizzo 16777216 e la dimensione del file 8294400 = 1920*1080*4 (4 canali = RGB + alfa).

Funziona !

Continua

Consigliato: