Aljaz.Ogrin - Predstavitev projekta: Načrtovanje DMX konzole v jeziku VHDL za implementacijo v FPGA Xilinx Spartan-II

6. Zgradba vezja in delovanje

Načrtovanje in sinteza vezja

Vezje je bilo najprej po komponentah zgrajeno in preizkušano kot shematika. Posamezne ločene komponente ali moduli so tudi sedaj ločeni. Ker je za moj okus program "Active HDL" nekoliko preveč neroden in tudi časovno omejitev ima, sem celoten projekt naredil v ISE (WebPack) proizvajalca Xilinx.

Opis elementov v VHDL jeziku je na precej nizkem programskem nivoju (logičnih gradnikov), ker je bil projekt prevajan v VHDL direktno iz shematike. Le zadnji komponenti (tipke_strani1 in tipke_IO_module) sta bili napisani direktno v VHDL jeziku, brez predhodnje shematike.

Za referenco pri analizi vezja prilagam tudi shematiko (.sch) s potrebnimi simboli (.sym).

Namen sem imel testirati vezje v jeziku VHDL, ker to omogoča (s stavki wait,… in internimi generatorji ure), vendar je bilo enostavno premalo časa za učenje vseh opcij in zvijač za dosego rezultatov.

Fizično testiranje vezja v realni aplikaciji se je veliko bolje obneslo kot testiranje v Active HDL orodju, zato je bila vsaka komponenta ločeno prevajana in implementirana v FPGA z mnogimi testnimi točkami. Delovanje je bilo preizkušano z logičnim analizatorjem.

Tudi končna verzija vezja ima nekaj testnih točk za lažje testiranje in razumevanje delovanja.

Vsi uporabljeni čipi so priključeni direktno na FPGA čip (pin to pin). Vhodni in izhodni signali vezja, ki so priključeni na čipe, nosijo isto ime kot pini čipov. Izjema sta le naslovna signala ADC-ja in analognega mux-a, ki sta v dokumentaciji označena kot A,B,C signali.
 
 

Delovanje vezja

 
Vhodna ura 40MHz:

Uporabljen je števec kot delilnik frekvence, ker je le-ta previsoka. Omejitve postavlja samo AD pretvornik, ki ima najvišjo frevenco ure 1MHz. Vezje se še najbolje obnaša pri priporočeni frekvenci okrog 600kHz. Brez te omejitve bi lahko vezje delovalo pri polni frekvenci 40MHz.

Ta oscilator je zelo nestabilen in ima zelo veliko temperaturno odvisnost. Zato sem moral v vezje dodati tudi stabilen vir urinega signala. Vendar je kljub velikim spremembam frekvence uporaben za časovno nekritične aplikacije, kar je v tem primeru prva polovica vezja.
 
 
 
ADC modul (AD konverter):

Poizkušal sem dobiti AD-pretvornik z sample&hold vezjem in 16 analognimi vhodi, vendar ga ni v slovenskih trgovinah. Zato sem uporabil (za nekatere) že legendarni ADC0808, ki sem ga slučajno imel na zalogi. Ima 8 analognih vhodov, zato sem na vhod 8 priključil analogni multiplexer 8/1 74HC4051. S tem sem dobil 15 analognih vhodov. Vezje sem naredil s podporo za 16 vhodov, če bom kdaj dobil pravi ADC, in priredil dizajn tako, da 16-ega kanala ne bere (ga preskoči).


Slika 3 - Naslovi ADC0808 in 74HC4051 analognih MUX-ov
>> Slika 3 – Naslovi ADC0808 in 74HC4051 analognih MUX-ov

Na vsak analogni vhod je priključen potenciometer, od Vcc na Gnd, tako kot referenčna uporovna veriga ADC-ja. S tem dobimo ratiometrično pretvorbo 0-5V. Izkazalo se je (posebej izrazito pri potenciometrih R > 20kOhm), da je notranja kapacitivnost analognega dela ADC-ja tako velika, da se nekaj napetosti iz prejšnjega kanala prenese na nasledni kanal po preklopu analognega multiplekserja. Nezaželen pojav je bil nekoliko manjši pri uporabi potenciometrov R = 1kOhm . Popolnoma pa je izginil pri vezavi kondenzatorja med signal in Gnd (ali Vcc), ker zunanji kondenzator v dovolj kratkem času izravna napetost na notranjih kapacitivnostih. Poleg tega kondenzator tudi eliminira skoraj ves šum, povzročen s potenciometrom ali od zunaj.

ADC-ju najprej nastavimo naslov kanala, sprožimo ALE in nato sprožimo konverzijo. Po končani konverziji (EOC = 1) se podatek shrani v latch (da je stabilizacijski čas podatkovnega signala v vezju čim krajši). Od tu se podatek vpiše v RAM. Za to sekvenco skrbi sekvencer A. Ker je uporabljen Dual port RAM, sta istočasno dovoljeni dve operaciji branja, ni pa dovoljeno istočasno pisanje v RAM. Zato je vpisan podatek samo takrat, ko je izhodni serijski del v stanju pošiljanja Sync signala in nekaj časa ne bere iz RAM-a.
 
 
 
Sekvencer A:

Ta skrbi za zaporedje dogodkov:

  • Vpis podatka iz Latch-a v RAM
  • Povečanje števca kanalov ADC-ja in lokacije v RAM-u
  • ADC-ju omogočiti branje številke kanala
  • Proženje pretvorbe A->D
  • Čakanje na naslednji Sync signal, ko RAM nekaj časa ne bo v uporabi.

  • Slika 4 - Sekvencer A
    >> Slika 4 – Sekvencer A



     
     
     
     
     
     
     
    RAM - port A:

    Spodnje naslovne linije RAM-a (3:0) so krmiljene s številko kanala ADC-ja, naslov na zgornjih linijah (8:4) pa določimo s tipkami preko modula "tipke_strani1". S tem dobimo t.i. "strani", od katerih je vsaka dolga 16 bytov oz. 16 kanalov. Zadnji kanal (16) na vseh straneh je prazen oz. nepriključen zaradi zgoraj (AD konverter) omenjenega problema.
     
     
     
    Izhodni – serijski del:

    Serijski DMX protokol določa točno hitrost podatkov (širina bita = 4us), zaradi česar je bilo potrebno dodati nov urin signal v vezje. Obstoječa ura (40MHz) je preveč temperaturno odvisna in se je ne da zdeliti na frekvenco 250kHz. Poizkušal sem z oscilatorjem z resonatorjem pri 500kHz in s TTL inverterji, vendar ni bil dovolj točen in stabilen. Oscilator z 74HCT4060 je bil mnogo bolj stabilen, vendar je bil problem s trimanjem frekvence (ki je bila 502 do 511 kHz). Zato sem kot idealno rešitev vzel že narejen 16MHz oscilator in frekvenco delil. Končna frekvenca je 250,00kHz in nima opazne temperaturne odvisnosti!

    Izhodni – serijski del vezja ima 4 glavne komponente: shift-register z generatorjem start/stop bitov, generator Sync signala, izhodno vozlišče in sekvencer B, ki koordinira dogajanje.
     

     
    Serijski vmesnik:

    9-bitni shift R register s paralelnim vhodom: Na vhodu serijskega vmesnika je signal "Load_start" ("L_start"), ki ob pozitivni fronti naloži podatek v shift register in nato omogoči premikanje podatka ("run" =1). 8-bitni podatek se vpiše v bite 8:1. Bit 0 je vedno nič. Ko podatek premikamo desno, dobimo ven najprej LSB bit, ki je 0, kar nam da Start bit. Nato sledi ostalih 8 bitov. Izpraznjeno mesto (MSB) v shift-registru se polni z vrednostjo 1. Ko je podatek poslan iz registra, še dvakrat naredimo premik (sedaj je register poln enic) in dobimo na izhodu dva stop bita (visok nivo). Ko je podatek premaknjen 11x (start bit + 8x data + 2x stop bit) se postopek zaključi ("run" = 0) in dobimo pomožni signal "Serial idle" = 1. Glej sliko 2 ("serial_idle" = "stop").
     

    Generator Sync signala:

    Sestavljajo ga: D-FF, dve logični funkciji in števec v vlogi štoparice. D-FF skrbi za oblikovanje vhodnega signala. Ko je sklop sprožen, se vhod ignorira dokler ni sklop resetiran. Ko se pojavi zahteva za generacijo sync signala ("break_mab_enable" = 1) števec začne z štetjem od 0, prva logična funkcija iz njegovih izhodov naredi Break signal in nato MAB signal, druga funkcija pa sporoči, kdaj je določen čas pretekel in resetira celotno vezje za generacijo Sync signala. Glej sliko 1.
     

    Izhodno vozlišče:

    Multiplexer 2/1 preklaplja med serijskim signalom (podatki) in Sync signalom, ko je le ta zahtevan.

    Dobrodošla opcija je invertiranje izhodnega DMX signala. Izhod iz vezja krmili diferencialni oddajnik (driver), ki napaja dve žili v DMX kablu: +Data in –Data. Če sta obe žili v kablu pomotoma zamenjani, problem rešimo z invertiranjem izhodnega signala. To funkcijo naredimo z enimi xor vrati.
     

    Sekvencer B:

    Ta koordinira celotno dogajanje od RAM-a do serijskega vmesnika.

    Zahtevano zaporedje dogodkov:

  • Branje podatka iz RAM-a
  • Poglej, če serijski vmesnik kaj dela ("Serial_idle"=0) -> čakanje; če je prost:
  • Vpis podatka v serijski vmesnik in zagon oddajanja
  • Povečanje števca kanalov (=lokacija v RAM-u), ki so oddajani.

  •  
     
    Vezje okrog RAM-a:

    Komparator kanalov sporoča, kdaj je bil oddan zadnji zahtevani kanal ("restart_channels" = 1). Takrat se zažene generator Sync signala. Med generacijo sync signala sekvencer zahteva nov podatek iz RAM-a, vendar je s signalom "break_mab_enable" vhod RAM-a RSTB na enici, kar nam da prebrani podatek = 0. Po končanem Sync signalu pošljemo že prebrani podatek (= 0) na serijski vmesnik in dobimo StartCode na DMX izhodu. Ta čas je RS (ali JK) FF blokiral resetiranje števca kanalov, sedaj ga resetira in začne se branje in pošiljanje prvega podatka iz RAM-a (kanal 1).

    Vhod RSTB na RAM-u je krmiljen tudi z zunanjim signalom "Blackout", s katerim simuliramo vrednosti 0 na vseh kanalih. S tem ugasnemo vse aparature, ki so priključene na DMX signal.
     
     
     
    Test-mode generator:

    Namenjen je predvsem razhroščevanju vezja. Če je ob vklopu ali start-up-u vezja signal "Blackout" = 1, preprečimo vpisovanje podatkov v RAM na portu A. S tem dobimo na izhodu podatke, ki so vpisani v RAM kot konfiguracija (atributi "INIT_00", "INIT_01",…). Trenutno so ti podatki: 1, 2, 3,… in s tem dobimo številsko identifikacijo kanala v DMX paketu podatkov. Glej sliko 1. Seveda mora biti korigiran tudi vhod RSTB na RAM-u, da ne dobimo vseh izhodov 0 (glej zgornji odstavek).

    Čim je signal "Blackout" = 0 za čas ene urine periode, se v D-FF vpiše vrednost 1 in funkcija Test-mode ni več dosegljiva do restarta vezja ali GSR=1.
     
     
     
    LCD display driver:

    Prvi del pretvori 8-bitni podatek v dve hex števili, jih pretvori v 7-segment kodo in doda pike ("dp"). Drugi del, ki je krmiljen z urinim signalom 20 – 60Hz, razseka in po potrebi invertira signale, da je LCD krmiljen z izmeničnimi signali nizke frekvence.

    Podatek, ki bo prikazan na LCD-ju, lahko izbiramo med kanali ADC-ja ali prikaz številke trenutno izbrane strani, ki se vpisuje v RAM.
     
     
     
    Tipke za izbiro strani:
    shema

    Za vsako tipko z vgrajeno LED je uporabljen le en IO pad. Z uporabo IOBUF (primitive) komponente in nekaj logike dosežemo branje tipke, če LED ni prižgana.


    Slika 5 - Logika za delo s tipko z vgrajeno LED
    >> Slika 5 – Logika za delo s tipko z vgrajeno LED

    Slika 6 - Priklop tipke z LED
    >>Slika 6 – Priklop tipke z LED

    Tabela 1 - Signali v vezju za tipko
    >> Tabela 1 – Signali v vezju za tipko
    P = pritisnjeno, S = sveti

    Ob priklopu tipke (slika 6) na vezje (slika 5) dobimo delovanje, kot opisano v tabeli 1. S priklopom 16 tipk preko IO vmesnika na sinhroni enkoder dobimo podatek o zaporedni številki tipke, ki je pritisnjena. Pritisk katerekoli tipke sproži sinhroni vpis v enkoder preko or-povezave in vmesnika za filtriranje vibracij kontaktov v tipki. Ta vmesnik mora imeti dovolj počasno uro, da "ne vidi" odskakovanja tipk, ura pa mora biti dovolj hitra, da prestreže že kratek pritisk na tipko. LED so krmiljene s siganlom iz sinhronega enkoderja (zgornji naslovi RAM-a) preko dekoderja. Vsaka tipka, ki je pritisnjena, ugasne prejšnjo LED, prižge pa se LED na tej tipki, ki je bila pritisnjena.
    Podatek o pritisnjeni tipki uporabimo kot zgornje bite naslova RAM-a za vpis podatkov (na portu A). S to povezavo nam vsaka tipka predstavlja eno stran v RAM-u. Žal s 16-imi tipkami pokrijemo le polovico RAM-a; za celega bi potrebovali 32 tipk. Lahko bi dodal eno tipko in z njo izbiral prvo ali drugo polovico RAM-a.
     
     


    >> Skica 1 - Pretvorba: tipka v naslov strani


    >> Skica 2 - Debouncer, proti odskakovanju kontaktov tipke, uporabljen na skici 1



     
     
     
     
     
     
     
    Kanalne, PWM krmiljene LED:

    Nad vsakim od 16-ih potenciometrov je tudi ena LED, ki s svojo svetilnostjo sporoča približno vrednost kanala. Vezje za eno LED je sestavljeno iz dekoderja naslova kanalov ADC-ja, latcha, ki prebere in si zapomni podatek (vrednost kanala) in komparatorja. Teh vezij je 16. Vsem je skupen 8-bitni števec, ki deluje kot štoparica in je povezan na vse komparatorje. Ko ima števec manjšo vrednost od vrednosti kanala, je LED prižgana, ko pa ima večjo vrednost, LED ugasne. LED prižgana od časa: števec = 0 do časa: števec = vrednost kanala. S tem je nastavljeno razmerje visok nivo / nizek nivo (duty-cycle) pri konstantni frekvenci. Če je vrednost kanala majhna, je tudi navidezna, povprečna svetilnost majhna. Frekvenca je izbrana okrog 300Hz. Če je f < 60 Hz, človeško oko zazna utripanje, če ja frekvenca previsoka, pride do izraza nepotrebno kapacitivno breme.