Prieš savaitę ar dvi baigiau kurti antrą žaidimą, bet dėl didelio tingėjimo, vis neprisiruošiau jo čia aprašyti. Per tą laiką parašiau dar ir meniu, kuris apjungia du žaidimus. Apie tai galbūt parašysiu vėliau, o dabar pažiūrim klipą:
Žaidimas yra ganėtinai nuobodus. Čia dėl to, kad patingėjau padaryti pralaimėjimo funkciją :D Vienas iš doktorantų tai išgirdęs, pavadino mano žaidimą "kosmoso kimarintojai".. Ką padarysi :)
Techniškai, žaidimas yra "kietesnis" už Pong - naudojamos spalvos, patobulintas garsų generatorius, pridėtas NES valdiklių palaikymas, kodas logiškai išskirstytas po failus ir t.t.
Kaip visada, kodas yra patalpintas github'e: FPGalaxy. Šį kartą užtaginau 1.0 versiją, tad jei ateity ką nors pridirbčiau, tai neturės įtakos kitiems.
Pasirašiau kodą savo NES adapteriui, pratestavau - viskas lyg ir veikė, tačiau kai atėjo laikas prijungti interfeisą prie žaidimo kodo, susidūriau su problemomis. Erdvėlaivis, kuris turi judėti į šonus, kartais užstringa.
Pradžiai šiek tiek informacijos. Kaip minėjau, Nintendo pultai naudoja serijinę komunikaciją. Su šia dalim viskas tvarkoj - susirenku bitus į baitą ir pateikiu jį išėjime. Valdymo pultams pateikiu 800Hz taktinį dažnį, taigi mygtukų reikšmes gaunu šimtą kartų per sekundę.
Spartan-3E plokštė darbui naudoja 50MHz dažnį, todėl kiekvieno spustelėjimo metu erdvėlaivis pasislenka į šoną per maždaug 60k pikselių. Reikėjo būdo šį skaičių sumažinti. Tam panaudojau skaičiuoklį (counter):
position_next <= position + 1 when (nes1_right = '1' and move_counter = 0) else
position - 1 when (nes1_left = '1' and move_counter = 0) else
position;
Kodas tvarkingas, aplink esantis kodas irgi veikė, tačiau kartas nuo karto erdvėlaivio judėjimas sustodavo, o po trumpos pauzės vėl veikdavo. Teko šiek tiek palaužyt galvą, kol supratau kur bėda. Įtarimo patvirtinimui, prijungiau osciloskopą ir pamačiau štai ką:
Teks spręst šią problemą tvarkingai ir montuot kokį edge-detector.
Nuo pat pradžių, norėjau, kad projektas būtų ne vien VHDL rašymas. Realiausias variantas atrodė valdymo pulto gaminimas. Paskui bemąstydamas nusprendžiau, kad visai kietas variantas būtų paimti NES valdiklį ir parašyti jam interfeisą su VHDL. Labiau pasidomėjus, išaiškėjo, kad tiesiogiai valdiklių su kūrybine plokšte sujungti nepavyks. Seni Nintendo kontroleriai naudoja 4021 paralel-to-serial konverterius, o šis supranta tik 5V TTL logiką. Kur bėda? Spartan-3E plošktė naudoja 3.3V (LVTTL, LVCMOS). Taip ir gimė hardwarinė projekto dalis.
Būdų TTL ir CMOS logikų suderinimui yra n+1. Aš panaudojau 74 serijos logiką.
3.3V -> 5V: 74HCT4066 (Quad bilateral switches).
5V -> 3.3V: 74LCX125 (Low Voltage Quad Buffer with 5V Tolerant Inputs and Outputs).
Pabaigęs spausdintos plokštės dizainą, nunešiau jį univiero technikams, kad išmaltų. Ganėtinai įspūdingas CNC pas juos, buvo visai įdomu stebėt procesą. Po kokios valandos, mano plokštelės buvo baigtos ir atėjo laikas litavimui. Šiaip galvojau, kad nuo čia man jau reiks tvarkytis pačiam, bet klydau. Grįžus į laboratoriją, man parodė kaip naudotis lydmetalio pastos švirkštu. Reikėjo padengti visus paviršinių komponentų padus, ir galiausiai pabaigti darbą su karšo oro pompa. Toliau galima lituoti ir likusius komponentus.
Žemiau matosi visos stadijos, nuo dizaino iki baigtos plokštės. Dabar reiks prisėsti prie VHDL rašymo.
Štai praėjo pirmas mokslo metų mėnuo, galima pasigirti akademiniais pasiekimais. Kaip jau rašiau, šiemet darau projektą paremtą FPGA technologija. Per vasarą šiek tiek mokiausi VHDL kalbos, Spalio pradžioje pradėjau kurti žaidimą, o šiandien jau galiu parodyti rezultatus.
Viskas sukasi ant Xilinx Spartan 3E kūrybinės plokštės: prie VGA išėjimo jungiamas įprastas monitorius, valdymui naudojami 4 ant plokštės esantys mygtukai (valdymo pulto dar nedarau), garsas išgaunamas su piezo garsiakalbiuku (buzzer).
Kaip atrodo žaidimas matote aukščiau esančiame paveiksliuke, o žemiau galite peržiūrėti žemos kokybės video:
Kadangi iki projektui skirto laiko pabaigos dar liko kažkur 5 mėnesiai, bandysiu kurti antrą žaidimą, šįkart tai turbūt bus kosmoso šaudyklė (žr. Space Invaders, Galaxian, Galaga). Daugiau papasakosiu kai žinosiu kąnors konkrečiai :) Tuo tarpu, jei čia yra besidominčių programuojama logika, prašau peržiūrėti/išbandyti kodą.
Knyga, kurią naudoju VHDL mokymuisi yra paremta Spartan-3 plokšte. Ta plokštė yra senesnė ir turi keturis 7 segmentų indikatorius. Spartan-3E vietoj to turi 2x16 LCD ekraną. Kadangi nenorėjau praleisti pavyzdžių esančių knygoje, nutariau pasigaminti įskiepį savo ploštei.
Indikatorių turėjau nusipirkęs iš ebay, tai vienintelis dalykas, kurį reikėjo įsigyti - dvi "pin header" jungtys.
Žemiau matosi darbo eiga. Daug litavimo ir nemažai debuginimo, bet galų gale viskas veikia.