Navrhujeme a vyrábíme vlastní CPU: architektura počítače MB50

24. 4. 2025
Doba čtení: 6 minut

Sdílet

Vývojová deska s FPGA
Autor: Martin Beran
Z předchozích dílů máme připravený procesor MB5016 ve formě VHDL entity. Nyní přidáme další potřebné komponenty (paměť, řadiče periferií a ladicí rozhraní) a postavíme celý počítač.

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, vpravo zapojené konektory VGA, RS-232 a PS/2

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.

prace_s_linuxem_tip

Schéma zapojení počítače MB50 

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.)

Neutrální ikona do widgetu na odběr článků ze seriálů

Zajímá vás toto téma? Chcete se o něm dozvědět víc?

Objednejte si upozornění na nově vydané články do vašeho mailu. Žádný článek vám tak neuteče.


Autor článku

Vystudoval informatiku na MFF UK v Praze, kde následně několik let učil programování v Unixu. Poté se dlouhá léta věnoval síťové bezpečnosti a programování firewallů. V současnosti se zabývá vývojem interních backendových systémů ve společnosti Gen (dříve Avast).