MOS 6502 · reverse engineered from silicon

Kutatási dolgozat (2001)

TDK dolgozat, BME Villamosmérnöki Kar, 2001. Az eredeti magyar szöveg webes kiadása.

EnglishMagyar

Mikroprocesszorok: layouttól a kapcsolási rajzig

Az eredeti dolgozat letöltése (Word, 2001)

Bevezetés

Az 1960-as évek óta a tranzisztor szédületes fejlődésen ment keresztül, a mikroprocesszorok bonyolultsága pedig még napjainkban is a Moore-törvény szerinti trendet követi, másfél évente duplázódik a tranzisztorszám. A gyártók között éles konkurenciaharc zajlik, a fogyasztók és a befektetők bizalmának elnyeréséhez nem elegendő csupán jó terméket piacra dobni, fontos szerepe van a technológiai újítások minél előbbi versenybe állításának is, mely a marketing tevékenység hatékonyságát is növeli. Ki érte el először az 1 GHz-et? Melyik processzorban alkalmazták először a rezet az alumínium fémezés helyett?

Van olyan gyártó, mely arra helyezi a hangsúlyt, hogy a lehetséges legnagyobb órajelen működjenek a termékei, mások inkább a legnagyobb számítási teljesítmény költséghatékony elérésén dolgoznak. A piaci verseny a fogyasztók manipulálása mellett elsősorban a fejlesztésen és a műhelytitkokon múlik: nagyon keveset lehet arról tudni, hogy mi zajlik egy mai processzorban a műveletek végrehajtása közben. A gyártók tipikusan csak azokat az információkat teszik közzé, melyek az alkalmazáshoz feltétlenül szükségesek.

Dolgozatomban a processzorok mikroszkópi vizsgálatával, a kapcsolási rajz layoutfénykép alapján való megfejtésének lehetőségeivel foglalkozom. Részletesen elemzek egy konkrét esetet, a 6502 teljes visszafejtését. Ez a processzor a fejlődés egy nagyon fontos szakaszát képviseli: az első hazai személyi számítógépek épültek a 65xx családra, mely az olcsó, hatékony és ötletgazdag tervezés egy mintapéldája. Mérete és egyszerűsége lehetővé teszi, hogy az áramköri rajzát egyetlen nagy lapra felrajzolva közzé lehessen tenni, így szemléletes oktatási segédletet nyújthat a mikroelektronikával foglalkozóknak. Kitérek egy, az egyéb processzorokban is gyakran előforduló jelenség, a nemdokumentált utasítások problémakörére is: hogyan működnek, mire lehet felhasználni őket, miért léteznek egyáltalán.

A tapasztalatok alapján megvizsgálom az Intel x86 processzorok megfejthetőségének elvi lehetőségeit, összefoglalom az alkalmazható módszereket. A kapott eredményeknek az oktatási felhasználáson kívül gyakorlati jelentőségük is van. Egyrészt az integrált áramkörök meghibásodás-analizálása igényli a tranzisztor szintű vizsgálatot, másrészt a tervezés során, a megvalósítás előtt a layout visszafejtésével ellenőrizhető, hogy a tervezett funkciót valósítja-e meg az áramkör. Ez az eljárás része a tervezés során alkalmazott ellenőrzési lépéseknek.

A 6502 tulajdonságainak áttekintése

A 6502 sikertörténete az Apple II-vel kezdődött, Magyarországon elsősorban a Commodore gépek révén ismerhetjük. Működése, programozása szinte teljesen megegyezik a legelső sorozatú Commodore 64-esekben megtalálható 6510-es processzorral, a különbség annyi, hogy a 6510-ben kijavítottak néhány hibát, és 6 darab I/O kivezetéssel látták el. A 6502-est a VC1541-es lemezegységben használták. Mai szemmel furcsának tűnhet, hogy miért kell egy floppyba egy 8 bites processzor, amely ráadásul ugyanakkora számítási teljesítménnyel bír, mint maga az alapgép. A VC1541-es a géptől különálló készülék, soros buszon csatlakoztatható intelligens periféria 2 Kbyte szabadon programozható RAM-mal (speciális lemezkezelő rutinok, gyorstöltők használták, melyek közvetlenül vezérelték a beolvasást, a léptetőmotort).

A 65xx család tagjainak minimális számú regisztere van, de azok a sokféle címzésmódnak köszönhetően nagyon hatékonyan használhatók. 16 bites utasításszámláló (IP), 8 bites veremmutató (SP), flag, akkumulátor (A), X és Y indexregiszterek. A veremműveletek és a memória alsó 256 byte-ján dolgozó utasítások 1 óraciklussal gyorsabbak, mint az egyéb műveletek, ezt ki is használják azok a szoftverek, melyeket sebességre optimalizáltak. Az egyszerű utasítások 2-3 óraciklus alatt lefutnak. Érdekesség az indirekt indexelt és az indexelt indirekt címzésmód, melyekkel nagyon hatékony adatmanipuláló ciklusokat lehet írni. A BCD számábrázolás is támogatott, ráadásul jobb megoldással, mint a mai PC-k processzoraiban: nem kell külön utasítással (DAA-val) kérni a korrekciót, mert az automatikus, ha a flag-ben a D bitet beállítják, és plusz óraciklust sem igényel. Az utasítások 1, 2 és 3 byte hosszúságúak, és nagyon tömör kódot lehet velük létrehozni: például a Commodore 64-es ROM-jában a BASIC interpreter mindössze 8 Kbyte.

56 féle utasítás, 13 féle címzésmód. A 65xx család a hatékonysága ellenére jóval olcsóbb volt a konkurencia termékeinél, még az első 16 bites processzorokkal is felvette a versenyt.

A layout

A műanyag tokozás eltávolítása reszeléssel és forró, tömény kénsavval történt. Öblítés után mikroszkóp alá került a szilícium lap. Először elektronmikroszkóppal próbálkoztam. Döbbenetes részletességű képet adott, a poliszilícium vezetékek és a fémezés jól kivehető térbeli alakzatokként jelentek meg. Az aktív zónák határa viszont egyáltalán nem látszott, ugyanis nem volt színinformáció. Hogy miért színesek az integrált áramkörök annak ellenére, hogy a szilícium szürke, annak oka a következő: a gyártási eljárás során megadott sorrendben alakulnak ki az áramkör alkotóelemei, tranzisztor gate-ek, poliszilícium vezetékek, aktív zónák, fémezés. Szigetelő rétegre van szükség a különböző alkatrészek elválasztására, ez a szilícium-dioxid. Az oxidréteg nagy hőmérsékletű kemencében alakul ki, és mivel az egyes elemek különböző időt töltenek a kemencében, ezért különböző vastagságú oxidréteg alakul ki attól függően, hogy mi van alatta. Az oxid felületéről és az oxid-szilícium határfelületről visszaverődő fény interferál egymással, a szín az oxidvastagságtól és attól függ, milyen szögből nézzük a lapkát. Az azonban mindenképpen látszik, hogy hol vannak az alkatrészek határai, és az áramkör megfejtéséhez nagyban hozzásegít.

A teljes layout
1. ábra: A teljes layout

Emiatt egy CCD kamerával ellátott optikai mikroszkópon folytattam a vizsgálatot. A felbontás ezen már korántsem volt olyan jó, közepes minőségű mikroszkóp lévén olyan képet adott, amely alapján éppenhogy lehetséges a fejtés. Az aktív zónák viszont jól felismerhetőek a színük alapján, így el tudtam kezdeni a munkát. A CCD kamera 512×512-es bitmap-eket állított elő, kis darabokban digitalizáltam be a teljes szilícium lapkát, melyeket egy képszerkesztő programmal raktam össze.

Az alapvető alakzatok, melyek felismerésével a kapcsolás rekonstruálható, a következőek:

Az NMI láb illesztése
2. ábra: Az NMI láb illesztése

Tranzisztorok

  • Kiürítéses: minden kapu terhelőtranzisztora ilyen. Jellegzetes alakjáról lehet felismerni, valamint arról, hogy a drain elektródája tápfeszültségen van, a gate pedig a source-ra van kötve.
  • Növekményes: a terhelőtranzisztorokon kívül minden más ilyen.

Vezetékek

  • Alumínium: világosszürke árnyalatú. Keresztezheti a másik két vezetéktípust, hiszen köztük oxidréteg van. A tápfeszültség és a föld mindenhova alumínium vezetékeken keresztül jut el.
  • Aktív zóna: sötétszürke árnyalatú. A 6502-n belül nagyon ritka a vezetékként való alkalmazása.
  • Poliszilícium: a leggyakoribb vezetékfajta, mivel a tranzisztorok gate-jét is ez alkotja. Egy kapu kimenete és a hozzá csatlakozó kapu bemenete egyetlen poliszilícium vezeték is lehet, az aktív zónák határaitól függ a poliszilícium szerepe.

A teljes layout (1. ábra) három jól elkülöníthető részre bontható: a regiszterblokk, mely szemlátomást 8 sorból áll, aztán középen egy nagyon kusza tranzisztorhalmaz, és végül egy PLA, mely a legrendezettebb struktúra. Az alkatrészkészlet kizárólag tranzisztorokból és vezetékelésből áll, nincsenek kondenzátorok sem, pedig a processzor nagy számban tartalmaz dinamikus tárolókat. Az ezekhez szükséges kapacitásokat a tranzisztorok és vezetékek kapacitásai adják.

A tápfeszültség és a föld mindenhol alumínium vezetékeken jut el a kapukig. A nagy távolságokat összekötő órajel vezetékek szintén, bár itt érdemes megjegyezni egy kivételt: egy hosszú alumínium vezeték középső részén egy kétszeres csíkszélességű poliszilíciumon terjed az egyik órafázis jele. A tervezők kénytelenek voltak megszakítani az alumíniumot, és a kétszeres csíkszélességgel próbálták korrigálni a nagyobb fajlagos ellenállás hátrányait.

Inverterek az adatbemeneteken
3a. ábra: Inverterek az adatbemeneteken
Inverter kapcsolási rajza
3b. ábra: Inverter kapcsolási rajza

A kapuk kialakításában jóformán semmi szabályosság nincs, változatos formavilág figyelhető meg. Egyes kapuk terhelése és a bemeneteik nagyon messze helyezkednek el a layouton, ez a toldozva-foldozva tervezés hátulütője. Olyan kapu is van, melynek terhelése egy hosszú poliszilícium vezetéken keresztül van összekötve a driver tranzisztorokkal, valószínűleg ez hátrányosan hat a kapcsolási tulajdonságokra. A nagy változatosságban jóformán csak egy szabály ismerhető fel, mely a bemenetek számára vonatkozik: NAND kapu maximum 2, NOR kapu maximum 8 bemenetű lehet.

A layout szélén tesztáramkörök is találhatók, melyeken nagy fémfelületek vannak kiképezve a mérőtűk csatlakoztatására.

Mérőtű csatlakozó helye
4. ábra: Mérőtű csatlakozó helye
Tesztáramkörök a layout szélén. Sehova nincsenek bekötve.
5. ábra: Tesztáramkörök a layout szélén. Sehova nincsenek bekötve.

Másik példa a fejlesztési fázis nyomaira: egy alumínium vezetéket olyan helyen toldottak meg egy poliszilícium vezetékkel, ahol semmi nem keresztez, tehát látszólag értelmetlen a dolog. Minden bizonnyal egy korábbi tervezési fázisban még keresztezte egy alumínium, melyet aztán máshova helyeztek át. Hasonló a helyzet a flag 5. bitjével, melynek írásvezetéke „lóg a levegőben”. Ez a bit nem használt, olvasáskor mindig 1-et ad vissza. A transzfer gate-ekkel megszakított vezetékek invertereken is átmennek (jel regenerálás), az egyedüli kiugró példa a felső 8 címkimenet meghajtó áramköre, itt 3 transzfer gate van sorba kötve.

A layouton szerencsére sehol sincs nagy felületeket lefedő fémezés, így minden tranzisztor jól látható. (Ellenkező esetben a fémezést le kellett volna marni, ahogy az a 6. ábrán látszik, mely egy Intel 8255-ös perifériavezérlő fotója.) A 6502 helykihasználása kiemelkedően jó, sehol nincsenek szabad területek: a takarékos tervezés szembetűnő.

A 8255-ös layoutrészlete
6. ábra: A 8255-ös layoutrészlete

A kapcsolási rajz megfejtése

A regiszterblokkal kezdtem a fejtést, mert ez tűnt a legegyszerűbbnek, és mivel ismétlődő sorok vannak benne, ezért viszonylag gyorsan feltérképezhettem egy nagy területet a processzorban. A 8 bitsor nem teljesen ugyanolyan, például a carry-t váltott logikával szállítja, így némely kapcsolásnak soronként a duálisa van megvalósítva. Az oszlopok, mint különálló regiszterek csak kis mértékben hasonlítanak egymásra: közös, hogy mindegyikben órajelvezérelt transzfer gate-tel megszakított, keresztbe csatolt inverterpár tárolja az információt, a különbség annyi, hogy a regiszterek a működésüktől függően más-más belső sínre tudnak írni, vagy onnan olvasni. Az Aritmetikai és Logikai Egység is egy külön oszlop a regiszterblokkban.

A blokk megfejtése után tudtam, hogy a regiszterek és az ALU hogyan cserélnek adatokat, valamint ezt hogyan írják ki a processzor D0..D7 kivezetéseire. Ekkor vettem észre, hogy ez a 8 adatbit a PLA bemeneteire is eljut, kézenfekvőnek tűnt, hogy a PLA az utasításdekódolásban játszik szerepet. Megszámoztam az oszlopokat és a sorokat, és egy egyesekből és nullákból álló táblázatot hoztam létre. Ezt egy program dolgozta fel, mely a teljes utasításkészlet ismeretében minden NOR kapura kiszámította, hogy milyen utasításokra ad 1-et a kimenetén (ez nem egyértelmű, hiszen ha egy adatbitnek sem a ponált, sem a negált vezetéke nincs rákötve a kapura, akkor többféle műveleti kód is lehetséges, melyre a kimenet érzékeny). Az egyszerű kezelhetőség kedvéért HTML file-ban adta meg az eredményeket a program: ennek segítségével gyorsan megtudható, hogy egy PLA kimenet milyen utasítások végrehajtását befolyásolja, valamint egy adott utasítás lefutásakor mely PLA kimenetek aktívak. A kétféle szempont szerinti lista között linkek segítségével lehet mozogni, tehát ez a formátum segíti a kapott eredmények gyors feldolgozását és növeli az adathalmaz áttekinthetőségét.

A munka legnehezebb részéhez értem, a layout középső legkuszább területéhez, mely egyben a működés lényegi része. 138 bemenet a PLA felől, 40 kimenet a regiszterblokk felé. A4-es lapokra kinyomtattam az egészet, a megfejtett kapcsolástöredékeket lerajzoltam, a vezetékeket beszámoztam és ráírtam az A4-es layoutkép széleire. Kissé zavaró volt, hogy toldozva-foldozva tervezték a processzort, emiatt az ugyanolyan működéshez tartozó kapcsolások (pl. interrupt logika) nem alkotnak egy összefüggő területet a layouton, hanem szétszórva helyezkednek el. Sőt: még a kapuk között is találni olyat, hogy egy lapon megvannak a bemenetek, de a terhelés két lappal arrébb van, és egy hosszú poliszilícium vezeték köti össze őket. Emiatt másfél hónapba telt, mire a layout összes tranzisztorát megtaláltam. Ez még távolról sem hasonlított kapcsolási rajzra, csak egy kusza kapuhalmaz volt, F4X12, G3X15 és ehhez hasonló vezetékdefiníciók tömkelegével.

Van egy terület, amit szinte teljesen beborít a fémezés, és erről olyan rossz minőségű kép született, hogy azt a 20-30 tranzisztort 2 napig fejtettem. A kép alapján nem volt egyértelműen eldönthető, hogy mi mivel van összekötve, több lehetőség adódott, ezért figyelembe kellett venni a működést is. Kizártam az összes olyan esetet, melynél terhelés nélkül maradt volna kapu, vagy egy kapunak nem minden bemenete volt vezérelve. Így csak egy eset maradt, és az szerencsére működés szerint is tökéletesen beleillett a kapcsolásba, így nincs okom feltételezni, hogy rosszul fejtettem.

Elkészítettem a kapcsolás első rajzolatát, összeraktam a sok kicsi darabot, és amit lehetett, összekötöttem. Egy teljesen áttekinthetetlen rajzot kaptam, egyedül a státuszregiszter volt olyan, hogy egy kupacban volt az összes áramköre. Amit nem tudtam a lapon összekötni, azt a szokásos vezetékszámmal jeleztem. Ekkor jöttem rá, hogy nem jó a jelölésrendszerem, mert ugyan megegyező névvel illettem az ugyanolyan információt szállító vezetékeket, de nem változtattam nevet minden transzfer gate-nél, mely időeltolást is jelenthet. Így a rajzon néhány megegyező nevű dolgot nem is lehet összekötni. A második rajzolatot a következő módszerrel készítettem: az ugyanolyan működéscsoportba tartozó áramköröket igyekeztem összegyűjteni, tehát a layouton össze-vissza haladtam, minden vezetéket ellenőriztem, hogy transzfer gate-ek vannak-e rajta. Az első rajzolatnak annyi szerep jutott, hogy ellenőrizni tudtam, hogy a működés szerinti barangolással eljutottam-e minden tranzisztorig.

A harmadik, végleges rajz már nem papíron, hanem számítógépen született, egy Xfig nevű unixos rajzprogramot használtam. Kialakításában az esztétika volt a meghatározó: a blokkokat úgy kellett elhelyeznem, hogy jó helykitöltés legyen, a lehető legtöbb vezeték be legyen húzva amellett, hogy nem lehet kusza a rajz, és elsősorban jól áttekinthető legyen a kész kapcsolás, lehessen látni rajta, hogy egy utasítás végrehajtása milyen részeit és milyen sorrendben mozgatja meg a processzornak.

NMI bemenet és egy teszt csatlakozó
7. ábra: NMI bemenet és egy teszt csatlakozó

Az ábrán látható teszt pad érdekessége, hogy sehova nincs bekötve, mégis sérült az alumínium felület, mintha mérőtűvel rámértek volna. A fémezés a layouton sehol máshol nem sérült, csak az ehhez hasonló teszt lábaknál. Valószínűleg az oxidréteg tulajdonságait vizsgáló méréseket végezték rajta.

A processzor működésének leírása

A gyártó által kiadott blokkséma a leegyszerűsített valóságot tükrözi, a feltüntetett 1 bites és 8 bites vezetékekből jóval több fut a blokkok között, és olyan blokkok közti kapcsolatok is vannak, melyek azon nincsenek berajzolva.

Nézzük meg először, hogy nagy vonalakban hogyan hajtódik végre egy utasítás. A beolvasott műveleti kód az utasításregiszterbe kerül, mely egy 8 bites tároló, és a teljes végrehajtás ideje alatt, minden óraciklusban felhasználásra kerül a benne tárolt érték. Egy shift regiszter számolja, hogy épp hányadik óraciklusban jár a végrehajtás. Ez utóbbinak és az utasításregiszternek a kimenetei egy PLA bemeneteire kerülnek, melynek az utasításdekódolásban van szerepe. A PLA-nak 138 kimenete van. Néhánynak egyszerű a jelentése (pl. TSX utasítás a második óraciklusban, ez a vezeték egy ellenütemű inverteren keresztül közvetlenül eljut a regiszterblokkba, és 8 transzfer gate-et vezérel, melyek egy belső sín tartalmát beírják az X regiszterbe), néhány kimenet viszont egészen összetett, utasításcsoportokat jelent, és több ilyen kimenetet egy kombinációs hálózat dolgoz fel. Az utasításdekódolónak természetesen nem csak a PLA és a hozzá csatlakozó kombinációs hálózat ad bemenetet, hanem például az interrupt logika, a státuszregiszter (feltételes ugrásnál), és felhasználásra kerül jó néhány belső vezérlőjel, ami a blokksémán egyáltalán nincs rajta, például ilyen a belső Ready jel, vagy a Sync jel.

A műveletek tényleges végrehajtása a regiszterblokkban történik: 4 belső sín van, a regiszterek és az ALU ezeken keresztül cserélhet adatot. Transzfer gate-ekkel lehet befolyásolni az adatáramlást és azt, hogy az ALU egy fázisban előállított aritmetikai műveletei közül melyik kerüljön a kimenetére, és ezeket vezérli az utasításdekódoló. Minden regiszter írása 1 óraciklus (Cp1 fázisban előtöltés, Cp2-ben kiértékelés). Az utasításszámláló növelése az összes többi művelettel párhuzamosan történik, mert saját összeadója van. Indexelés az ALU-n keresztül, BCD korrekció szintén, és ez utóbbi nem is igényel plusz óraciklust.

Órajel generátor

A Cp0 órajel bemenetből (980 kHz) a processzor saját maga állítja elő a Cp1 és Cp2 fázisjeleket, melyek nem lapolnak át, tehát élesen két időszeletre osztják az óraciklusokat. Ez nem csak a regiszterek írásánál hasznos, külső egységeknek is szükségük lehet erre, ezért két lábra ki is vannak vezetve. Az órajel generátor működésének lényege, hogy két ellenütemű inverterpár, melyek nagy áramot adnak (mindenhova el kell juttatni a fázisjeleket) és lassúak, mint késleltetők használhatók fel a jelek időbeli csúsztatására a lenti ábrának megfelelően. Maga a kapcsolás nagyon egyszerű, kevés tranzisztort használ, viszont sok helyet foglal el szilíciumon, hasonlóan a buszmeghajtó áramkörökhöz.

Órajel generátor kapcsolási rajza és működésének idődiagramja
8. ábra: Órajel generátor kapcsolási rajza és működésének idődiagramja

Utasításdekódoló

Lényegi része a PLA, mely NOR kapukból áll, és a bemeneteit az utasításregiszterből és az időzítőtől kapja. Kimenetei közvetlenül meghajtják a regiszterblokkot. Ezen kívül fontos feladata még az utasításhatárok megállapítása: ez a fetch jel kiadásához és a sync láb vezérléséhez szükséges, valamint az interrupt logikához is (megszakítás csak utasításhatáron). Az, hogy mikor kell új opkódot betölteni (fetch), az előző opkódtól függ, mert az utasítások nagy része adott óraciklust igényel, függetlenül attól, hogy van-e BCD korrekció, vagy nincs. Kivételesek a feltételes vezérlésátadások esetei, melyekben a feltétel teljesülésétől függően vagy vezérlésátadás, vagy fetch következik.

Utasításregiszter és PLA részlet
9. ábra: Utasításregiszter és PLA részlet
PLA layout
10. ábra: PLA layout

A layouton az oszlopok a NOR kapuk kimenetei, a sorok a bemenetek ponáltjai és negáltjai. Az elrendezés meglehetősen praktikus, mert 1 kontaktus két bit információt is hordozhat: az egyik sor negált bemenetét és az alatta levő sor ponált bemenetét. A 8 adatbit bemenet egyébként nem sorban van, hanem össze-vissza. Az oszlopok között előfordul olyan is, amelyik sehova nincs lekontaktusozva, mert például nem is az utasításdekódolóhoz tartozik, hanem az IRQ kérést szállítja.

A PLA kimeneteit egy kombinációs hálózat fogadja, mely nem csak a PLA-ból dolgozik, hanem jó néhány belső vezérlőjelet is felhasznál, például ilyen a belső Ready jel, a Sync jel, az időzítő egyik kimenete is. A PLA kimenetek komplex kapukon áthaladva ellenütemű inverterekre jutnak, melyek egy hosszú poliszilícium vezetéket és 8 transzfer gate-et meghajtva közvetlenül befolyásolják a regiszterek írását / olvasását, az ALU működését, valamint a buszmeghajtó áramkörök, cím és adat vezetékek tartalmát.

Akkumulátor értékadás
11. ábra: Akkumulátor értékadás

A 11. ábrán egy egyszerű eset látható, az akkumulátor írásának a vezérlése. A 61-estől a 66-os számú PLA kimenetig a következő műveletek vannak kikapuzva: X vagy Y írása A-ba, logikai műveletek, összeadás - kivonás, akkumulátor bitléptetése, betöltése veremből. Vannak azonban ennél jóval bonyolultabb kapcsolások, melyek szintén a regiszterblokk transzfer gate-jeit vezérlik: például mikor kell egyik belső sín tartalmát a másikra írni, honnan kapja az ALU a bemeneteit stb. Sokbemenetű kapuk dolgozzák fel a PLA olyan kimeneteit, melyek nem teljesen specifikáltak: a műveleti kód néhány bitje se 0-ra, se 1-re nincs lekötve. Emiatt a nem használt opkódok egészen érdekes működést produkálhatnak. Mivel nincs ellenőrizve, hogy egy opkód megfelelő-e, valami mindenképpen történik. A PLA néhány kimenete aktivizálódik, a regiszterblokk ennek hatására csinál valamit. Az úgynevezett „tiltott kódokat” három csoportba lehet besorolni:

  • Üres utasítás, mint a NOP: beolvassa az operandusát, egy sínre kiírja, ám ekkor be is fejezi a működését, az eredményt „ottfelejti”. Valamely későbbi utasítás fogja felülírni, így elvész.
  • Értelmes utasítás, mely komplex is lehet, több műveletet is elvégezhet, mint például az ANE: A = (A | #$EE) & X & #byte. A beépített konstans sem garantált!
  • Fagyást okozó utasítás. Ha több regiszter tartalmát ugyanarra a sínre írjuk, vagy az ALU egy menetben kiszámolt logikai függvényeiből többet is a kimenetére kényszerítünk, akkor logikai kapuk egymás ellen dolgozhatnak, nem alakul ki éles 0 vagy 1 szint, amit ugyan a következő kapuk elfogadnak, csinálnak belőle valamit, de mindenképpen lassabban kapcsolnak. Az előírt időzítések felborulnak, a processzor működésképtelen állapotba kerül.

A tiltott kódoknak egyébként fontos alkalmazása volt a programvédelem: egy módszer volt a sok közül arra, hogy egy szoftver írói megnehezítsék a kódtörők munkáját. Eleinte ugyanis a disassemblerek nem ismerték a tiltott kódokat, azokat érvénytelen opkódnak mutatták, ezért rosszul állapították meg az utasításhatárokat is: a tiltott kódokkal megírt program így egy nehezen módosítható, zavaros byte-halmaznak tűnt.

Időzítő vezérlő

Fő feladata, hogy az utasításdekódolónak megadja azt az információt, hogy a végrehajtás alatt levő utasítás hányadik óraciklusban jár. Az utasítások legalább 2, legfeljebb 7 óraciklus alatt futnak le, az első óraciklus mindig fetch (műveleti kód betöltése az utasításregiszterbe). Az időzítő vezérlő 1-1 kimenetén adja ki 6 ciklus információját (ez közvetlenül a PLA bemeneteire jut). Az utolsó négy ciklust egy olyan shift regiszterrel oldották meg, amelyben egy végigfutó 1-es bit jelenti az információt, és RDY=0 esetben a shift regiszter 4 bites tárolóként működik. A regiszternek ezen kívül van egy nullázó bemenete is, melyet az utasításdekódoló vezérel.

Shift regiszter
12a. ábra: Shift regiszter
Shift regiszter layout. A fémezés miatt nehezen fejthető.
12b. ábra: Shift regiszter layout. A fémezés miatt nehezen fejthető.

Interrupt logika

Feladata az IRQ, NMI vonalakon érkező megszakításkérések fogadása, engedélyezés eldöntése, és a megfelelő vektor által meghatározott címre történő vezérlésátadás, amennyiben utasításhatárra ér a processzor, valamint RESET esetén a reset vektor betöltése. Mindhárom eset lényegében egy indirekt vezérlésátadás, melyhez memóriaolvasási ciklusok kellenek. IRQ és NMI esetén veremműveletekre is szükség van, menteni kell a flag-et és az utasításszámlálót. Megszakítás elfogadásakor az interrupt logika szimulál egy BRK (szoftver megszakítás) utasítást az utasításdekódolónak, a különböző események között csupán annyi a különbség, hogy milyen címen van az ugrásvektor. A vektor címének beállításakor közvetlenül meghajtja a címkimeneteket, ehhez óraciklusokat „foglal le”, és a belső READY jellel (Rdy0 a kapcsolási rajzon) várakoztatja a processzor többi részét. Ezt a többi blokk úgy észleli, mintha egy külső, lassú egység húzta volna le a processzor RDY lábát, plusz óraciklusokat igényelve. A három vektor, az NMI, RESET és az IRQ rendre a következő: FFFA, FFFC, FFFE. Vektor betöltésekor tehát a felső 13 címbit 1, az alsó 3 pedig attól függ, milyen esemény van. Az alsó bit mindig 0, mely nem csak arra szolgál, hogy meghajtja a címkimenetet, hanem arra is, hogy jelzi, hogy interrupt végrehajtás van folyamatban. Az alábbi áramkör ezt a jelet, és annak óraciklusokkal késleltetettjeit használja fel arra, hogy óraciklusokat foglaljon le a kérés teljesítéséhez:

Részlet az interrupt logikából
13. ábra: Részlet az interrupt logikából

A fenti kapcsolásra ugyan látszólag csak az NMI-nek a Schmitt triggeres bemenete van közvetlenül rákötve, de IRQ és RESET esetében is ugyanúgy működik, hiszen a legalsó címbit mindhárom esetben 0, és ennek a jelnek az 1 és 2 óraciklussal késleltetett jelei meghajtják ezt a kapcsolást.

Regiszterblokk, utasításszámláló

8 bites processzoron belül egy 16 bites regiszter: két 8 bites darabban valósították meg, 2 óraciklus kell az értékadáshoz. Előnyös az olyan címzésmód, mely az úgynevezett nulláslapon dolgozik (a memória alsó 256 byte-ja), mert ekkor 1 óraciklus megtakarítható. Az utasításszámlálóval végzett leggyakoribb művelet a növelés, ehhez külön áramkör van beépítve, így nem kell igénybe venni az ALU-t, és a növelés a processzor többi területétől függetlenül zajlik. A tárolók olyan inverterpárok, melyek a növelőn keresztül vannak visszacsatolva: ha a carry 0, akkor az eredeti bit íródik vissza, ha 1, akkor az inverze.

Két darab tároló-összeadó
14. ábra: Két darab tároló-összeadó

A transzfer gate-ek jelentése a következő:

  • x1: írás a DATA1 sínre, ahonnan az adatlábakra és az ALU-ba kerülhet az IP egyik 8 bites fele
  • x2: IP értékadás ADDR1-ről (carry = 0 esetben)
  • x3: visszacsatolás
  • x4: írás ADDR1-re (ALU vagy a címkimenetek felé)
Negált logikájú 1 bites tároló-összeadó layoutja
15. ábra: Negált logikájú 1 bites tároló-összeadó layoutja

Stack pointer, X és Y indexregiszterek

Ezekben a regiszterekben a tárolás egy fázisjellel vezérelt transzfer gate-tel megszakított, keresztbe csatolt inverterpárral valósul meg. Cp1 alatt a parazita kapacitások feltöltése, Cp2 alatt visszacsatolás, az információ tartása történik. A stack pointer annyival tud többet X-nél és Y-nál, hogy értékét a címkimenetre is lehet írni.

1 bites tárolók kapcsolata a belső sínekkel
16. ábra: 1 bites tárolók kapcsolata a belső sínekkel
  • x1: Stack pointer írása ADDR2-re (és onnan címkimenetre)
  • x2, x5, x7: írás ADDR1-re (többi regiszter írása, vagy ALU bemenet)
  • x3, x4, x6: olvasás ADDR1-ről
1 bites S, X, Y tárolók layoutja
17. ábra: 1 bites S, X, Y tárolók layoutja

Akkumulátor, BCD korrekció

Az akkumulátor egy BCD korrekciós kapcsoláson keresztül kaphat értéket. (Binary Coded Decimal, ez egy olyan számábrázolás, melynél például a 33-as byte, a hexadecimális 21 értéke decimális 21-ként kerül feldolgozásra, tehát a byte 2 darab 4 bites fele tárol egy-egy decimális számjegyet.) Összeadásnál és kivonásnál kell korrigálni a kapott eredményt, mert az ALU bináris összeadást végez. Ekkor mindkét dekádot meg kell vizsgálni, hogy nagyobb-e 9-nél, és ha igen, hozzá kell adni 6-ot (így lesz a decimális 10-ből hexadecimális 10). Az alábbi korrekciós áramkör úgy végzi el az összeadást, hogy nem használ bitenként végigfutó carry-t, mert az lassú, 1 óraciklusba kerülő eljárás lenne, hanem az ALU logikai függvényeiből előre számítja az összeadás hatását. A kapcsolás jobb oldali oszlopa az összehasonlítást végzi, jobbról a második oszlop a 6-tal való növelést, amennyiben a dekád nagyobb 9-nél, és a BCD engedélyezett, bal oldalon pedig az 1 bites tárolók és összeadók láthatók.

4 bites BCD-korrekciós kapcsolás
18. ábra: 4 bites BCD-korrekciós kapcsolás

Aritmetikai és logikai egység

Az aritmetikai és logikai egység egy nagyon kompakt kapcsolás. A regiszterblokkban helyezkedik el, ugyanazokat a belső síneket használja, mint a regiszterek. Két bemenő operandusa van, a kapcsolási rajz jobb oldalán látható az az 5 transzfer gate, melyekkel kiválasztható, hogy a három sín, az egyik negáltja, valamint a 0 közül melyek kerüljenek a bemenetekre. Az ALU az aktuális utasítástól függetlenül előállítja az összes logikai függvényt, a carry-t, az összeget. Hogy ezek közül mi kerül a kimenetre, azt a transzfer gate-ek döntik el.

1 bit az ALU-ból
19. ábra: 1 bit az ALU-ból
  • Összeadás: x12-vel jut a kimenetre, ehhez carry is kell, mely váltott logikával halad végig a 8 biten.
  • Kivonás: a kivonandó inverzének hozzáadása, az alsó helyiértéken carry=1 kell.
  • Összehasonlítás: kivonás, csak x12 nem nyit.
  • Növelés: egyik bemenet 0, összeadás carry=1 beállításával.
  • AND, OR, EOR: x8, x6, x9 kapcsolók.
  • Bitléptetés jobbra: x7-tel jut a NAND kapu kimenete az eggyel kisebb helyiérték ALU-kimenetének negált vonalára. Ehhez az kell, hogy mindkét bemenet ugyanaz legyen (azaz az operandus két sínen is rendelkezésre álljon).
  • Bitléptetés balra: ez egy 2-vel való szorzás, ami összeadás két megegyező bemenetre.

A kész kapcsolási rajz

A rajzot igyekeztem a lehető legáttekinthetőbb formára hozni, ennek során néhány kompromisszumra kényszerültem:

  • A regiszterblokk kivételével a kapcsolásnak nincs sok köze a layout elrendezéséhez.
  • Nincs minden vezeték behúzva. A regiszterblokk soraiban a DATA1, DATA2, ADDR1, ADDR2 jelű belső sín minden regiszteren áthalad. Az Rdy0 negált jel nagyon sok helyen felhasználásra kerül, ezért csak jelölve van (az interrupt logika és a Sync, R/W jeleket előállító kapcsolás állítja be az értékét). A kapcsolás középső részén az ellenütemű inverterek kimenetei a regiszterblokk mind a 8 sorát keresztezik, x5, x12 stb. elnevezésük van. Minden regiszter alatt újra kezdődik a számozásuk!
  • A PLA sorai a layouton össze vannak keverve, a kapcsolási rajzon rendezve vannak.
A dolgozathoz mellékelt 1,5×1,5 méteres kapcsolási rajz kicsinyített változata (kattintásra a zoomolható változat nyílik meg)
20. ábra: A dolgozathoz mellékelt 1,5×1,5 méteres kapcsolási rajz kicsinyített változata (kattintásra a zoomolható változat nyílik meg)

Az Intel 80286-os

Vizsgálataim következő darabja ez az 1,2 mikronos technológiával készült típus, melyben kb. 110 ezer tranzisztor van, és szintén nMOS technológiával, kiürítéses terhelésekkel készült, mint a 6502. A layout felépítése lényeges különbségeket mutat a 6502-höz képest: jól struktúrált, számítógéppel tervezték, az ugyanazon működéshez tartozó kapcsolások egy blokkban vannak, a 16 bitre vonatkozó ismétlődések 16 ugyanolyan layoutcsoportot jelentenek, üres helyek is vannak, abszolút áttekinthető a struktúra.

Részlet egy 286-osból
21. ábra: Részlet egy 286-osból

A 6502-nél például az utasításregiszternek nem ugyanúgy néz ki mind a 8 bitje (és persze nem is sorban, hanem össze-vissza helyezkednek el), két bit áramköre a layout sarkában teljesen össze van zsúfolva, mert éppen ott volt hely. Ez a modernebb processzorok esetében nem egy járható út, mert egyrészt nem hatékony (újra le kell szimulálni a különböző kapcsolásokat, ahelyett, hogy egymás mellé rakosgatnák 8-szor, 16-szor), másrészt a layoutbeli különbségek működési sebességben és időzítésekben eltéréseket okozhatnak. Ez nagy órajel-frekvencián megengedhetetlen.

A 286-os layout másik szembetűnő tulajdonsága, hogy nagyon sok PLA-t tartalmaz, melyeket ROM-ként is lehet alkalmazni például utasításdekódolásra, ezen kívül NAND és NOR kapukból álló blokkokból a kimenetek bemenetre történő visszacsatolásával állapotgépet lehet létrehozni: a bemenetek és a bemenő, órajellel késleltetett előző állapotokból a PLA előállítja a szükséges logikai függvényeket, melyek a kimeneteket és a következő állapotokat állítják be. Ez egy kompakt, helytakarékos megoldás (mert rendezett struktúra: egy mátrix, melynek mezőiben az 1 bites információ attól függ, hogy van-e kontaktus vagy nincs). Egyszerű a tervezése is, viszont a nagy belső kapacitások miatt a kész áramkör lassú. A 80x86 család további tagjaiban a PLA-kat kiváltották kombinációs hálózatokkal. Ezek ugyan sokkal több helyet foglalnak el a szilíciumon, de a nagy sebességű működésnek ez az ára.

Típusjelzés a layouton. Alul és felül PLA-k.
22. ábra: Típusjelzés a layouton. Alul és felül PLA-k.

Lehetséges-e a 286-os teljes visszafejtése? A 6502-vel szerzett tapasztalatok alapján meg lehet becsülni a munka időigényét. A körülbelül 30-szor annyi tranzisztor egyáltalán nem jelent 30-szoros munkát: a szisztematikus tervezésnek köszönhetően a tranzisztorok felismerését követően nincs szükség a kapcsolás kibogozására, rendezésére, valamint a 16 bites processzorból fakadóan jóval több az ismétlődő kapcsolás. Ráadásul a layout 1/4 részét PLA-k teszik ki, az arány tranzisztorszámban mérve ennél még nagyobb. Ezek a körülmények lehetővé teszik, hogy egy gyakorlattal rendelkező 4-5 fős csoport néhány hónap alatt megfejtse. Kérdés persze, hogy van-e értelme: erre jó példa az Amiga esete, melyet a Commodore cég csődjét követően néhány éve fel akartak támasztani poraiból. A tervezett új típusnak kompatibilisnek kellett lennie az elődökkel, ám az egyik IC-nek a tervrajzai teljes egészében elvesztek. Visszafejtették...

Az ilyen szintű processzorok fejtése tehát lehetséges, bár természetesen nem lehet egységes, összefüggő kapcsolási rajzot produkálni a méretek és a nagy bonyolultság miatt.

Az x86 család további tagjai

A 386-ostól kezdve kizárólag CMOS technológiát használtak, tehát a kapcsolások n és p csatornás tranzisztorokat is tartalmaznak. A layout fejtését ez jelentősen megnehezíti, mert a kép alapján nem lehet egyértelműen megkülönböztetni a kettőt. Néhány támpont szerencsére van:

  • A CMOS kapcsolásokban többnyire komplementer p hálózatok vannak, azaz a kapuk felépítése olyan, hogy az n csatornás tranzisztorokból következtetni lehet a p-kre, mert azok bekötése az n-ek duálisa.
  • A p inverziós rétegnek kisebb a fajlagos vezetése, ezért a p csatornás tranzisztorok csatornaszélessége 2-szer, 3-szor nagyobb, mint egy ugyanakkora áramot adó n csatornásnak.
  • Ha egy tranzisztorról valamilyen módon kiderül, hogy n vagy p, akkor az összes, ugyanabban a zsebben található tranzisztor is ismert.
CMOS layout fotó [8]
23. ábra: CMOS layout fotó [8]
CMOS layout fotó [8]
24. ábra: CMOS layout fotó [8]

A fenti szabályok jól használhatók ugyan, de az egyértelműséget nem biztosítják. A CMOS-ra sokkal inkább igaz az, hogy csak akkor lehet fejteni, ha az ember érti is, hogy az adott áramkör hogyan működik. Bizonyos esetekben csak a működés megvizsgálásával dönthető el, hogy egy tranzisztor milyen típusú. Az nMOS-nál csak akkor van szükség ilyen módszerekre, ha a layoutfotó minősége rossz, vagy szennyeződések takarnak el alkatrészeket.

A 386-os az 1 mikronos csíkszélességgel még éppenhogy vizsgálható hagyományos optikai mikroszkópon. Az ennél kisebb méretek már összemérhetőek a fény hullámhosszával. Az újabb, még kisebb csíkszélességgel készült lapkák pásztázó elektronmikroszkóppal vagy pásztázó optikai mikroszkóppal vizsgálhatók. A PEM nem ad színinformációt, azaz az aktív zónák határa nem ismerhető fel a képen, önmagában nem használható. Szelektív maratást kell alkalmazni, amely az újabb áramköröknél egyébként is szükséges, például a többrétegű fémezés miatt. Az, hogy egy tranzisztorrétegről több síkban készül felvétel, nagyon komoly illesztési problémákat okoz. Elkerülhetetlen, hogy a különböző marási és mikroszkópozási fázisok között a szilícium szeletet ne mozgassák, és a szelet egyenetlensége, a tárgylemez nem tökéletes vízszintessége mindenképpen okoz elcsúszásokat. Ez pedig kritikus lehet, hiszen akár 1 mikron eltérés is több tranzisztornyi hibát okozhat. A pásztázó optikai mikroszkópia (Near Field Scanning Optical Microscopy) meglehetősen költséges, Magyarországon jelenleg nem elérhető eljárás. Lényege, hogy a vizsgálandó felületet egy olyan optikai szállal kell letapogatni, melynek kilépőnyílás-átmérője és a felülettől való távolsága is kisebb a fény hullámhosszánál.

Hagyományos módszerekkel tehát a 386-osig lehet eljutni, tehát körülbelül a 15 évvel ezelőtti technológia boncolható fel nagy költségráfordítás nélkül. Azonban ezek az áramkörök is vannak olyan bonyolultságúak, hogy a vizsgálatuk bőséges munkát ad annak, aki a megfejtésükkel próbálkozik: a 386-osban például 275 ezer tranzisztor van. Ilyen nagyságrendű alkatrészszám esetén legfeljebb a szoftveres layoutfejtés képzelhető el. Ennek lényege, hogy a layoutfotókat egy szoftver dolgozza fel, felismeri az ugyanolyan árnyalatú (működésű, anyagú) területeket, melyeket például egy gráffá képez le a területek szomszédossága és a kontaktusok helyzete alapján. Ebből kapcsolási rajzot is generálhat, bár ez a teljesen automatikus működés egy igen nehéz mesterséges intelligencia probléma lenne. A járható út minden bizonnyal a szoftverrel támogatott fejtés, tehát a gép által generált adatokat a kezelő személy rendezi kapcsolássá, figyelembe véve az áramkör működési sajátosságait is.

Irodalomjegyzék

  1. Dr. Mojzes Imre: Mikroelektronika és elektronikai technológia. Műszaki Könyvkiadó, 1995
  2. Dr. Kovács Ferenc: MOS integrált áramkörök. Műszaki Könyvkiadó, 1976
  3. Saufert János: Mikroprogramozás és mikroprocesszorok. KGTMT, 1977
  4. Simon Zoltán: Második generációs mikroprocesszorok felépítése és az Intel 8080, Motorola 6800, Signetics 2650 és a Fairchild F-8 rendszerre írt benchmark programok vizsgálata. HIKI, 1977
  5. Angerhausen–Brückmann–English–Gerits: A Commodore 64-es belső felépítése. Data Becker – Novotrade, 1985
  6. http://www.6502.org
  7. http://www.intel.com/intel/intelis/museum/exhibit/hist_micro/hof/hof_main.htm
  8. http://www.eet.bme.hu