4 bites mini processzor

Régóta gondolkodtam egy saját számítógép megépítésén, és mostanra jutottam el odáig, hogy meg is tudjam valósítani. Az elkészítésben nagy segítséget nyújtott a SEM és a műhelyük, ahonnan alkatrészeket kaptam, és hibajavítás céljából egy nyákot is legyártottam.

A cikk egy saját tervezésű processzorról fog szólni, amit a Digit tárgyban már megismert regiszterek, számlálók és multiplexerek segítségével sikerült összeraknom. Igyekeztem a lehető legegyszerűbb (azaz legkevesebb hibalehetőséget tartalmazó) áramkört létrehozni.

A processzor két 10×10 cm-es nyákból áll, az egyiken a vezérlő egység, a másikon az aritmetikai egység kapott helyet. Maga a processzor 4-bites (azaz 0 és 15 közötti számokkal dolgozik). Az eredeti változatban sajnos elég sok hibát találtam, de az ide feltöltött tervrajzokban ezek már javítva vannak. Jelenleg a bemenetre 4 kapcsolót, a kimenetre pedig 4 LED-et raktam, de ez akár shift regiszterekkel is bővíthető.

Schematic: aritmetikai egységvezérlő egység

Utasításkészlet:

Aritmetikai utasítások esetén az egyik operandus a 4-bites akkumulátor (A) regiszer vagy a 0. A másik operandus lehet egy szám, az INPUT külső bemenet, vagy egy adat a memóriából, illetve ezek kettes komplensei (azaz -1 -szeresei).

  • add/sub: összeadás és kivonás (modulo 16), az átvitelbit minden műveletvégzés után alaphelyzetbe állítódik
  • and/or/xor: bitműveletek
  • mov: adatmozgatás, az A regiszer tartalma a megadott címre kerül az adatmemóriába, vagy az OUTPUT kimeneti regiszterbe
  • jmp: ugrás, a programszámláló (PC) regiszter átállítása
  • jz/jnz: feltételes ugrás, csak akkor ugrik, ha A zérus, illetve nem zérus

Az utasítások formátuma “utasítás érték”, pl. “add 5“, de az assembler bonyolultabb parancsokat is ismer, amiket visszaalakít a processzor számára érthetővé, pl. “inc @0” (ami C-ben ezt jelenti: memory[0]++ ) helyett “and 0, or @0, add 1, mov @0“.

Aritmetikai egység:

Itt található az adatmemória, amiben 16 darab 4-bites érték tárolható. A memória adatbuszán található még egy three-state buffer is, hogy írni és olvasni is lehessen belőle. Minden aritmetikai utasítás után számolás eredménye az A regiszterbe kerül. Ha “mov OUTPUT” utasítás érkezik, akkor az OUTPUT kimeneti regiszterbe másolódik az A regiszter értéke.

Maga a számítást végző rész egy mindössze 3 darab logikai kapus (azaz AND, OR, XOR) IC-ből álló kombinációs hálózat, ami az eredményt bitenként számítja ki, és beleshifteli az A regiszterbe. A bitek számítása között keletkező átvitelt és az eredmény zérusságát egy külön státuszregiszterben tárolom, ahonnan csak a zérus (Z) jelet vezettem ki. Emiatt egy műveletvégzés 4 órajelet igényel.

A maradék IC multiplexer, ami arra szolgál, hogy a operandust (szám, memória vagy INPUT) és a megfelelő művelet eredményét (add/sub, and, or vagy xor) kiválassza, illetve hogy a műveletek elején a carry és zero flageket alaphelyzetbe állítsa.

Vezérlő egység:

A feladata, hogy a programmemóriában az éppen a programszámláló (PC) által kijelölt címen található utasításnak megfelelően állítsa elő a vezérlőjeleket az aritmetikai egység számára. A PC regiszer két darab számlálóból áll, így összesen 256 utasítás megcímzésére alkalmas. A programmemória adat- és címvezetékei ki vannak vezetve, hogy pl. egy Arduino-val lehessen rá a programot feltölteni.

Egy aritmetikai számoláshoz 4 órajel szükséges, de még az aktuális utasítást több memóriacímről is ki kell olvasni (mivel minden utasítás 12 bites, de a memóriának csak 8 adatvezetéke van), ezért az egyszerűség kedvéért minden utasításnak 8 órajelnyi időt adtam, és egy számláló alsó 3 bite segítségével állítottam elő a vezérlőjeleket (pl. az adatmemória írása, az A regiszer léptetése, stb.).

Az itt található gombokkal lehet resetelni, és a végrehajtást szünetelni.

Példaprogramok (erős idegzetűeknek):

Az Arduinonak csak az a szerepe, hogy feltöltse a programokat, és még debuggerként is használható. Feltéve, hogy a program már beíródott a programmemóriába, csak egy külső órajel kell a működéshez, amit szintén az Arduino szolgáltat.

Egyszerű számláló, ami a bemenetről beolvasott számnak megfelelő ciklusnyit várakozik:

Megszámolja az 1-es biteket a bemeneten (popcount):

Pszeudovéletlenszám-generátor: