FORTH a procesor J1

Martin Malý ·

Kapitola z knihy Data, čipy, procesory

Procesor J1 je zásobníkový mikroprocesor, který implementuje minimální sadu instrukcí pro jazyk FORTH.

Jazyk FORTH – dovolte odbočku – si vytvořil Charles „Chuck“ Moore na konci 60. let, a to jako vývojářskou pomůcku pro svou práci, totiž programování systémů na řízení radioteleskopů. Byla to jeho pomůcka, a myslím, že se dá směle říct, že nese dodnes velmi silný vtisk jeho osobnosti. Zatímco ostatní jazyky se snaží přiblížit počítač programátorovi, FORTH jako by šel opačnou cestou: je velmi jednoduchý pro počítač, ale náročný pro programátora. Dokonce se tvrdí, že některá slova tohoto jazyka Moore vymýšlel tak, aby se mu pohodlně psaly na klávesnici… V Československu se FORTH dostal do povědomí veřejnosti v osmdesátých letech, kdy o něm začal vycházet seriál v časopise Amatérské Radio. Říkalo se, že nějaká ústřední plánovací komise rozhodla, že FORTH bude ten správný jazyk pro budoucí socialistické mikropočítače, ale pak to s tím socialismem nějak nedopadlo…

Hlavním rysem jazyka FORTH je, že používá dvojici zásobníků (uživatelský zásobník a zásobník návratových adres). Na zásobníku očekávají procedury (ve FORTHu se nazývají „slova“) své parametry a nechávají tam výsledky své činnosti.

Tato podstata vede k zajímavému důsledku: FORTH nezapisuje aritmetické operace tak, jak jsme zvyklí, s operátory mezi operandy („a + 1“ – infixová notace), ale v notaci postfixové („a 1 +“).

Opačná, prefixová notace, kdy je zapsán nejdřív operátor a pak operandy („+ a 1“), může být povědomá těm, kdo znají jazyk LISP. Navrhl ji polský logik Jan Łukasiewicz kolem roku 1920, a proto je známa i jako polská notace. Její obrácená varianta, postfixová, je tedy logicky nazývána „obrácenou polskou notací“, v angličtině Reverse Polish Notation (RPN).

Obrácená polská notace lehce znepřehledňuje zápis aritmetických operací („2 + 3 * 4“ zapíšete jako „3 4 * 2 +“, popřípadě jako „2 3 4 * +“), na druhou stranu výrazně zjed-nodušuje zpracování: interpreter nemusí řešit závorky ani prioritu či asociativitu operátorů. Operátor „+“ prostě vezme dvě hodnoty ze zásobníku, sečte je a výsledek zase uloží na zásobník. Operátor násobení * udělá totéž, ale hodnoty vynásobí. Je na programátorovi, aby zohlednil priority.

Největší síla a důvod, proč se FORTH rozšířil a nezůstal soukromou pomůckou geniálního, i když možná lehce šíleného vývojáře, je v tom, že si ve FORTHu může každý vytvářet vlastní příkazy („slova“). Respektive ještě jinak: Když programujete ve FORTHu, vytváříte si tím vlastní dialekt FORTHu, plný krátkých a efektivních „slov“, která se skládají do složitějších a složitějších, až nakonec na nejvyšší úrovni zůstane jedno či několik mocných slov, které udělají všechno to, co potřebujete („ŘIĎ-TELESKOP!“). Zkrátka jazyk, strukturovaný z podstaty, v době, kdy „strukturované programování“ bylo předmětem vášnivých akademických diskusí.

Díky těmto rysům je FORTH velmi efektivní, rychlý a implementačně jednoduchý. Nerozšířil se jako univerzální jazyk pro vývoj software, ale je samozřejmě dostupný pro všechny možné operační systémy a své použití nachází často právě ve světě zabudované („embedded“) elektroniky.

Chuck Moore navrhl i vlastní mikroprocesor, který by dokázal přímo „podporovat FORTH“ – jmenoval se Novix N4000. Později jej vylepšil a koncepci prodal společnosti Harris. Ta jej vylepšila na verzi RTX2000, přidala radiační ochranu a našla pro něj zákazníka: vesmírný program. Dnes společnost Intersil vyrábí verzi RTX2010, který například řídil přistávací modul Philae při misi Rosetta.

Bowmanův procesor J1 je mnohem jednodušší (200 řádků Verilogu) než tyto specializované procesory, ale přesto překvapivě efektivní a rychlý. V dokumentaci autor uvádí, že s tímto procesorem streamoval nekomprimované video přes Ethernet jen pomocí jednoduché programové smyčky.

J1 je šestnáctibitový dvouzásobníkový procesor s von Neumannovou architekturou a instrukční sadou, která je velmi blízká standardu ANS FORTH. J1 neimplementuje některé funkce: příznak přenosu, přerušení, výjimky, relativní skoky, násobení a dělení nebo osmibitový přístup k paměti. I s těmito omezeními jde o výkonný procesor, schopný mnoha komplexních úloh (a v roli grafického koprocesoru ideální).

Obsahuje zásobník návratových adres RS (16 položek) a uživatelský datový zásobník DS (17 položek). Nejvyšší položka zásobníku RS je označována R. Nejvyšší položka datového je T (TOS, Top Of Stack), položka pod ní je N (NOS, Next Of Stack). Adresní sběrnice (a tedy i programový čítač) má 13 bitů (může tedy adresovat paměť o velikosti 8192 šestnáctibitových slov). Programátor může pracovat s jednotlivými bajty a přistupovat k paměti jako k 16 kB prostoru, ale interně probíhá přístup vždy zarovnaný na 16 bitů.

Sada instrukcí obsahuje pět základních typů instrukcí pro zásobníkové procesory, totiž literály (konstanty, které se mají uložit na zásobník), skoky, podmíněné skoky, volání podprogramu a aritmetické / logické operace. Literály jsou patnáctibitové, šestnáctý bit je 0, takže rozsah hodnot je 0 – 32767. Pokud je potřeba zadat číslo z rozsahu 32768 – 65535, musí překladač vložit instrukci „invert“, která nastaví nejvyšší bit na 1.

Všechny cílové adresy skoků jsou 13bitové a absolutní. Podmíněný skok má pouze jeden jediný typ podmínky, totiž „skok, pokud je nejvyšší hodnota na zásobníku nula“.

Šestnáctibitové instrukční slovo obsahuje několik pevně daných polí s jednoznačným významem:

  • Bit 15: 1 = literál (pak ostatních 15 bitů obsahuje konstantu), 0 = instrukce
  • Bity 14 a 13: pokud je bit15=0, kódují typ instrukce:
    • 00 – nepodmíněný skok JUMP
    • 01 – podmíněný skok JUMPZ
    • 10 – volání podprogramu CALL
    • 11 – operace s ALU,

U operací skoků a volání je v bitech 0 – 12 požadovaná adresa.

Instrukce ALU má v bitech 0 – 11 zakódováno, co má procesor udělat s daty (bit 12 není použitý – v dokumentaci je chybně uvedeno, že je to bit 4):

Bity Označení Význam
12   Není použito
11 – 8 T‘ Konkrétní operace s ALU
7 R->PC Zkopírovat nejvyšší hodnotu ze zásobníku návratových adres (R) do čítače PC
6-4 func Požadovaná operace
3-2 rstack O kolik položek se má změnit zásobník R (se znaménkem)
1-0 dstack O kolik položek se má změnit uživatelský datový zásobník (se znaménkem)

Tato struktura instrukčního slova umožňuje provést některé optimalizace a spojit často používané operace dohromady. Například bit 7 (R->PC) slouží jako příznak návratu z podprogramu (vezme hodnotu ze zásobníku adres a vloží ji do PC). Není potřeba speciální instrukce, stačí u poslední instrukce podprogramu nastavit bit 7 a bity rstack na „-1“ a procesor se správně vrátí za příslušnou instrukci call.

Bity 6-4 kódují požadovanou operaci, kterou má procesor vyvolat, a to takto:

Hodnota funkce
000 Nic
001 T->N
010 T->R
011 MWR (Memory Write)
100 IOWR (IO Write)

ALU nabízí 16 operací, které jsou komplexnější než ty, co jsme používali u procesoru MHRD, ovšem také samotná aritmeticko-logická jednotka není složená z připravených obvodů, ale zapsaná behaviorálně, jak uvidíme dál.

Kód Výsledek Kód Výsledek
0 T 8 N < T (porovnání se znaménkem)
1 N 9 N » T (posun doprava)
2 T+N 10 N « T (posun doleva)
3 T AND N 11 R (hodnota z RS)
4 T OR N 12 [T] (čtení z paměti)
5 T XOR N 13 [T(io)] (čtení z periferie)
6 NOT T 14 Počty položek na RS a DS
7 N = T (porovnání) 15 N u< T (porovnání bez znaménka)

Pro nejzákladnější operaci se zásobníkem, DUP, tedy nastavíme slovo takto: Výsledek ALU bude hodnota T, dstack se zvýší o 1 a provádí se operace T->N.

Další díl

Twitter, Facebook