Arkanoid on Altera DE-1

771 views
632 views

Published on

This is a basic implementation of the famous game Arkanoid running on a FPGA that I've developed for the final project of Electronic II FPGA course at the University of Trieste.
The development board I've used is TERASIC DE1 with Cyclone II FPGA by Altera.

Features:
- 6 different angles of impact for the sphere.
- The ball striking a brick causes the brick to disappear.
- When all the bricks are gone, the player has won.
- Some bricks are indestructible.
- The Player has 3 lives to win the game.
- Start/Pause and restart game button.

For More Informations and for the english version look at this: http://www.vuolsavest.net/t3o/arkanoidFpga/

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
771
On SlideShare
0
From Embeds
0
Number of Embeds
11
Actions
Shares
0
Downloads
8
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Arkanoid on Altera DE-1

  1. 1. INTRODUZIONEArkanoid è un videogioco prodotto dalla software house giapponese Taito nel 1986. Esso è da considerarsi come il rifacimentodellarcade Breakout, di casa Atari, risalente agli anni settanta. Sebbene non sia il padre del suo genere, è considerato una pietramiliare dei videogiochi e negli anni ha ispirato innumerevoli cloni e giochi simili.Scopo del gioco originale è abbattere un certo numero di mattoncini colorati colpendoli con una sfera. Sul fondo dello schermosi trova lastronave "Vaus" che agisce da "base" con cui far rimbalzare la sfera contro i mattoncini; naturalmente bisogna evitareche la sfera cada nella porzione di schermo sottostante al "Vaus", pena la perdita di una vita.Per questa tesina si è realizzata una versione semplificata di Arkanoid che ne rispecchia tutte le funzionalità base:  La sfera rimbalza e distrugge i mattoncini;  Esiste il concetto di vita(ci sono 3 vite disponibili per poter tentare di distruggere il muro di mattoncini)e alcune di quelle avanzate:  Alcuni mattoncini sono indistruttibili;  È possibile variare l’angolo di rimbalzo della sfera imprimendole un effetto tramite il movimento della navicella;  È possibile colpire la sfera con i lati a 45 gradi della navicella facendole invertire il moto mantenendo l’angolo.Per lo sviluppo si è utilizzata la scheda terasic DE1 che monta FPGA Cyclone II di ALTERALa scheda DE1 mette a disposizione numerose features per sviluppare variegati progetti:  Altera Cyclone II 2C20 FPGA with 20000 LEs  Altera Serial Configuration deivices (EPCS4) for Cyclone II 2C20  USB Blaster built in on board for programming and user API controlling  JTAG Mode and AS Mode are supported  8Mbyte (1M x 4 x 16) SDRAM  4Mbyte Flash Memory  512Kbyte(256Kx16) SRAM  SD Card Socket  4 Push-button switches  10 DPDT switches  8 Green User LEDs  10 Red User LEDs  4 Seven-segment LED displays  50MHz oscillator ,24MHz oscillator ,27MHz oscillator and external clock sources
  2. 2.  24-bit CD-Quality Audio CODEC with line-in, line-out, and microphone-in jacks  VGA DAC (4-bit R-2R per channel) with VGA out connector  RS-232 Transceiver and 9-pin connector  PS/2 mouse/keyboard connector  Two 40-pin Expansion HeadersPer la realizzazione di Arkanoid si è scelto di utilizzare:  2 switch ”Push-Button” per comandare il movimento a destra e sinistra della barretta;  2 switch DPDT per controllare reset del gioco e Start/Pause;  I display a 7 segmenti per visualizzare le “vite” rimanenti;  L’uscita VGA per la visualizzazione a schermo.Inoltre, finita la fase di testing in cui la programmazione del FPGA Cyclone II è stata effettuata con metodologia JTAG, si è anchesfruttata la eeprom EPCS4 per salvare in maniera permanente il codice.Il software di sviluppo utilizzato è Quartus II fornito da Altera. Per la finalità didattica diquesto progetto è sufficiente la versione web scaricabile direttamente dal sito Altera.Tale software rende disponibili tool per realizzare tutte le fasi necessarie per il progetto:  Editor Grafico per gli schematici  Editor testuale per la creazione dei file in linguaggio VHDL  Interfaccia per programmare in modalità JTAG o AS
  3. 3. ARCHITETTURADIVISORE DI FREQUENZA:Ha il compito di dividere di un fattore due la frequenza di clock di 50 MHz fornita da uno degli oscillatori montati sulla BoardTERASIC DE1. Tale divisione è necessaria per ottenere la frequenza di 25 MHz richiesta per la modalità di funzionamento dellaVGA: 640x480 pixel a 25MHz.INTERFACCIA VGA:Come visto nell’introduzione la scheda TERASIC DE1 rende disponibile un’uscita VGA con connettore a 16pin. I segnali disincronizzazione vengono gestiti direttamente dallaFPGA Cyclone II ed è presente un convertitore digitale analogico (4bit DAC)per produrre i segnali analogici R G e B. Figura 1 - Circuito VGA scheda terasic DE1La risoluzione supportata è 640x480 a cui corrisponde un dot clock di 25MHz e un refresh di 60Hz, ossia vengono disegnati 60schermi al secondo. La visualizzazione dell’immagine su monitor avviene tramite righe. Una volta disegnata una riga ed atteso iltempo di latenza necessario(Front Porch) per passare da una riga all’altra, si passa a disegnare la successiva fino a che si èdisegnato tutto il monitor. A questo punto si ricomincia da capo. Figura 2 - Diagramma temporale del segnale di sincronismo orizzontale Figura 3 - Specifiche temporaliUn impulso attivo basso di durata a viene applicato al segnale di sincronismo orizzontale della porta VGA; tale periododetermina una riga di dati. L’ingresso RGB del monitor dev’essere pilotato a 0 Volt per un periodo di tempo chiamato back porchdopo l’arrivo dell’impulso hsync. Successivamente nel periodo c viene disegnato sull’uscita ogni singolo pixel relativo a quellalinea. Infine si attende ancora il tempo d, Front Porch, dove il segnale RGB è ancora una volta pilotato a 0 Volt in attesa delsuccessivo hsync. Il grafico della sincronia verticale è il medesimo solamente che l’arrivo del vsync significa la fine di un frame el’inizio del successivo.
  4. 4. IMPLEMENTAZIONE: LOGICA DI CONTROLLOLa maggior parte del progetto, sia per quanto riguarda la logica di funzionamento che per la visualizzazione su schermo, è statainserita in un unico file VHDL chiamato myArkanoid. Tale modulo si occupa della sincronizzazione VGA, della gestione degli inputswitch e dei display a 7 segmenti, del movimento e della resa grafica delle componenti del gioco.SINCRONIZZAZIONE VGA:Il segnale viene generato grazie ad un contatore h_cnt che viene incrementato ogni colpo di clock ( 25Mhz ). Il segnale h_syncviene pilotato in base al valore che assume h_cnt, per poter rispettare i tempi dello standard VGA 640x480.In particolare h_cnt varia da 0 a 799, un intervallo di valori corrispondente al periodo totale della linea, cioè 31,7 µs (a+b+c+d nelgrafico in Figura 3); il segnale h_sync si mantiene alto per h_cnt che varia tra 0 e 659, viene posto a 0 quando h_cnt assumevalori compresi tra 660 e 755, poi viene nuovamente settato a 1 fino a 799. A differenza del grafico precedentemente illustrato,questa routine inizializza il contatore a 0 nel momento dell’inizio del Display Interval, spostando Back Porch dopo il Front Porch.In questo modo il funzionamento del sincronismo non cambia, ma permette di leggere direttamente in h_cnt il valore dellacolonna attuale ( column). Figura 4 - Diagramma temporale del segnale di sincronismo orizzontale (nellimplementazione usata)In maniera analoga avviene per quanto riguarda la sincronia verticale, in particolare v_cnt varia da 0 a 524, un intervallo di valoricorrispondente al periodo totale della schermata, cioè 16.6 ms; il segnale v_sync si mantiene alto per v_cnt che varia tra 0 e 492,viene posto a 0 quando v_cnt assume i valori 493 e 494, poi viene nuovamente settato a 1 fino a 524.Esiste un ulteriore segnale interno, video_en ossia video enabled, il quale è attivo solo se h_cnt è minore di 640 e v_cnt è minoredi 480. Pertanto l’informazione sul colore del pixel viene ricopiata dall’ingresso all’uscita solo quando video_en è settato a uno,cioè solo se ci si trova all’interno dello schermo attivo.In appendice A il frammento di codice che realizza quanto visto.INPUT SWITCH:Per comandare il movimento della navicella sono stati utilizzati due dei quattro switch Push Button presenti sulla scheda. Taliswitch mantengono lo stato logico fino a che non vengono rilasciati e quindi sono ideali per realizzare quanto necessario.Altri due Toggle Switch sono stati invece utilizzati per il Reset del gioco e la Pausa.DECODER DISPLAY A 7 SEGMENTI:Per pilotare il display a 7 segmenti è stato realizzato un semplice decoder atto a creare una corrispondenza biunivoca trasimbolo visualizzato sul display e il numero intero corrispondente alle vite rimanenti. Il codice è molto semplice e si riassume conun banale statement case. In appendice A il frammento di codice che lo realizza.DIVISORE DI FREQUENZA:Il modo più semplice per realizzare un divisore di frequenza è quello di realizzare un contatore che fornisce un segnale in uscitasolamente per alcuni valori. In questo caso particolare è sufficiente un contatore a 1 bit: se il contatore conta ad ogni fronte disalita (o discesa) infatti, otteniamo già il clock a frequenza dimezzata. In appendice A il frammento di codice che lo realizza.
  5. 5. IMPLEMENTAZIONE: ELEMENTI GRAFICI E ANIMAZIONIOgni elemento grafico è stato realizzato andando ad accendere o meno i pixel che lo compongono in una determinata posizionedello schermo. Ad esempio per realizzare un mattoncino, è necessario fornirne gli estremi v_cnt e h_cnt:IF ((v_cnt >=195) AND (v_cnt <= 204) AND (h_cnt >= 61) AND (h_cnt <= 110)) THEN red3_signal <= 0; red2_signal <= 1; red1_signal <= 1; red0_signal <= 0; green3_signal <= 0; green2_signal <= 1; green1_signal <= 1; green0_signal <= 0; blue3_signal <= 0; blue2_signal <= 1; blue1_signal <= 1; blue0_signal <= 0;END IF;Per capire meglio il significato di v_cnt e h_cnt li si consideri come righe e colonne: se il pixel si trova tra le righe 195 e 204 e trale colonne 61 e 110, allora viene acceso secondo la colorazione fornita specificata(grigio scuro).Appare subito evidente come sia complicata la realizzazione di linee oblique o curve. Nel dettaglio le configurazioni per la resagrafica degli altri oggetti in scena.LA SFERA:Quanto visto in precedenza, come introduzione riguardo alla resa grafica del mattoncino, rappresenta la modalità di disegno diun oggetto statico. Nel gioco, la sfera deve muoversi nello schermo, rimbalzare sulle pareti, sugli ostacoli e sui mattoncini. Perrendere possibile il movimento, anziché disegnare la sfera tramitepunti fissi, si utilizzano delle variabili che vengono aggiornatecontinuamente in base ad un contatore che divide il clockaffinché il movimento avvenga ad una velocità umanamenteragionevole. In figura lo schema utilizzato per la resa della sfera:si notano le variabili ballPositionV e ballPositionH cherappresentano la posizione della sfera in ogni istante. La sfera hadue componenti di movimento: orizzontale ballMovementH everticale ballMovementV. Tali variabili assumono 3 valori: 0movimento negativo, verso l’alto nel caso del movimentoverticale e verso sinistra nel caso del movimento orizzontale; 1movimento positivo, verso il basso e verso destra; 2 situazione diSTOP, prima di partire o alla fine della partita. Tali variabiliservono per discriminare l’aumento o la diminuzione dei valori Figura 5 - Realizzazione grafica della sferacaratterizzanti la posizione della sfera negli istanti di cambiodirezione; infatti se ad esempio la sfera si muove dall’alto verso il basso il valore di ballPositionV aumenterà fino al momento incui la sfera stessa si scontra con un ostacolo: a tal punto il valore di ballPositionV diminuisce in modo analogo. Similmenteaccade per il movimento orizzontale. Per creare il movimento in diagonale, ad ogni refresh della posizione della pallina,dovranno variare contemporaneamente sia la componente di movimento orizzontale che quella verticale. In particolare perquanto riguarda il caso in questione si sono adottati diversi angoli di impatto in base all’effetto impresso alla sfera dalmovimento della navicella. È evidente che per variare l’angolo descritto dalla traiettoria della sfera, bisogna variare l’incrementodi una delle due componenti. Si è scelto di utilizzare la variabile angle che varia l’incremento per quanto riguarda la componenteverticale. Figura 6 - Componenti del movimento della sferaLa figura 7 mostra la variazione delle componenti del movimento della sfera nei vari casi presi in esame. Il valore anglesopraccitato varia quindi tra 1 e 3 a creare gli angoli di 45°, 60° e 72° circa in modulo. Una variazione di questo tipo comportainevitabilmente una variazione anche della velocità di movimento della sfera. Questo perché aumentando il numero di pixel chevengono saltati da una posizione all’altra, in un istante temporale la sfera si è muove di più. Tale caratteristica(divenuta poi talema nata come un errore) peraltro era presente anche nel videogioco originale. Un metodo semplice per sopperire a questo
  6. 6. errore è basato sulla variazione della velocità della sfera a seconda dell’angolo. Come accennato infatti la sfera varia la suaposizione a intervalli regolari cadenzati da un contatore che suddivide la frequenza di clock. Se si variasse dinamicamente ilvalore a cui si azzera il contatore, variabile ballSpeed nel sorgente, in base all’angolo di impatto della pallina, ne risulterebbe unavelocità adattata al movimento della sfera. Una prova in tal senso è stata fatta e rimane commentata all’interno del codice.Tuttavia si è notato che rallentando la frequenza di aggiornamento della sfera, il movimento della stessa risulta meno fluido e diconseguenza la resa finale è meno piacevole alla vista.Il codice che realizza quanto descritto è abbastanza complesso e si rimanda al sorgente completo per un’analisi più specifica.Volendo semplificarlo al massimo al caso di una sfera che rimbalza, sempre mantenendo il medesimo angolo e a velocitàcostante, a contatto con i bordi dello schermo, eccone il sorgente:IF(ballMovementV = 1) THEN IF (ballPositionV = 450) --Pallina Colpisce fondo schermo THEN ballMovementV:=0; ballPositionV:= ballPositionV-1; ELSE ballPositionV:= ballPositionV+1; END IF;END IF;IF(ballMovementV = 0) THEN IF (ballPositionV =30) --Pallina Colpisce bordo alto dello schermo THEN ballMovementV:=1; ballPositionV:= ballPositionV+1; ELSE ballPositionV:= ballPositionV-1; END IF;END IF;Analogamente per quanto riguarda il movimento orizzontale.LA NAVICELLA:Considerazioni simili a quelle del movimento della sfera, con la differenza che la navicella ha solamente la componenteorizzontale del movimento. Ecco come è stata realizzata la navicella: Figura 7 - Realizzazione grafica della navicellaCome accennato, in base al movimento della navicella all’istante dell’impatto con la sfera, a quest’ultima viene impresso uneffetto che ne varia la traiettoria. Inoltre i lati della navicella sono posti a 45 gradi e nel caso in cui la sfera impattasse questaparte di navicella, il movimento verrebbe completamente invertito facendole ripercorrere la stessa traiettoria al contrario. Lafigura 9 mostra alcuni degli angoli d’impatto. Figura 8 - Angoli dimpatto
  7. 7. BORDI E SCRITTE:Per rendere più piacevole la grafica del gioco, si sono creati dei bordi per delimitare la zona di movimento della sfera. Inoltre aldi sotto della navicella si è disegnata una grafica che ricorda uno specchio d’acqua ondulato.Sempre con la stessa finalità si è inserita l’intestazione che contiene l’autore, l’università, il corso per il quale è stata realizzataquesta tesina, il titolo del gioco e la scheda su cui si è lavorato. Per disegnare le lettere si è proceduto come visto in precedenza,ecco a titolo di esempio come è stata realizzata la “S” e il codice corrispondente: IF (((v_cnt = 300 OR v_cnt = 305 OR v_cnt = 310)) AND ((h_cnt >=Pause_s_Position+1) AND (h_cnt <= Pause_s_Position+3))) OR (((v_cnt >= 301 AND v_cnt<=304) OR v_cnt = 309) AND (h_cnt = Pause_s_Position)) OR (((v_cnt >= 306 AND v_cnt<=309) OR v_cnt = 301)AND(h_cnt = Pause_s_Position+4)) THEN red3_signal <= 0;red2_signal <= 0;red1_signal <= 0; red0_signal <= 0;green3_signal <= 1;green2_signal <= 0; green1_signal <= 0; green0_signal <= 0; blue3_signal <= 1; blue2_signal <= 0; blue1_signal <= 0; blue0_signal <= 0; END IF;SFUMATURE: 12Poiché sono disponibili 4bit per ogni colore, sono a disposizione 2 colori ossia 4096 colori. La gradazione di colore è datadall’insieme dei segnali red0, red1, red2, red3 ,green0, green1, green2, green3,blue0, blue1,blue2 e blue3. Ad esempio con lacombinazione: red3_signal <= 0; red2_signal <= 1; red1_signal <= 1; red0_signal <= 0; green3_signal <= 0; green2_signal <= 1; green1_signal <= 1; green0_signal <= 0; blue3_signal <= 1; blue2_signal <= 1; blue1_signal <= 1; blue0_signal <= 0;si ottiene una gradazione di azzurro.Sfruttando alcune delle variazioni di colore si sono creati diversi gradienti per simulare i riflessi nei bordi, nel mare sottostante,nella navicella e nella sfera.
  8. 8. SCHEMATICO FINALE E PIN ASSIGNMENT Figura 9 - schematico finaleEcco come appare il file di design dello schematico finale. Come già detto, per l’implementazione si è scelto di concentrare lamaggior parte della logica in un unico blocco, myArkanoidVHDL. Nella figura sono evidenziati anche i pin di destinazione nelFPGA.
  9. 9. PROGRAMMAZIONE DELLA BOARD: MODALITÀ ASUna volta terminato il progetto ed eseguite le fasi di compilazione, analisi e sintesi del circuito e pin assignment, si procede conla programmazione della scheda. Le modalità utilizzate sono state 2:  JTAG in fase di debug, comodo in quanto il bitstream (.sof) viene scaricato al volo nel FPGA e vi rimane fino allo spegnimento della board;  AS, Active Serial Programming: in questo caso il file del programma (.pof) viene scritto nella eeprom EPCS4 montata sulla board e risiede in memoria fino a quando questa non viene riscritta. In questo modo all’avvio della scheda verrà avviato automaticamente il codice presente sulla EPCS4. Lo schema a blocchi seguente mostra la fase di Programmazione, si noti lo switch RUN/PROG in posizione PROG, e la successiva fase di caricamento dalla EPCS4 all’FPGA: Figura 10 - Schema di configurazione Attiva SerialeSi tralascia la descrizione della modalità JTAG che è trattata in altri tutorial e ci si sofferma sulla programmazione attiva serialeche richiede anche alcune configurazioni preliminari: infatti il file .pof va preparato in base al tipo di eeprom montata sullascheda. In particolare la scheda DE1 monta una eeprom da 512Kbyte, EPCS4.Procediamo dunque con le impostazioni necessarie. Cliccando su AssignmentsDevice appare la seguente finestra:
  10. 10. Cliccando poi su Device and Pin Options e selezionando la tab Configurations appare:Come indicato in figura, selezionare Active Serial per quanto riguarda il Configuration Scheme e la eeprom EPCS4 come device.A questo punto ogni volta che il software compilerà e assemblerà il codice, verrà creato un file .pof di 512Kbyte compatibile conla EPCS4 e quindi non rimane che programmarla. Cliccando su ToolsProgrammer apparirà la seguente: 1. Selezionare la modalità Active Serial Programming. 2. Selezionare il device di destinazione, l’EPCS4 cliccando su Add Device. 3. Selezionare il file .pof sorgente cliccando su Add File.A questo punto si procede con la programmazione vera e propria cliccando su Start sempre nella finestra del programmatore. Èimportante assicurarsi che sia selezionato USB-Blaster come Hardware di Programmazione, in caso contrario va selezionatotramite l’apposito bottone Hardware setup. Inoltre, dato che stiamo programmando la EEPROM lo switch RUN/PROG va postonella posizione PROG. Al termine della programmazione, va spenta la scheda, rimesso lo switch RUN/PROG in posizione RUN eriaccesa la scheda che avvierà la configurazione appena scritta sulla EPCS4.
  11. 11. COMANDI DI GIOCOData la semplicità del gioco, i comandi necessari sono pochi:PUSH BUTTON SWITCH KEY0 : Muove la navicella verso destra;PUSH BUTTON SWITCH KEY1 : Muove la navicella verso sinistra;TOGGLE SWITCH SW1 : Mette in pausa il giocoTOGGLE SWITCH SW2 : Resetta il gioco. Figura 11 - Comandi di GiocoPer completare la distruzione del muro di mattoncini il giocatore ha a disposizione 3 vite che corrispondono a 3 navicelle.Quando una navicella viene distrutta, la sfera viene riposizionata nella posizione iniziale e dopo circa 2 secondi riparte condirezione casuale; in questo lasso di tempo la navicella non potrà muoversi. Figura 12 - Screenshot del gioco
  12. 12. APPENDICE A: PORZIONI SIGNIFICATIVE DI CODICE SORGENTESINCRONIZZAZIONE VGA: --Horizontal Sync --Reset Horizontal Counter IF (h_cnt = 799) THEN h_cnt <= "0000000000"; ELSE h_cnt <= h_cnt + 1; END IF; --Generate Horizontal Sync IF (h_cnt <= 755) AND (h_cnt >= 659) THEN h_sync <= 0; ELSE h_sync <= 1; END IF; --Vertical Sync --Reset Vertical Counter IF (v_cnt >= 524) AND (h_cnt >= 699) THEN v_cnt <= "0000000000"; ELSIF (h_cnt = 699) THEN v_cnt <= v_cnt + 1; END IF; --Generate Vertical Sync IF (v_cnt <= 494) AND (v_cnt >= 493) THEN v_sync <= 0; ELSE v_sync <= 1; END IF; --Generate Horizontal Data IF (h_cnt <= 639) THEN horizontal_en <= 1; --column <= h_cnt; ELSE horizontal_en <= 0; END IF; --Generate Vertical Data IF (v_cnt <= 479) THEN vertical_en <= 1; --row <= v_cnt; ELSE vertical_en <= 0; END IF;DECODER DISPLAY A 7 SEGMENTI: case vite is when 0 => leds1 <= "0111111"; when 1 => leds1 <="0000110”; when 2 => leds1 <= "1011011”; when 3 => leds1 <="1001111”; when others => NULL; end case;DIVISORE DI FREQUENZA: ENTITY dimezzaClock IS PORT (clock_f : IN STD_LOGIC; clock_f_mezzi : OUT STD_LOGIC); END dimezzaClock; ARCHITECTURE comportamento OF dimezzaClock IS SIGNAL conta : STD_LOGIC_VECTOR(0 DOWNTO 0); BEGIN PROCESS (clock_f) BEGIN IF clock_f = 0 AND clock_fevent THEN conta <= conta + 1; END IF; END PROCESS; clock_f_mezzi <= conta(0); END comportamento;
  13. 13. BIBLIOGRAFIASincronizzazione VGA: http://www.pyroelectro.com/tutorials/vhdl_vga/Arkanoid Game: http://en.wikipedia.org/wiki/ArkanoidTerasic DE1 Development Board Manuals: http://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&No=83Altera Web Site: http://www.altera.com/

×