Architektura počítače
Počítač MB50 je definovaný v jazyce VHDL ve stejném adresáři na GitHubu, kde je také implementace CPU MB5016. Hlavní entita definující propojení všech komponent je mb50
v souboru mb50.vhd. Porty této entity jsou připojeny na fyzické I/O piny obvodu FPGA a z nich dále ke konektorům na vývojové desce.
Počítač MB50 je složen z několika komponent, které si dále podrobněji popíšeme. Blokové schéma počítače je na následujícím obrázku.
+=======+ interrupts || I/O || +-------------+|devices|| | +===+===+ | | memory mapped I/O | | | | +==+==+ | +========+ || || +===+====+ || || +=====+ || |+---------+| MEMCTL |+---------+| Memory |+--------+| VGA || || CPU || +===+====+ || || +=====+ || || | +========+ || || | +==+==+ | | | | +======+======+ | || CDI || | || (Serial) || +----------+| Control and || || Debugging || || Interface || +=============+
Schéma zapojení komponent počítače MB50
Úplně vlevo je CPU
MB5016. Tomu jsme se věnovali v předchozích článcích. Procesor je připojen k paměti prostřednictvím řadiče MEMCTL
. Řadič grafického výstupu VGA
čte z paměti obrazová data nezávisle na procesoru. Sestavu doplňují vstupně-výstupní zařízení komunikující s procesorem pomocí generování přerušení a řídicích registrů mapovaných do paměti. Poslední částí je ladicí rozhraní CDI
, prostřednictvím něhož se do počítače nahrávají a spouští programy.
Paměť
Jako paměť RAM se používají bloky statické paměti dostupné uvnitř FPGA o celkové velikosti 30 KiB. Příslušná entita ram
v souboru ram.vhd byla vygenerována pomocí průvodce ve vývojovém prostředí a pouze nastavuje konfigurační parametry paměti, jako jsou šířky adresové a datové sběrnice. Na desce je sice ještě 64 Mib dynamické RAM, ale s tou se pracuje podstatně složitěji než s interní pamětí a pro naše potřeby 30 KiB stačí, proto externí paměť nepoužíváme.
Interní paměť v FPGA funguje jednoduše. Při čtení procesor na adresovou sběrnici pošle adresu a o dva takty později z datové sběrnice přečte jeden bajt. Naopak při čtení procesor zapíše na adresovou sběrnici adresu, na datovou sběrnici zapisovaný bajt, nastaví signál zápisu do paměti a v následujícím taktu paměť hodnotu uloží. Paměť má druhé nezávislé rozhraní zahrnující adresovou a datovou sběrnici a řídicí signály. Přes něj čte z paměti řadič VGA obrazová data.
Paměť RAM zabírá prvních 30000 B adresového prostoru. V horní části adresového prostoru, nad oblastí paměti, jsou namapované řídicí registry systémových hodin a klávesnice. Počítač nemá paměť ROM. Po zapnutí je vždy nutné před spuštěním procesoru nejprve nahrát do paměti program přes ladicí rozhraní.
Procesor není k paměti připojen přímo, ale přes řadič paměti definovaný entitou memctl
v souboru memctl.vhd. Tento obvod má dvě základní funkce. Zaprvé, podle adresy se rozhoduje, zda se pracuje s pamětí nebo s mapovaným řídicím registrem. Zadruhé, přepíná mezi přístupem do paměti z procesoru nebo z ladicího rozhraní.
Periferní zařízení: VGA, klávesnice PS/2, systémové hodiny
Možnosti implementace periferních zařízení jsou dány tím, co poskytuje vývojová deska. Na ní jsou připravené konektory pro VGA a PS/2, proto v počítači MB50 použijeme tyto starší periferie. Sice by bylo teoreticky možné implementovat modernější rozhraní, např. HDMI, Display Port, nebo USB, protože na desce jsou kromě předpřipravených konektorů přímo vyvedené i datové piny FPGA. Vyžadovalo by to ale připojit další hardwarové komponenty, minimálně konektory a konvertory napěťových úrovní.
Řadič pro zobrazování na VGA monitoru jsme si připravili už ve druhém dílu tohoto seriálu. Je definován entitou vga
v souboru vga.vhd. Nebudeme zde zabíhat do detailů implementace, pouze si zopakujeme, že z pohledu softwaru zobrazování funguje v rastru 256×192 pixelů, kde každý pixel je reprezentován jedním bitem. Pro každý blok 8×8 pixelů je navíc v obrazové paměti jeden bajt definující atributy: barvu pozadí (používá se, když má pixel hodnotu 0), barvu popředí (pro pixely s hodnotou 1) a povolení blikání.
Pro každou barevnou složku RGB je rezervován jeden bit. Obrazová paměť je uložená v horní části paměti RAM, začíná od adresy 0×5a00. Na začátku obsahuje po řádcích uložené pole pixelů o velikosti 32×192 = 6144 B. Následuje pole atributů o velikosti 32×24 = 768 B. Poslední dva bajty definují barvu ohraničení obrazovky a periodu blikání. Celá obrazová paměť zabírá necelých 7 KiB.
Jako uživatelské vstupní zařízení se používá klávesnice PS/2. Také řadič PS/2 známe z druhého dílu jako entitu ps2
v souboru ps2.vhd. Softwarově je klávesnice přístupná přes řídicí registry namapované do paměti. Jeden registr obsahuje poslední přečtený bajt z klávesnice, což je většinou kód stisknuté nebo uvolněné klávesy (scan code). Druhý registr se používá pro posílání příkazů klávesnici, především pro ovládání LED indikátorů CapsLock, NumLock a ScrollLock. Poslední registr indikuje nová příchozí data nebo naopak možnost poslat klávesnici další bajt. Každá taková událost je navíc oznámena procesoru pomocí přerušení.
Posledním implementovaným zařízením jsou systémové hodiny, entita system_clock
v souboru system_clock.vhd. Jedná se o jednoduchý 16bitový čítač, který se spustí při zapnutí počítače. Inkrementuje se automaticky s frekvencí 100 Hz, tedy po 10 ms. Po přetečení hodnoty pokračuje znovu od nuly. Každá změna hodnoty vyvolá přerušení.
Kombinace čítače a přerušení má tu výhodu, že se neztratí žádné „tiky” hodin, i když software nestihne zpracovat přerušení dostatečně rychle. Například, když je přerušení zakázáno po dobu více než 10 ms, může se více signálů přerušení hodin obsloužit jediným voláním obslužné rutiny. Pro správné počítání času stačí obsloužit hodiny častěji, než je perioda čítače 655,36 s.
Řídicí a ladicí rozhraní
Pro nahrávání programů do počítače MB50, jejich spouštění a ladění, slouží řídicí a ladicí rozhraní (Control and Debugging Interface, CDI), implementované entitou cdi
v souboru cdi.vdh. S hostitelským počítačem, na němž běží debugger, je spojeno pomocí sériového portu RS-232. Implementaci sériového rozhraní, entitu uart
v souboru uart.vhd, jsme si představili v druhém dílu.Jako hostitelský systém lze použít libovolný linuxový počítač. Pokud na něm nemáme sériový port, nahradíme ho konvertorem USB na RS-232.
Nejdůležitější funkcí ladicího rozhraní je nahrání programu ve strojovém kódu do paměti a jeho spuštění. K tomu účelu má CDI přímý přístup do paměti, bez účasti CPU. Vykonávání programu se řídí signálem Run
. Ten je ovládán ladicím rozhraním a testuje se vždy, když je řadič procesoru v počátečním stavu (na začátku zpracování instrukce). Jestliže ladicí rozhraní nastaví Run
na logickou 1 po dobu jednoho taktu, provede procesor jednu instrukci a opět se zastaví. Pokud drží signál na hodnotě 1 pořád, běží CPU kontinuálně dál a provádí další instrukce.
Další funkce ladicího rozhraní používá debugger spuštěný na hostitelském počítači. Programátorovi dávají možnost číst a měnit obsah paměti a také všech registrů procesoru.
Zapojení celého počítače
Všechny komponenty počítače MB50 jsou pospojovány dohromady prostřednictvím entity mb50
v souboru mb50.vhd. Napojení portů této entity na piny pouzdra obvodu FPGA a tím ke konektorům na desce je definované v souboru mb50.qsf pomocí příkazů set_location_assignment
. Entita mb50
obsahuje instance entit pro jednotlivé komponenty a definuje propojovací signály mezi nimi. Kromě toho implementuje přepínání přístupu do paměti mezi procesorem a ladicím rozhraním. Zajišťuje také generování přerušení od klávesnice v procesu keyboard_irq
.
Obsah následujícího dílu
Konstrukci počítače MB50 máme dokončenou. Příště začneme s programováním. Nejprve si vyrobíme debugger a spustíme první program zapsaný v binárním strojovém kódu. Potom naprogramujeme assembler, abychom mohli psát software snadněji.
(Autorem obrázků je Martin Beran.)