.. _w07-io: ================================================= WykĹad 7: WejĹcie i wyjĹcie, popularne interfejsy ================================================= Data: 21.11.2018 .. toctree:: .. contents:: Bufory wejĹcia/wyjĹcia ====================== ZewnÄtrzne sygnaĹy nie sÄ podĹÄ czone bezpoĹrednio do wewnÄtrznej sieci poĹÄ czeĹ FPGA -- przechodzÄ najpierw przez bufory wejĹcia/wyjĹcia (IOB). Ich zadania to: 1. Zmiana interfejsu elektrycznego. FPGA pracuje wewnÄtrznie na ustalonym napiÄciu zasilajÄ cym (1.2V w przypadku Spartana 3E) i w technologii CMOS. Na zewnÄ trz natomiast moĹźemy wybraÄ jedno z wielu wspieranych napiÄÄ interfejsowych i standardĂłw elektrycznych. 2. Konwersja pojedynczych sygnaĹĂłw w sygnaĹy róşnicowe i z powrotem. 3. Rozdzielenie zewnÄtrznych sygnaĹĂłw dwukierunkowych na 3 sygnaĹy wewnÄtrzne (wejĹcie, wyjĹcie, wĹÄ czenie wyjĹcia). 4. Synchronizacja danych przychodzÄ cych i wychodzÄ cych do zegara. Bufory wejĹcia/wyjĹcia tworzone sÄ przez narzÄdzia syntezy automatycznie z portĂłw zewnÄtrznych na gĹĂłwnym module, ale moĹźemy teĹź zinstancjonowaÄ je rÄcznie:: module my_ram( input wire write_enable, input wire read_enable, inout wire data); reg storage = 0; wire data_in; // Rzadki przypadek celowej syntezy zatrzasku. always @(write_enable, data) begin if (write_enable) storage <= data_in; end `ifdef MANUAL // Wersja rÄczna: // Bufor wejĹcia/wyjĹcia: stan pinu data zawsze jest widoczny na data_in. // JeĹli T == 0, bufor nadaje na pinie data wartoĹÄ storage. JeĹli T == 1, // bufor wyjĹciowy jest wyĹÄ czony i nic nie nadaje. IOBUF my_buffer(.IO(data), .I(storage), .O(data_in), .T(!read_enable); `else // Wersja automatyczna (rĂłwnowaĹźna): assign data = read_enable ? storage : 1'bz; assign data_in = data; `endif endmodule Druty wiszÄ ce, pullup, pulldown ------------------------------- RozwaĹźmy sygnaĹ zewnÄtrzny, do ktĂłrego akurat nie jest podĹÄ czony Ĺźaden aktywny bufor wyjĹciowy (nazywany wiszÄ cym drutem (floating)). Jaki bÄdzie jego stan? ZaleĹźy to od technologii. W przypadku logiki TTL, stan takiego sygnaĹu ustabilizuje siÄ na 1. Jednak w przypadku logiki CMOS, stan takiego sygnaĹu jest nieustalony -- drut efektywnie stanie siÄ antenÄ zbierajÄ cÄ zakĹĂłcenia z okolicy i bÄdzie oscylowaĹ, czÄsto zmieniajÄ c stan i powodujÄ c zwiÄkszone zuĹźycie prÄ du na wszystkich podĹÄ czonych ukĹadach. Z tego powodu, wiszÄ cych drutĂłw naleĹźy unikaÄ. Z drugiej strony, w przypadku sygnaĹĂłw dwukierunkowych zawsze musi istnieÄ krĂłtki moment, w ktĂłrym Ĺźaden z ukĹadĂłw nie ma aktywnego wyjĹcia (w przeciwnym wypadku mielibyĹmy jeszcze wiÄksze problemy). RozwiÄ zaniem problemu jest doĹÄ czenie elementĂłw ciÄ gnÄ cych w dóŠ/ ciÄ gnÄ cych w gĂłrÄ (pulldown / pullup) -- sÄ to po prostu oporniki podĹÄ czone z drugiej strony do masy (pulldown) bÄ dĹş napiÄcia zasilajÄ cego (pullup), ustalajÄ ce stan sygnaĹu jeĹli nie ma Ĺźadnego aktywnego bufora wyjĹciowego (ktĂłry jest silniejszy od opornika). W ukĹadach FPGA moĹźemy wybraÄ jednÄ z 4 opcji dla kaĹźdego sygnaĹu zewnÄtrznego: - uĹźycie wbudowanego opornika pulldown - uĹźycie wbudowanego opornika pullup - uĹźycie ukĹadu keeper (pullup jeĹli aktualny stan to 1, pulldown jeĹli 0) -- efektywnie utrzymuje obecny stan na sygnale - brak wbudowanego opornika (uĹźywamy, jeĹli mamy zewnÄtrzny pullup/pulldown na pĹytce) Wyboru dokonujemy przez zinstancjonowanie odpowiedniego prymitywu w Verilogu (PULLDOWN, PULLUP, KEEPER) bÄ dĹş w pliku UCF. UkĹady FPGA majÄ duĹźo nóşek i prawdopodobnie nie uĹźyjemy wszystkich. NarzÄdzia syntezy automatycznie aktywujÄ na nich pulldown. SygnaĹy open-drain ------------------ Podstawowym problemem przy projektowaniu ukĹadu z sygnaĹami dwukierunkowymi jest ustalenie, ktĂłry ukĹad akurat ma prawo nadawaÄ (aby uniknÄ Ä sytuacji, gdy jeden ukĹad nadaje 0, a inny 1). DoĹÄ ciekawym i powszechnym rozwiÄ zaniem tego problemu jest uĹźycie sygnaĹĂłw open-drain (nazywanych teĹź open collector) -- wspĂłlnej linii komunikacyjnej z pullupem, na ktĂłrej ukĹadom wolno nadawaÄ tylko stan 0, bÄ dĹş nic nie nadawaÄ (i pozwoliÄ innemu ukĹadowi nadaÄ 0, bÄ dĹş pozwoliÄ pullupowi podciÄ gnÄ Ä stan do poziomu 1). Najprostszym przykĹadem uĹźycia takiej linii sÄ wspĂłĹdzielone linie przerwaĹ na szynie PCI -- urzÄ dzenie zgĹaszajÄ ce przerwanie wystawia 0, a natura linii open-drain efektywnie tworzy bramkÄ logicznÄ AND z wszystkich urzÄ dzeĹ. Bardziej skomplikowanymi przykĹadami uĹźycia open-drain sÄ szyna I2C bÄ dĹş interfejs klawiatury i myszy PS/2. Rodzaje interfejsĂłw =================== Interfejsy sprzÄtowe moĹźemy z grubsza podzieliÄ na nastÄpujÄ ce kategorie: - wolne (<~10 MHz) -- uĹźywamy byle jakiego zegara i przepuszczamy wszystkie wejĹcia przez synchronizator, cykl w tÄ czy w tamtÄ stronÄ nic nie zmienia. PrzykĹady: wolne SPI/JTAG, UART, I2C, PS/2, EPP, przyciski/diody. - Ĺrednie (<~200MHz) -- uĹźywamy zegara zsynchronizowanego z interfejsem. PrzykĹady: szybkie SPI/JTAG, VGA, PCI, ISA/ATA. - szybkie (<~1GHz) -- jak wyĹźej, ale uĹźywamy sygnaĹowania róşnicowego, ostroĹźnie dobieramy impedancjÄ poĹÄ czeĹ i terminatory, zapewniamy rĂłwnej dĹugoĹci ĹcieĹźki na pĹytce, wyrĂłwnujemy fazÄ zegara, itp. Nie ma juĹź nadziei na zrobienie szyny -- tylko ĹÄ cza P2P. PrzykĹady: interfejsy do pamiÄci DDR*. - bardzo szybkie (>~1GHz) -- nie ma juĹź nadziei na interfejs rĂłwnolegĹy, musimy uĹźyÄ interfejsu szeregowego i odtwarzaÄ zegar z sygnaĹu. Wymaga dedykowanych skomplikowanych blokĂłw nadawczych i odbiorczych (nie mamy takich w Spartanie 3E). PrzykĹady: PCI Express, SATA, TMDS (DVI/HDMI), DisplayPort. .. _vga: VGA, DVI, HDMI ============== Monitor (bÄ dĹş telewizor) CRT skĹada siÄ z: - ekranu, w ktĂłrym punkty ĹwiecÄ gdy zostanÄ trafione elektronem - dziaĹka elektronowego, ktĂłre strzela elektronami (a wĹaĹciwie trzech, dla kaĹźdego koloru) - magnesu odchylenia pionowego, sterujÄ cego dziaĹkiem w osi pionowej - *potÄĹźnego* magnesu odchylenia poziomego i *potÄĹźnego* transformatora do niego - ukĹadu sterujÄ cego powyĹźszym WyĹwietlanie obrazu rastrowego na monitorze CRT odbywa siÄ nastÄpujÄ co: - zaczynamy (arbitralnie -- proces jest cykliczny, a proces synchronizacji skomplikowany) od lewego gĂłrnego piksela obrazu - wyĹwietlamy pierwszÄ liniÄ obrazu, przesuwajÄ c dziaĹko od lewej do prawej krawÄdzi ekranu, modulujÄ c intensywnoĹÄ dziaĹka przez kolor piksela - wyĹÄ czamy dziaĹko i szybko przesuwamy dziaĹko z powrotem na lewÄ krawÄdĹş ekranu - wĹÄ czamy dziaĹko z powrotem i wyĹwietlamy kolejnÄ liniÄ - przez caĹy proces przesuwamy powoli dziaĹko w dóŠ- gdy dojdziemy do doĹu ekranu, wyĹÄ czamy dziaĹko i przesuwamy je w gĂłrÄ, zaczynajÄ c caĹy proces od poczÄ tku (trwa to o wiele dĹuĹźej niĹź powrĂłt do lewej krawÄdzi ekranu) PoniewaĹź monitory CRT sÄ starÄ i bardzo analogowÄ technologiÄ , ukĹad poziomy jest tak naprawdÄ niezaleĹźny od ukĹadu pionowego i oba dziaĹajÄ bez przerwy -- w trakcie powrotu dziaĹka na gĂłrÄ ekranu, ukĹad poziomy caĹy czas jeĹşdzi miÄdzy lewÄ a prawÄ krawÄdziÄ ekranu. Monitory CRT sterowane przez zĹÄ cze VGA majÄ nastÄpujÄ ce piny: - R, G, B -- analogowa wartoĹÄ aktualnie wyĹwietlanego piksela - HSYNC -- cyfrowy sygnaĹ powrotu do lewej krawÄdzi - VSYNC -- cyfrowy sygnaĹ powrotu do gĂłrnej krawÄdzi Na pĹytce Basys2 mamy bieda-konwerter cyfrowo-analogowy, z 3 bitami precyzji na kolory czerwony i zielony oraz 2 bitami pracyzji na kolor niebieski. Aby uzyskaÄ obraz na monitorze CRT przez VGA naleĹźy wykonaÄ nastÄpujÄ ce kroki: - wybraÄ jakÄ Ĺ rozdzielczoĹÄ i czÄstotliwoĹÄ odĹwieĹźania (http://martin.hinner.info/vga/timing.html, http://tinyvga.com/vga-timing) - uzyskaÄ skÄ dĹ (DCM) stosowny pixel clock - dla kaĹźdej wyĹwietlanej linii: - przez (active video) cykli wysyĹaÄ kolejne piksele obrazu, HSYNC=inactive - przez (front porch) cykli wysyĹaÄ czarny piksel, HSYNC=inactive (ten obszar jest "strefÄ buforowÄ ", ktĂłra moĹźe byÄ znieksztaĹcona przez monitor ze wzglÄdu na bliskoĹÄ sygnaĹu powrotu poziomego) - przez (sync pulse) cykli wysyĹaÄ czarny piksel, HSYNC=active (dziaĹko wraca na lewÄ stronÄ) - przez (back porch) cykli wysyĹaÄ czarny piksel, HSYNC=inactive (kolejna strefa buforowa) - dla kaĹźdej wyĹwietlanej ramki: - przez (active video) linii wysyĹaÄ kolejne linie obrazu, VSYNC=inactive - przez (front porch) linii wysyĹaÄ same czarne piksele, VSYNC=inactive - przez (sync pulse) linii wysyĹaÄ same czarne piksele, VSYNC=active - przez (back porch) linii wysyĹaÄ same czarne piksele, VSYNC=inactive - wyĹwietlaÄ ramki bez przerwy w pÄtli (trzeba poczekaÄ kilkadziesiÄ t ramek aĹź monitor siÄ zsynchronizuje) - pamiÄtaÄ, Ĺźe mapowanie wartoĹci active i inactive na 0 i 1 zaleĹźy od wybranego trybu (i moĹźe byÄ róşne dla HSYNC i VSYNC) Do tego, zĹÄ cze VGA ma interfejs I2C do EEPROMu wbudowanego w monitor, w ktĂłrym opisane sÄ moĹźliwoĹci monitora (tzw. EDID). Niestety, Basys 2 nie pozwala nam dostaÄ siÄ do tych sygnaĹĂłw. Aby uzyskaÄ obraz na monitorze LCD przez interfejs VGA, naleĹźy wspĂłlnie z nim udawaÄ, Ĺźe jest on monitorem CRT. DVI --- DVI jest zĹÄ czem zawierajÄ cym, oprĂłcz sygnaĹĂłw analogowych zgodnych z VGA, sygnaĹ cyfrowy. SygnaĹ cyfrowy uĹźywa 4 par róşnicowych (R, G, B, zegar), ma dokĹadnie 10Ă szybszy zegar niĹź pixel clock i przesyĹa dokĹadnie te same dane co sygnaĹ analogowy (z 8 bitami na kolor, zakodowanymi przez kodowanie 8b10, ze specjalnymi symbolami zastÄpujÄ cymi sygnaĹy HSYNC i VSYNC). HDMI ---- HDMI to cyfrowa czÄĹÄ DVI na (wstecznie zgodnych) sterydach -- m.in. wysyĹa audio w nieuĹźywanym obszarze danych w pionowym front/back porch. OgĂłlna struktura sygnaĹu wciÄ Ĺź jest taka sama jak VGA. Praktycznie kaĹźde zĹÄ cze DVI we wspĂłĹczesnych kartach graficznych jest tak naprawdÄ ĹşrĂłdĹem sygnaĹu HDMI. .. _ps2: PS/2 ==== Interfejs PS/2 opiera siÄ na dwĂłch sygnaĹach 5V open-drain: - DATA - CLK Zegar interfejsu nie jest dokĹadnie wyspecyfikowany, ale powinien byÄ w zakresie 10-16.7 kHz. Komunikacja na interfejsie PS/2 jest sterowana przez urzÄ dzenie wejĹciowe (mysz/klawiaturÄ). WysyĹanie poleceĹ do urzÄ dzenia jest moĹźliwe (np. polecenie zapal diody na klawiaturze), ale jest doĹÄ skomplikowane. JeĹli chcemy tylko odbieraÄ dane: - nie wysyĹamy nic na pinach CLK/DATA - dopĂłki CLK = 1, nic siÄ nie dzieje - gdy CLK = 0, urzÄ dzenie transmituje bit -- naleĹźy go zĹapaÄ w momencie zmiany z 1 na 0 - kaĹźdy bajt ma 11 bitĂłw: - bit startowy, rĂłwny 0 (jeĹli widzimy inny, zgubiliĹmy synchronizacjÄ) - 8 bitĂłw danych, od najniĹźszego - bit parzystoĹÄi (1 jeĹli parzysta liczba bitĂłw danych jest rĂłwna 1) - bit stopu, rĂłwny 1 Klawiatura wysyĹa powyĹźszym protokoĹem kody klawiszy (nie sÄ w ASCII -- sÄ to tzw. scan codes i naleĹźy uĹźyÄ tabelki https://wiki.osdev.org/PS/2_Keyboard#Scan_Code_Set_2). NiektĂłre z nich sÄ 2-bajtowe (w tym wypadku pierwszy bajt to ``0xe0``). Przy naciĹniÄciu klawisza wysyĹany jest jego kod, a przy puszczeniu klawisza wysyĹany jest jego kod poprzedzony bajtem ``0xf0``. Mysz wysyĹa powyĹźszym protokoĹem 3-bajtowe pakiety opisujÄ ce ruch myszy: - bajt 0: - bit 0: stan lewego przycisku - bit 1: stan prawego przycisku - bit 2: stan Ĺrodkowego przycisku - bit 3: zawsze rĂłwny 1 (jeĹli widzimy inny stan, zgubiliĹmy synchronizacjÄ pakietĂłw) - bit 4: bit 8 przesuniÄcia w osi X - bit 5: bit 8 przesuniÄcia w osi Y - bit 6: jeĹli 1, przesuniÄcie w osi X siÄ nie zmieĹciĹo w 9 bitach - bit 7: jeĹli 1, przesuniÄcie w osi Y siÄ nie zmieĹciĹo w 9 bitach - bajt 1: bity 0-7 przesuniÄcia w osi X - bajt 2: bity 0-7 przesuniÄcia w osi Y Klawiatura i mysz wysyĹajÄ rĂłwnieĹź kod statusu po uruchomieniu (po ktĂłrym moĹźna m.in. rozpoznaÄ, z ktĂłrym z nich mamy do czynienia). Niestety, nie zobaczymy go na naszej pĹytce (FPGA nie zdÄ Ĺźy siÄ skonfigurowaÄ zanim klawiatura/mysz wystartuje). Po peĹny opis interfejsu odsyĹam do: - https://web.archive.org/web/20050120021034/http://panda.cs.ndsu.nodak.edu:80/~achapwes/PICmicro/PS2/ps2.htm - https://web.archive.org/web/20041117095622/http://panda.cs.ndsu.nodak.edu:80/~achapwes/PICmicro/mouse/mouse.html - https://web.archive.org/web/20050120022433/http://panda.cs.ndsu.nodak.edu:80/~achapwes/PICmicro/keyboard/atkeyboard.html - https://www.digikey.com/eewiki/pages/viewpage.action?pageId=28278929 - https://wiki.osdev.org/PS/2_Keyboard - https://wiki.osdev.org/PS/2_Mouse .. _epp: EPP === EPP (enhanced parallel port) byĹ oryginalnie jednym z kilku trybĂłw, w ktĂłrych mĂłgĹ pracowaÄ stary port rĂłwnolegĹy komputerĂłw PC (zwany rĂłwnieĹź IEEE 1284, LPT, bÄ dĹş portem drukarki). Z jakiegoĹ powodu Digilent uznaĹ za stosowne uczyniÄ z niego interfejs uĹźywany na niektĂłrych pĹytkach do komunikacji miÄdzy komputerem a ukĹadem FPGA. Piny interfejsu sÄ nastÄpujÄ ce: - EppDB[7:0] -- dwukierunkowa szyna danych - EppAstb -- z komputera do FPGA, komputer ĹźÄ da przesyĹu adresu, gdy ten pin jest rĂłwny 0 - EppDstb -- z komputera do FPGA, komputer ĹźÄ da przesyĹu danych, gdy ten pin jest rĂłwny 0 - EppWR -- z komputera do FPGA, komputer pisza dane gdy rĂłwne 0, czyta gdy rĂłwne 1 - EppWait -- z FPGA do komputera, 1 oznacza zakoĹczenie przesyĹu ProtokóŠjest caĹkowicie sterowany przez komputer i dziaĹa nastÄpujÄ co: 1. DopĂłki Epp*stb sÄ rĂłwne 1, nic siÄ nie dzieje. FPGA powinna nie wysyĹaÄ nic na EppDB i wysyĹaÄ 0 na EppWait. 2. Gdy zauwaĹźymy 0 na EppAstb lub EppDstb, komputer ĹźÄ da transakcji. JeĹli transakcja jest zapisem, powinniĹmy zĹapaÄ dane (bÄ dĹş adres) z pinĂłw EppDB, a jeĹli jest odczytem, powinniĹmy wysĹaÄ dane (bÄ dĹş aktualny adres) na piny EppDB. 3. Gdy wykonamy zapis bÄ dĹş odczyt (i, w przypadku odczytu, zaczniemy wysyĹaÄ dane na EppDB), zaczynamy wysyĹaÄ 1 na linii EppWait. 4. Czekamy aĹź EppAstb/EppDstb wrĂłci do stanu 1. 5. JeĹli to byĹ odczyt, przestajemy wysyĹaÄ dane na EppDB. 6. Przywracamy EppWait do stanu 0. W standardowym uĹźyciu portu EPP, komputer zawsze zapisuje adres, a potem zapisuje bÄ dĹş odczytuje dane, pozwalajÄ c nam na realizacjÄ 256 8-bitowych rejestrĂłw danych. RS-232 ====== RS-232, zwany rĂłwnieĹź portem szeregowym lub UARTem, jest prostym interfejsem oryginalnie uĹźywanym do podĹÄ czania dalekopisĂłw do komputerĂłw, byÄ moĹźe za poĹrednictwem modemĂłw i linii telefonicznych. Ma nastÄpujÄ ce linie sygnaĹowe: - TxD (komputer do dalekopisu), RxD (dalekopis do komputera) -- dane szeregowe - RTS (komputer do dalekopisu), CTS (dalekopis do komputera) -- kontrola przepĹywu - DTR (komputer do dalekopisu), DSR (dalekopis do komputera) -- sygnaĹy gotowoĹci do pracy - DCD (modem do komputera) -- stan obecnoĹci sygnaĹu - RI (modem do komputera) -- przychodzÄ ce poĹÄ czenie telefoniczne Zazwyczaj uĹźywa siÄ tylko TxD i RxD. Standard RS-232 specyfikuje standard elektryczny nastÄpujÄ co: - 0: przesyĹane jako od +3V do +15V wzglÄdem masy - 1: przesyĹane jako od -3V do -15V wzglÄdem masy Jest to zbyt duĹźe napiÄcie, by podĹÄ czyÄ je do FPGA czy wiÄkszoĹci mikrokontrolerĂłw. Dlatego teĹź zawsze uĹźywa siÄ konwertera napiÄÄ (bÄ dĹş, w przypadku komunikacji w ramach jednej pĹytki, w ogĂłle uĹźywa siÄ tylko niskich napiÄÄ). Na liniach danych (TxD i RxD) komunikacja przebiega nastÄpujÄ co: 1. Nadawca i odbiorca muszÄ uĹźywaÄ tych samych parametrĂłw przesyĹu (standard nie przewiduje Ĺźadnej moĹźliwoĹci wykrycia ich). 2. Komunikacja jest symetryczna (TxD wyglÄ da tak samo jak RxD). 3. DopĂłki nic siÄ nie dzieje, linia jest w stanie 1. 4. Gdy ktĂłraĹ strona chce wysĹaÄ bajt: 1. WysyĹa przez jeden bit time stan 0 (bit startu). 2. WysyĹa bity danych (moĹźe ich byÄ od 5 do 9, zazwyczaj jest ich 8). 3. ByÄ moĹźe wysyĹa bit parzystoĹci. W zaleĹźnoĹci od konfiguracji, jest to zawsze bit 0, zawsze bit 1, XOR wszystkich bitĂłw danych (even parity), bÄ dĹş zanegowany XOR (odd parity). 4. WysyĹa 1, 1.5, bÄ dĹş 2 bity stopu (zawsze rĂłwne 1). 5. Utrzymuje stan 1 aĹź do momentu, gdy chce wysĹaÄ kolejny bajt. Komunikacja jest asynchroniczna -- odbiorca musi odtworzyÄ zegar przez zmierzenie, kiedy zaczÄ Ĺ siÄ bit startu i odliczanie odpowiedniego czasu do kolejnych bitĂłw.