Оригиналът е на Ken Shirriff, изключително популярен специалист, познат с интересните си статии в своя официален блог.
През 1980 година Intel представи чипа 8087 за ускорение обработката на числата с плаваща запетая за процесорите 8086, които по това време се използваха в в оригиналните IBM PC. Тъй като първите процесори работеха само с цели числа, аритметиката с плаваща запетая бе много бавна, а с трансцендентните функции от рода на арктангенс и логаритми нещата бяха много по-зле. Добавянето на копроцесора 8087 към компютърната система от това време ускоряваше математическите операции с плаваща запетая до 100 пъти.
Аз отворих един чип 8087 и направих няколко снимки с помощта на микроскоп. На фотографията по-долу е показан малкият кристал на този копроцесор. На всичките му страни се виждат малките проводници, които осъществяват съединенията с неговите външни 40 крачета. Различните основни функционални блокове на чипа отбелязвах след като направих реверсивно инженерство на този копроцесор. Ако внимателно изучим този чип, то от неговата интегрирана ROM памет можем да извлечем различните използвани константи, като например числото π, които се използват по време на изчисленията.

В горната половина на чипа се намира управляващата логика. За изпълнението на една инструкция с плаваща запетая може да са необходими до 1000 стъпки, като за описването на тези стъпки в 8087 се използва микрокод. На снимката е показан функционалният енджин, който изпълнява програмата на микрокода и на практика това е еди опростен CPU. Точно до него се намира доста големият ROM блок, в който е записан микрокодът.
В долната част на кристала се намира модулът, обработващ числата с плаваща запетая. Всяко число с плаваща запетая се състои от дробна част (мантиса), експонента и еди бит за знака на числото. В десетичния вид на числото 6,02×1023 – 6,02 е мантисата, а 23 е експонентата, В този чип отделните модули паралелно извършват изчисленията на мантисата и на експонентата. Схемата за обработка на мантисата поддържа 67-битови значения – 64-битова мантиса и три допълнителни бита за точността. Отляво надясно схемата за работа с мантисата включва ROM с необходимите константи, преместващ регистър, суматор и стек с регистри. Тук ще разгледаме оцветеният в зелено блок с постоянна памет на чипа.
Чипът 8087 работи като копроцесор към процесора 8086. Когато 8086 се сблъска със специална инструкция, която се отнася към числата с плаваща запетая, той игнорира тази команда и дава възможност тя да бъде паралелно изпълнена от копроцесора. Взаимодействането между 8086 и 8087 е направено по много оригинален начин. Опростено казано, 8087 наблюдава потока инструкции за 8086 и извършва инструкциите предназначени за 8087. Сложното тук е, че 8086 има буфер за изпреварващо изпълнение на инструкциите и често се случва инструкцията, която в момента получава 8086 да не съвпада с инструкцията, която се изпълнява. Ето защо 8087 дублира този буфер (както и по-малкия буфер на 8088), за да знае с какво е зает процесорът 8086
Реализацията на постоянната памет
Ние ще се спрем върху ROM, където са записани необходимите константи за специализираните изчисления. Тази памет не бива да се бърка с с голямата ROM, където са записани микрокодовете. А за записа на микрокода се използва доста необичайна технология за запис на два бита с един транзистор. Това става с помощта на транзистори с три различни размери или с отсъствието на транзистор на всяка позиция. Тези четири варианта кодират два бита. Тази сложна технология е необходима за да събере големият ROM кристал в копроцесора.
Постоянната памет за константите използва стандартни математически похвати със съхранението на важните константи включително π, ln(2) и √2, които са необходими за изчисленията на 8087. На снимката по-долу в показна именно ROM паметта с константите. За да може да се вижда самия кристал, от него е премахнат горният метален слой. Розовите участъци са силиций с примеси, които му придават различни свойства. Червеникавите и зеленикавите линии са полисилиций – специален тип на силициевото опроводяване, което се извършва в горната част на силициевия кристал. Обърнете внимание, че ROM структурата прилича на правилна решетка. Самият ROM се състои от две колони транзистори, в които са запомнени битовете. За да разберем начина на работа на този ROM, нека се спрем върху начина на работа на полевия транзистор.

Интегралните схеми с висока плътност от 1979-те години се правеха от N-MOS транзистори (в съвременните компютърни чипове се използват CMOS двойки, съставени от N-MOS и P-MOS транзистори). Малко по-долу е показана структурата на N-MOS транзистора. Чипът има силициева подложка, върху която се създават самите транзистори. В някои участъци на силиция са добавени примеси, които създават дифузни зони с необходимите електрически свойства. В този случай транзисторът може да се счита за превключвател, който позволява на тока да тече между двата дифузионни участъка с имена сорс и дрейн. Управлението на транзистора става чрез гейта, направен от полисилиций. Подаването на напрежение на гейта позволява протичането на ток между сорса и дрейна. Ако на гейта няма напрежение, токът не преминава. Кристалът на 8087 е сравнително сложен за своето време и включва около 40 000 от тези транзистори.
Ако увеличим още повече мащаба, можем да разгледаме различните транзистори в ROM-а. Розовите участъци са силиций с примеси, формиращи сорса и дрейна. Вертикалните шини [select lines] са направени от полисилиций и формират гейтовете. Отбелязаните с ярки цветове силициеви области са съединенията на едната страна на полевия транзистор с общия проводник. Кръгчетата са VIA – проходното съединяване между силиция и металните шини. Но за да се получи тази снимка, цялата метализация е премахната, като за да се разбере какво е било разположението на една от тях, тя е показана като оранжева линия.

Важна особеност на тази постоянна памет е липсата на някои транзистори, което е отбелязано с Х. Битовете се програмират чрез добавяне на примеси в силиция, които създават транзистори или изолирани участъци. Всеки наличен или отсъстващ транзистор означава един информационен бит. Самите битове са зададени твърди при производството и повече не могат да се променят.
Съдържанието на ROM-а
Постоянната памет с константите се състои от 143 реда и 21 колони. Тя включва 134 реда с по 21 бита, освен отделното късче от 6х6 транзистори горе вляво. Ето защо физическият размер на ROM-а с константите в 2946 бита.
Тази секция на ROM-а показва, че първите 12 константи са 64-битови, а не 67-битови. Това са константи, които нямат отношение към CORDIC и при тях не е необходима допълнителна точност.
Под микроскоп добре се вижда схемата на битовете на ROM-а и е сравнително лесно тя да бъде извлечена оттам. Но въобще не е очевидно, че тези битове след това ще трябва по някакъв начин да се интерпретират. Първо, какво означава наличието на транзистор – 0 или 1 (по-късно се оказа, че наличието на транзистор означава 1). Второ – как да се преобразува мрежата от 134х21 бита в значения.
Предположих, че 134-те реда на ROM-а съответстват на два комплекта 67-битови константи. Аз извлякох единия комплект от нечетните редове и другия – от четните, но получените значения нямаха никакъв смисъл. След като помислих още малко се досетих, че редовете не са поредни, а се редуват чрез ABBA повторения.
Редовете са подредени като ABBAABBAABBA…, където в редовете А се съдържат битовете на единия комплект константи, в В редовете – за другия. Тази схема се използва вместо обикновената АВАВ поредица навярно защото в този случай един контакт може да управлява два съседни транзистора. Тоест, един проводник може да избира всяка една от групите АА и ВВ.
По този начин получих редица познати константи. На снимката по-долу логическата 1 е във вид на зелена линия, а логическата 0 е червеникава. В двоичната система π изглежда като 11,001001… и именно това значение се вижда в горния ред на отбелязаните от мен битове. В долната част на снимката е записана константата 1.

Следващата сложност в интерпретацията е в това, че в ROM-а се съхраняват само мантисите, но не и експонентите. Не намерих отделен ROM с експоненти. Някои от тях станаха ясни веднага: така например, константата 1,204120 е log10 (2) с използването на експонентата 2-2. Но да се разберат останалите бе по-сложно, като например 1,734723. В крайна сметка разбрах, че 1,734723×259 = 1018. За какво му е на 8087 подобна константа? Може би защото 8087 поддържа пакетиран двоично десетичен код с 18 знака.
Някои експоненти бе твърде трудно да бъдат намерени и използвах метода на пробите и грешките, за да видя, дали това не е някой логаритъм или степен на някое число. Най-сложно се оказа определянето на константата за ln(2)/3. Не знам защо е токова важно това число.
Ето го и пълният списък на всички константи от ROM-а. Колоната „Смисъл“ е моето описание на съответната константа.
| Константи | Десетично значение | Смисъл |
|---|---|---|
| 1.204120×2-2 | 0.3010300 | log10 (2) |
| 1.386294×2-1 | 0.6931472 | ln(2) |
| 1.442695×20 | 1.426950 | log2 (e) |
| 1.570796×21 | 3.1415927 | π |
| 1.000000×20 | 1.000000 | 1 |
| 1.660964×21 | 3.219281 | log2 (10) |
| 1.734723×259 | 1.00e+18 | 1018 |
| 1.734723×259 | 1.00e+18 | 1018 |
| 1.848392×2-3 | 0.2310491 | ln(2)/3 |
| 1.082021×22 | 4.280851 | 3*log2(e) |
| 1.442695×20 | 1.426950 | log2 (e) |
| 1.414214×20 | 1.4142136 | √2 |
| 1.570796×2-1 | 0.7853982 | atan(20) |
| 1.854590×2-2 | 0.4636476 | atan(2-1) |
| 2.000000×2-15 | 0.0000610 | atan(2-14) |
| 2.000000×2-16 | 0.0000305 | atan(2-15) |
| 1.959829×2-3 | 0.2449787 | atan(2-2) |
| 1.989680×2-4 | 0.1243550 | atan(2-3) |
| 2.000000×2-13 | 0.0002441 | atan(2-12) |
| 2.000000×2-14 | 0.0001221 | atan(2-13) |
| 1.997402×2-5 | 0.0624188 | atan(2-4) |
| 1.999349×2-6 | 0.0312398 | atan(2-5) |
| 1.999999×2-11 | 0.0009766 | atan(2-10) |
| 2.000000×2-12 | 0.0004883 | atan(2-11) |
| 1.999837×2-7 | 0.0156237 | atan(2-6) |
| 1.999959×2-8 | 0.0078123 | atan(2-7) |
| 1.999990×2-9 | 0.0039062 | atan(2-8) |
| 1.999997×2-10 | 0.0019531 | atan(2-9) |
| 1.441288×2-9 | 0.0028150 | log2(1+2-9) |
| 1.439885×2-8 | 0.0056245 | log2(1+2-8) |
| 1.437089×2-7 | 0.0112273 | log2(1+2-7) |
| 1.431540×2-6 | 0.0223678 | log2(1+2-6) |
| 1.442343×2-11 | 0.0007043 | log2(1+2-11) |
| 1.441991×2-10 | 0.0014082 | log2(1+2-10) |
| 1.420612×2-5 | 0.0443941 | log2(1+2-5) |
| 1.399405×2-4 | 0.0874628 | log2(1+2-4) |
| 1.442607×2-13 | 0.0001761 | log2(1+2-13) |
| 1.442519×2-12 | 0.0003522 | log2(1+2-12) |
| 1.359400×2-3 | 0.1699250 | log2(1+2-3) |
| 1.287712×2-2 | 0.3219281 | log2(1+2-2) |
| 1.442673×2-15 | 0.0000440 | log2(1+2-15) |
| 1.442651×2-14 | 0.0000881 | log2(1+2-14) |
Не знам защо 1018 се повтаря, може би има някаква разлика в експонетата.
Физически константите са разположени в три групи. Първата група са константите, които потребителят може да взема от копроцесора (1, π, log210, log2e, log102, и ln), както и значеният за вътрешно ползване (1018, ln(2)/3, 3*log2(e), log2(e) и √2. Втората група се състои от 160те константи на арктангенса, а третата от 14-те константни за log2.
Копроцесорът 8087 има седем инструкции за директното зареждане на константите. Това са инструкциите FDLZ, FLD1, FLDPI, FLD2T, FLD2E, FLDLG2 и FLDLN2, които зареждат в стека съответно константите 0, 1, π, log210, log2e, log102 и ln 2. Всички тези константно, освен 0, са записани в ROM-а.
Последните две групи се използват за пресмятането на трансцендентните функции чрез CORDIC алгоритмите.
CORDIC алгоритмите
По самите константи в ROM-а могат да се разберат редица подробности за алгоритмите, използвани в 8087. В постоянната памет са записани 16 значения за арктангенса – арктангенсите от 2-n.
Тези значения изглеждат необичайни, но се използват в CORDIC алгоритъма измислен през 1958 година. Идеята е да се използват единствено събиране и побитови операции, за което са необходими междинни константи.
Заключение
Копроцесорът 8087 е сложен чип и на пръв поглед изглежда като безнадеждно объркан лабиринт. Но неговата работа може да се разбере чрез внимателно изучаване. В неговата постоянна памет са записани 42 константи, които могат да бъдат прочетени с помощта на микроскоп. Някои константи като π са съвсем очаквани, но други като ln(2)/3 повдигат много въпроси. Много от тези константи се използват за бързото изчисление на тангенси, арктангенси, логаритми и степени с помощта на CORDIC алгоритмите.
Въпреки че Intel 8087 за работа с плаваща запетая бе представен пред 40 години, неговото влияние се усеща и до днес. Той породи IEEE 754 стандарта за работа с числа с плаваща запетая, използван при почти всички машинни изчисления. А инструкциите на 8087 си останаха част от х86 процесорите използвани в повечето компютърни системи.
Всичко важно от света на технологиите, директно в пощата ти.
С абонирането приемате нашите Условия и Политика за поверителност. Може да се отпишете с един клик по всяко време.
Коментирайте статията в нашите Форуми. За да научите първи най-важното, харесайте страницата ни във Facebook, и ни последвайте в Google Новини, TikTok, Telegram и Viber или изтеглете приложението на Kaldata.com за Android, iPhone, Huawei, Google Chrome, Microsoft Edge и Opera!



















