Programovací jazyk Forth a zásobníkové procesory (16)

26. 4. 2005
Doba čtení: 11 minut

Sdílet

V dnešním pokračování seriálu o programovacím jazyce Forth a zásobníkových procesorech si popíšeme dva zajímavé šestnáctibitové zásobníkové procesory: WISC CPU/16 a MISC M17. Před popisem těchto procesorů si však ještě shrneme základní vlastnosti šestnáctibitových zásobníkových procesorů, zejména jejich klady a zápory v porovnání se zásobníkovými procesory jiných bitových šířek.

Obsah

1. Zásobníkové procesory kategorie MS0 a ML0
2. Vlastnosti šestnáctibitových zásobníkových procesorů
3. Zásobníkový procesor WISC CPU/16
4. Instrukce a mikroinstrukce procesoru WISC CPU/16
5. Zásobníkový procesor MISC M17
6. Architektura procesoru MISC M17
7. Základní vlastnosti procesoru MISC M17
8. Instrukční soubor procesoru MISC M17
9. Obsah dalšího pokračování

1. Zásobníkové procesory kategorie MS0 a ML0

Multiple stack, 0-operand machines have two inherent advantages over other machines: 0-operand addressing leads to a small instruction size, and multiple stacks allow concurrent subroutine calls and data manipulations. These features and others lead to small programs, low system complexity, and high system performance. The main difference between MS0 and ML0 machines is that MS0 machines give up some performance in order to reduce the CPU cost by minimizing the resources used for the stack buffers.

Všechny zásobníkové procesory, které budou v tomto i dalším pokračování seriálu popisovány, spadají buď do kategorie MS0 nebo ML0. Jak již víme z předcházejících dílů, vyznačují se tyto kategorie procesorů použitím dvou samostatných zásobníků a použitím instrukcí, ve kterých nejsou (většinou) adresovány operandy, protože je předem zřejmé, že se hodnoty pro provádění operací získávají pouze z jednoho zásobníku, na který se posléze ukládá i výsledek operace. Víme také, že první zásobník je určen pro předávání parametrů a provádění výpočtů a druhý zásobník pro úschovu návratových adres volaných funkcí. Dvouzásobníkové procesory jsou často navrhovány tak, aby na nich bylo možné efektivně provozovat aplikace napsané v programovacím jazyce Forth. Instrukce jsou u této kategorie procesorů poměrně krátké, neboť v nich chybí část nutná pro adresování operandů.

Rozdíl mezi kategoriemi MS0 a ML0 spočívá ve velikosti zásobníku resp. zásobníků. Pokud je použit procesor kategorie MS0, znamená to, že je větší část zásobníku či dokonce celý zásobník uložen ve speciálních registrech mikroprocesoru. Výhodou je rychlejší přístup ke všem položkám zásobníku, může však dojít k jeho přetečení, zejména v případě použití špatně navržených programů. Přetečení buď způsobí chybu, nebo je nutné celý zásobník uložit do operační paměti počítače resp. z ní načíst, což samozřejmě znamená značné zdržení výpočtů.

U kategorie ML0 je naproti tomu skoro celý zásobník vytvořen v operační paměti počítače, kromě minimálně dvou položek na vrcholu zásobníku, které jsou prakticky vždy mapovány do speciálních registrů procesoru. Tento přístup k vytváření zásobníku patří mezi nejjednodušší a přitom prakticky neomezuje velikost zásobníků. Nevýhodou je pomalejší přístup k jednotlivým položkám, protože rychlost pamětí tvoří v současné době úzké hrdlo velké části mikroprocesorových systémů.

2. Vlastnosti šestnáctibitových zásobníkových procesorů

The primary motivating factor for making Forth machines 16 bits wide is that the Forth programming model has traditionally been 16 bits. This is consistent with average Forth program sizes of less than 32K bytes and the implementation of most of the first Forth compilers on microprocessors with 64K byte address ranges.

Oba dále popisované zásobníkové procesory jsou šestnáctibitové, tj. bitová šířka zásobníku operandů i zásobníku návratových adres je rovna šestnácti bitům, stejně jako bitová šířka aritmeticko-logické jednotky těchto procesorů. Šestnáctibitové zásobníkové procesory jsou velmi populární, a to i v dnešní době, kdy se na osobních počítačích a pracovních stanicích objevují procesory šedesátičtyřbitové. Otázkou je, proč tato popularita šestnáctibitových zásobníkových procesorů přetrvala i do dnešních dnů.

Nejprve začněme u jednodušších procesorů. Čtyřbitové a osmibitové procesory se pro provozování většiny aplikací nehodí, protože čtyři resp. osm bitů nabízí poměrně malý rozsah hodnot, které lze do registrů a zásobníků uložit. Ve své podstatě tyto procesory ve většině aplikací simulovaly šestnáctibitové prostředí, a to jak bitovou šířkou adresové sběrnice, tak i posloupností instrukcí provádějících aritmetické a logické operace (sčítání šestnáctibitových hodnot pomocí příznaku přetečení apod.). Na druhou stranu se ukazuje, že šestnáct bitů již může být pro mnoho operací dostačující hodnotou, dokonce se traduje, že většina systémů založených na Forthu si vystačí s pouhými 64 kB paměti, kterou lze adresovat právě šestnáctibitovou adresou.

Šestnáctibitové procesory jsou také v dostatečné míře jednoduché, oproti třicetidvoubitovým procesorům je použito mnohem méně logických prvků v ALU (zejména sčítačky a násobičky jsou „žrouty“ logických prvků) i při implementaci vnitřních sběrnic. Menší počet logických prvků se samozřejmě odráží jak v ceně samotného procesoru, tak i v jeho velikosti, spotřebě energie aj. To, spolu s menší potřebnou kapacitou operační paměti, činí tyto procesory ideálními pro velkou část vestavěných systémů, zejména v případě, kdy osmibitové procesory neposkytují dostatečný výpočetní výkon.

V dalším textu budou popsány dva čistě šestnáctibitové zásobníkové procesory: procesor WISC CPU/16 a MISC M17.

3. Zásobníkový procesor WISC CPU/16

There can be a great advantage to getting a high performance CPU, and specialized i/o coprocessors on a single chip. In volume the $1 manufacture cost becomes very attractive.
Jef Fox

Šestnáctibitový zásobníkový procesor WISC CPU/16 získal své označení podle zkratky Writable Instruction Set Computer. Jak již tento název napovídá, jedná se o procesor, ve kterém je možné použít vlastní instrukční sadu; každá instrukce uložená v této instrukční sadě je kódována pomocí několika takzvaných mikroinstrukcí (to je výrazný rozdíl oproti jiným mikroprocesorům, ve kterých bývají instrukce napevno „zadrátovány“). Tento procesor byl vytvořen zejména proto, aby se otestovaly některé klíčové vlastnosti modernějšího procesoru RTX 32P, který bude v dalších dílech tohoto seriálu také popsán. Velkou předností procesoru WISC CPU/16 je – na svou dobu výborný – poměr cena/výkon, který byl překonán až v době příchodu vyspělejších mikroprocesorů a zejména mikrořadičů.

Tento procesor byl vytvořen z diskrétních MSI komponentů na bázi řady 74LS00 (ALU bylo například tvořena čipem 74LS181), což umožnilo například jeho snadné rozšiřování a testování (připojení osciloskopu či logického analyzátoru na vnitřní sběrnice). Celý procesor byl, spolu s pomocnými obvody, vytvořen na plošném spoji, který bylo možné zasunout do PC jako koprocesor. Vzhledem k době vývoje tohoto procesoru byla pro komunikaci s PC použita sběrnice ISA. Adresovat bylo možné operační paměť o kapacitě 128 kB, adresa totiž byla uložena v šestnácti bitech, každá adresovatelná buňka měla velikost šestnáct bitů (po bytech nebylo možné adresování provést, podobně jako u následujících procesorů). V prakticky všech implementacích (zejména na testovací přídavné desce do PC) se však používala dynamická paměť o kapacitě pouhých 16 kB.

Datový zásobník má hloubku 256 položek, přičemž každá položka (v řeči Forthu buňka – cell) má velikost šestnáct bitů. Taktéž zásobník návratových adres má hloubku 256 položek po šestnácti bitech. Ukazatele na datový zásobník i zásobník návratových adres jsou uloženy na osmi bitech a lze je považovat za registry, z nichž lze číst i do nich zapisovat – teoreticky by však měla stačit pouze inkrementace a dekrementace.

4. Instrukce a mikroinstrukce procesoru WISC CPU/16

Kromě pracovní paměti byla použita ještě mikroprogramová paměť o kapacitě 2kB x 32 bitů. Tato paměť byla použita pro kódování mikroinstrukcí a díky konstrukci celého procesoru ji bylo možné po resetu naplnit z řídicího PC, což výrazným způsobem zjednodušovalo návrh a testování mikroinstrukcí. Formát mikroinstrukcí byl velmi jednoduchý, protože se používal takzvaný horizontální formát kódování. Pomocí mikroinstrukčního kódu bylo možné vytvořit například instrukce, které prováděly rozeskok a současně smyčky. Nejkratší mikrokód byl proveden již za 2–3 mikrocykly, nejdelší mohl zabrat i několik tisíc mikrocyklů.

Adresování mikroinstrukcí probíhá po 256 stránkách, v jedné stránce je možné vytvořit osm slov. Každá mikroinstrukce má délku 32 bitů, jež jsou rozděleny do několika polí o pevné délce. Existuje osm způsobů nastavení podmínky, 17 základních aritmetických a logických operací, inkrementace registru PC, autoinkrementace či autodekrementace některého operandu a bitový posun doleva a doprava o jeden bit. Vstupní operand je možné adresovat jedenácti způsoby (může být na zásobníku, na adrese uložené v registru PC, v operační paměti apod.), výstupní operand je možné adresovat až třinácti způsoby (dokonce je možné tvořit datové smyčky, kdy je jako vstupní operand použit výsledek předchozí instrukce). Zajímavé je, že procesor neobsahuje registr pro příznaky (carry, zero atd.), příznaky se tedy musí ukládat na datový zásobník jako hodnoty 0, –1 apod.

Pomocí mikroinstrukcí lze vytvořit prakticky libovolnou instrukční sadu. Standardně dodávaná instrukční sada se skládá z instrukcí, z nichž každá má fixní délku šestnáct bitů. Existují dva formáty instrukcí: pomocí instrukce prvního formátu se zavolá příslušná mikroinstrukce (provede se operace), pomocí instrukce druhého formátu se provede vyvolání podprogramu (call). Při použití instrukce prvního formátu musí být všechny bity 8–15 nastaveny na jedničku, zbývající bity 0–7 obsahují operační kód mikroinstrukce, kterých tak může být pouze 256. Při použití druhého formátu musí být alespoň jeden z bitů 8–15 nulový, na všech bitech dohromady je uložena adresa šestnáctibitového slova (nikoli bytu), na které se provede skok. Jelikož musí být alespoň jeden z horních osmi bitů nulový, nelze v adresovém prostoru o celkem 65536 slovech skákat na 2048 slov, což jsou pouhá tři procenta adresového prostoru.

Vlastní instrukce mohou být vytvořeny uživatelem vhodně naplněnou mikroprogramovou pamětí, existuje například implementace slov MVP-Forthu, Forthu-79 apod. Standardní mikrokód podporuje například následující forthovská primitivní slova (průměrně trvá jedna instrukce tři hodinové cykly):

    !                        DDROP
    +                        DDUP
    +!                       DNEGATE
    -                        DROP
    0                        DSWAP
    0<                       DUP
    0=                       I
    0BRANCH                  I'
    1+                       J
    1-                       LEAVE
    2*                       LIT
    2/                       NEGATE
    <                        NOP
    PICK                     NOT
    ROLL                     OR
    =                        OVER
    >R                       R>
    ?DUP                     R@
    @                        ROT
    ABS                      S->D
    AND                      SWAP
    BRANCH                   U*
    D!                       U/MOD
    D+                       XOR
    D@ 

Do jedné instrukce je možné zakódovat i různé složeniny primitivních forthovských slov, například:

    @ +
    @ -
    DROP ;
    DROP DUP
    I +
    I + @
    OVER +
    OVER -
    R> DROP
    R> SWAP >R
    SWAP -
    SWAP DROP
    DUP @ SWAP 1+        (fetch and increment address)
    DUP ROT ROT ! 1-     (store and decrement address)
    @ @                  (indirect fetch)
    @ !                  (indirect store)
    DUP @  @  1 ROT +!   (auto-postincrement indirect fetch for software stack)
    -1 OVER +!  @ !      (auto-predecrement indirect store for software stack) 

5. Zásobníkový procesor MISC M17

Several features of the MISC M17 are directed to the designer of small volume, high performance products. Example applications include remote sensing for smoke stacks, mines, hazardous areas, and remote equipment installations. The decision to place stacks in program memory results in lower system cost and complexity. The asynchronous memory bus protocol allows coupling high speed processing and data transmission operations without complicating the interface to low speed data acquisition devices.

Procesor MISC M17 byl vyráběný firmou se zajímavým názvem Minimum Instruction Set Computer, Inc.. Jedná se o zásobníkový procesor, který je primárně určen pro vestavěné systémy. Hlavním cílem, který se podle všeho podařilo splnit, byla nízká prodejní cena, což však negativně ovlivnilo některé další vlastnosti tohoto procesoru, zejména umístění obou zásobníků v operační paměti (nejvyšší položky zásobníků jsou samozřejmě uloženy v interních registrech, jinak by byl procesor velmi pomalý).

Zásobníky jsou v operační paměti umístěny tak, že rostou proti sobě, volný prostor mezi nimi lze využít k uložení dynamických dat.

6. Architektura procesoru MISC M17

Procesor MISC M17 obsahuje několik interních registrů. Registry označené symboly X, Y a Z obsahují nejvyšší tři elementy (buňky) datového zásobníku. Pomocí instrukcí procesoru lze mezi těmito registry přenášet data v jednom cyklu, současně lze také do registru Z načítat či naopak ukládat hodnoty z paměti – tímto způsobem lze jednoduše realizovat forthovská slova dup,drop, swap, over, rot, nip atd.

Interní registr LASTX obsahuje v každém cyklu kopii hodnoty registru X. Tento registr je možné využít pro některé výpočty a pro uložení mezivýsledků operací.

Interní registr INDEX obsahuje nejvyšší položku zásobníku návratových adres. Je ho také možné použít jako čítač (čítá se směrem k nule), čehož lze využít při tvorbě počítaných smyček.

Mezi další registry patří ukazatele na vrcholy datového zásobníku a zásobníku návratových adres. Tyto registry jsou vytvořeny jako čítače +-1. V registru PC je, jak již bývá zvykem, uložena adresa právě zpracovávané instrukce. Tento registr je možné měnit instrukcemi skoku a instrukcí pro návrat z podprogramu.

7. Základní vlastnosti procesoru MISC M17

Tento procesor může adresovat až 128 kB paměti, protože se, podobně jako u procesoru předchozího, provádí adresování po šestnáctibitových slovech. Existují však instrukce pro prohazování, pakování a rozdělování bytů, takže lze poměrně jednoduše implementovat i bytovou aritmetiku.

Kromě toho je z procesoru vyvedeno pět pinů, které svou logickou úrovní určují, jaká část paměti se bude číst či zapisovat – datový zásobník (1), zásobník návratových adres (2), část paměti s kódem programu (3), buffer A (4) nebo buffer B (5). Tyto piny se mohou buď ignorovat, nebo je možné použít pět na sobě nezávislých banků paměti, každý s kapacitou 128 kB (v tomto případě je možné signál z pěti zmíněných pinů negovat a přivést na vstup CS paměti).

Provedení každé instrukce z instrukčního souboru trvá vždy dva cykly, včetně skoků a návratů z podprogramu. Rychlost procesoru je při použití statických pamětí RAM s přístupovou dobou 30 ns rovna 15 MHz, při použití pamětí s přístupovou dobou 120 ns potom 6 MHz. Dynamické paměti se nepoužívají, jejich funkčnost ve vestavěných systémech je velmi problematická.

8. Instrukční soubor procesoru MISC M17

Jak již bylo zmíněno výše, používá zásobníkový mikroprocesor MISC M17 instrukce s délkou šestnáct bitů. Je použitý takzvaný horizontální formát instrukcí, čímž se značným způsobem zjednodušil instrukční dekodér na mikroprocesoru. Existují tři typy instrukcí. Prvním typem instrukce je skok do podprogramu, tato instrukce je charakterizovaná tím, že nejspodnější bit má nulovou hodnotu. Všech ostatních patnáct bitů potom specifikuje adresu (ve slovech), na kterou se má skok provést.

Dalším typem instrukce je instrukce s podmínkou. Pomocí dvanácti bitů je možné specifikovat libovolnou kombinaci dvanácti podmínek, po splnění těchto podmínek se může provést jedna ze tří operací: nastavení hodnoty, skok nebo návrat z podprogramu. Třetím a posledním typem instrukce je provedení aritmetické či logické operace; k dispozici je celkem šestnáct operací, volba zdroje a cíle operace a případně i bitový posuv doprava či doleva (bitový posuv je řešen samostatně a sériově k datům posílaným do ALU).

ict ve školství 24

9. Obsah dalšího pokračování

V dalším pokračování tohoto seriálu si popíšeme šestnáctibitové zásobníkové procesory Novix NC4016 a Harris RTX 2000. Poté se již budeme věnovat mnohem výkonnějším třicetidvoubitovým zásobníkovým procesorům.

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.