[Перевод] Регистры процессора Intel 8086: от чипа к транзисторам
Intel 8086 — один из самых влиятельных из когда-либо созданных компьютерных чипов. Он создал архитектуру x86, доминирующую в современных настольных и серверных компьютерах. Я занимался реверс-инжинирингом 8086 на основе фотографий кристаллов, и в данной статье я опишу реализацию регистрового файла (набора регистров).
Кристалл 8086. Отмечено место хранения регистров. Верхние регистры используются блоком интерфейса шины для доступа к памяти, а нижние регистры общего назначения используются исполнительным блоком. Буфер команд — это 6-байтная очередь, состоящая из заранее запрошенных команд.
На фото дано изображение процессора 8086 под микроскопом. Виден металлический слой сверху чипа, под которым прячется кремний. Расположенные по внешнему краю соединительные провода соединяют площадки на кристалле с 40 внешними контактами чипа.
Рамкой обведены пятнадцать 16-битовых регистров 8086 и шесть байтов очереди предварительного запроса команд (предвыборки кода). Регистры занимают значительную часть кристалла, хотя в сумме их наберётся всего на 36 байт. Из-за ограничений по площади у первых микропроцессоров было относительно небольшое количество регистров. Для сравнения, у современных чипов процессоров есть килобайты регистров и мегабайты кэшей.
8086 был одним из самых ранних микропроцессоров, реализовавших предвыборку кода, однако у Motorola 68000 (1979) немного раньше появился буфер предвыборки на 4 байта. В мейнфреймах предвыборка существовала у IBM Stretch (1961), CDC 6600 (1964) и IBM System/360 Model 91 (1966).
Количество регистров у современного процессора подсчитать сложно. Единственное точное число, найденное мною, содержалось в книге «Анатомия высокоскоростного микропроцессора» (1997), подробно описывающей процессор AMD K6. Из-за переименования регистров у современных процессоров физических регистров гораздо больше, чем архитектурных (тех, что видны программисту), а количество физических регистров в документации не указывается. У K6, кроме восьми регистров ч86 общего назначения, было 16 микроархитектурных рабочих регистров для переименования.
У процессоров с поддержкой AVX-512 есть 32 512-битовых регистра, то есть для одной этой функции зарезервировано 2 кБ регистров. В таких случаях размер регистров подсчитать ещё сложнее. Что до размера кэша, то у передовых процессоров его объём доходит до 77 МБ.
Как регистры реализуются в кремнии
Начну с описания того, как 8086 создаётся из N-МОП транзисторов. Затем объясню, как делается инвертор, как при помощи инверторов хранятся одиночные биты, и как делается регистр.
8086, как и другие чипы той эпохи, создавались на основе транзисторов типа N-МОП. Эти чипы состояли из кремниевой подложки, в которую при помощи диффузии внедряли примеси из мышьяка или бора, формировавшие транзисторы. Находящиеся над кремнием проводники из поликремния формировали вентили транзисторов и соединяли все компоненты друг с другом. Находившийся ещё выше металлический слой содержал дополнительные проводники. Для сравнения, современные процессоры используют технологию КМОП, комбинирующую N-МОП и P-МОП транзисторы, и содержат множество металлических слоёв.
На схеме ниже показан инвертор, состоящий из N-МОП транзистора и резистора. При низком входном напряжении транзистор выключен, поэтому подтягивающий резистор подтягивает выход вверх. При высоком входном напряжении транзистор включается, соединяет землю и выход, подтягивая выход вниз. Таким образом входящий сигнал инвертируется.
На самом деле, подтягивающий резистор в вентиле N-МОП представляет собой транзистор особого рода. Работающий в режиме обеднения транзистор ведёт себя, как резистор, будучи при этом более компактным и эффективным.
На схеме показано, как из транзистора и резистора получается инвертор. На фото показана реализация на чипе. Металлический слой удалён, чтобы было видно кремний и поликремний.
На фото выше видно, как физически сделан инвертор у 8086. Розоватые участки — это кремний с примесями, делающими его токопроводящим, а линии медного цвета — это поликремний сверху. Транзистор появляется там, где поликремний пересекается с кремнием. Поликремний формирует вентиль транзистора, а участки кремния с двух сторон дают исток и сток. Большой прямоугольник поликремния формирует подтягивающий резистор между +5 В и выходом. Таким образом, схема чипа совпадает со схемой инвертора. Подобные цепи можно рассмотреть под микроскопом и подвергнуть реверс-инжинирингу.
Строительный блок регистра — два инвертора в цепи обратной связи, хранящих один бит (см. ниже). Если на верхнем проводнике 0, правый инвертор выдаст 1 на нижний проводник. Затем левый инвертор выдаст 0 на верхний проводник, завершая цикл. Таким образом цепь оказывается стабильной и «помнит» 0. И наоборот, если на верхнем проводнике 1, она превратится в 0 на нижнем проводнике, и обратно в 1 на верхнем. В итоге цепь может хранить 0 или 1, формируя однобитную память.
У 8086 два спаренных инвертора хранят в регистре один бит. Схема стабильно находится в состоянии 0 или 1.
К паре инверторов добавляются три транзистора, чтобы получилась пригодная для использования ячейка регистра. Один транзистор выбирает ячейку для чтения, второй выбирает ячейку для записи, третий усиливает сигнал при чтении. В центре схемы ниже два инвертора хранят бит. Для чтения бита ток подаётся на красную шину. Это соединяет выход инвертора с разрядной шиной через усиливающий транзистор. Для записи бита ток подаётся на красную шину, соединяющую разрядную шину с инверторами. Подавая высокотоковые сигналы 0 или 1 на разрядную шину (и, соответственно, на хранящийся бит), мы заставляем инверторы переключаться на нужное значение. Отметьте, что разрядная шина используется и для чтения, и для записи.
В других процессорах используются несколько другие ячейки для хранения регистров. 6502 использует дополнительный транзистор в цепи обратной связи инвертора, чтобы разбивать цепь при записи нового значения. Z80 пишет одновременно в оба инвертора, что «облегчает» изменение, однако требует наличия двух проводников для записи. У 8086 есть усиливающий транзистор в каждой ячейке регистра для чтения, а другие процессоры считывают выходной сигнал с обоих инверторов и используют внешний дифференциальный усилитель для усиления сигнала. Базовая ячейка регистра 8086 состоит из 7 транзисторов (7Т), что больше, чем в типичной статичной ячейке RAM, использующей 6 или 4 транзистора, однако она использует только одну разрядную шину, а не две разных. Динамическая память (DRAM) работает гораздо эффективнее, и использует один транзистор и конденсатор, однако без обновления данных они будут утеряны.
Принципиальная схема хранящей бит ячейки регистра. Регистровый файл делается из массива таких ячеек.
Регистровый файл состоит из матрицы ячеек регистров, подобных описанному выше. Ширина матрицы составляет 16 ячеек, поскольку в регистрах хранятся 16-битные значения. Каждый регистр расположен по горизонтали, поэтому шина чтения или записи выбирает все ячейки определённого регистра. 16 вертикальных разрядных шин формируют единую шину, поэтому все 16 битов в выбранном регистре читаются и записываются параллельно.
На фото ниже показан увеличенный регистровый файл 8086 общего назначения, и видна матрица регистровых ячеек: 16 столбцов и 8 строк, 8 16-битных регистров. Затем дано увеличение одной регистровой ячейки в файле. Объясню, как реализована эта ячейка.
Фото кристалла 8086 с увеличением нижнего регистрового файла (восьми 16-битовых регистров), а потом и отдельной регистровой ячейки. Чтобы было видно кремниевые структуры, металлический и поликремниевый слои удалены.
8086 делается из кремния с примесями и поликремниевых проводников с металлическими проводниками сверху. На левом фото ниже показаны вертикальные металлические проводники регистровой ячейки. Отмечены земля, питание и проводники разрядной шины (оставшийся проводник пересекает регистровый файл, но не контачит с ним). На фото справа металлический слой растворён, чтобы было видно поликремний и кремний. Шины чтения и записи — это горизонтальные поликремниевые проводники. Поскольку у чипа только один металлический слой, в регистрах для вертикальных шин используется металл, а для горизонтальных — поликремний, чтобы они не пересекались друг с другом). Сквозные соединения металла и кремния видны как более яркие круги на фото с металлом и как кружки на фото с кремнием.
Ячейка хранения регистра. На фото слева показан металлический слой, а справа — соответствующие слои поликремния и кремния.
На диаграмме ниже показано соответствие физической схемы регистровой ячейки с принципиальной. Инверторы состоят из транзистора А и В и регистров. Транзисторы C, D и E формируются отмеченными кусочками поликремния. Разрядная шина не видна, поскольку располагается в металлическом слое. Отметьте, что схема ячейки памяти сильно оптимизирована для минимизации размера. Также отметьте, что транзистор А гораздо меньше других. У инвертора А довольно слабый выходной ток, поэтому РГ может преодолеть его при записи.
Регистровая ячейка от 8086 с соответствующей схемой
Поддержка 8-битных регистров
Если тщательно изучить кристалл, видно, что некоторые регистровые ячейки имеют немного другую структуру. Слева расположена регистровая ячейка, которую мы уже обсудили, а справа — пара регистровых ячеек с двумя шинами записи вместо одной. На левом фото шина записи пересекает кремний в обеих регистровых ячейках. На правом фото шина «правой записи» пересекает кремний в правой части, однако проходит между участками кремния в левой. И наоборот, шина «левой записи» пересекает кремний с левой стороны и проходит между участками кремния справа. Таким образом, одна шина управляет записью правого бита, а другая — левого. В 16-битном регистре таким образом можно отдельно записывать перемежающиеся 8-битные части.
Регистровая ячейка на кристалле повторяются не единообразно — каждая вторая ячейка является зеркальным отражением предыдущей. Это увеличивает плотность регистровой ячейки — шина питания, идущая между двумя зеркальными ячейками, может питать их обе (то же касается и земли). Зеркальные повторения уменьшают количество требуемых шин питания и земли в два раза.
Хотя на блок-схемах обычно нарисовано, как 16-битные регистры делятся на левую и правую половины, в реальном исполнении биты с каждой из сторон чередуются, вместо того, чтобы всегда хранить первую 8-битовую часть слева, а вторую — справа. Такая реализация упрощает иногда возникающую задачу перемены местами двух половин 16-битного слова. Один из таких случаев — чтение или запись памяти без выравнивания. Другой — операция АЛУ, использующая верхнюю часть регистра — например, АН. Для перемены местами битов между правой и левой половинами потребовалось бы тянуть длинные проводники между всеми битами половин слов. Однако при чередующемся расположении для перемены местами двух половин слова требуется поменять местами каждую пару соседних битов, для чего длинные проводники не нужны. Иначе говоря, чередующееся расположение регистров 8086 облегчает задачу расположения проводников для перемены местами двух половин слова.
Две пары ячеек памяти с разными цепями. У ячеек слева одна шина записи, а справа — отдельные шины записи для левых и правых битов.
Почему у некоторых регистров две шины записи, а других — одна? Причина в том, что у 8086 16-битные регистры, однако к четырём из них можно обращаться и как к 8-битным, как показано ниже. К примеру к 16-битному аккумулятору А можно обращаться как к 8-битному AH (старшая часть аккумулятора) и 8-битному AL (младшая часть) регистрам. Реализация регистров с двумя шинами контроля записи позволяет вести запись в каждую половину регистра отдельно.
Если бы регистровый файл поддерживал только 16-битные регистры вместо 8-битных, процессор мог бы работать, но менее эффективно. Записи в 8-битные половины производились бы путём чтения всех 16 бит, изменения 8-битной половины и записи всех 16 бит. В результате вместо доступа к одному регистру обращение шло бы к трём. При этом регистровому файлу не нужно как-то особо поддерживать чтение 8 бит, поскольку ненужную половину можно просто игнорировать.
Регистры общего назначения в процессоре 8086. Регистры A, B, C и D можно делить на две 8-битных половины.
Многопортовые регистры
Пока что мы рассмотрели восемь «нижних регистров» общего назначения. У 8086 есть также семь «верхних регистров», используемых для доступа к памяти, включая печально известные сегментные регистры. У этих регистров схема работы более сложная, многопортовая, позволяющая одновременно вести несколько процессов чтения и записи. К примеру, многопортовый регистровый файл позволяет прочесть счётчик программы, сегментный регистр и записать другой сегментный регистр — и всё это одновременно.
Приведённая ниже блок-схема отличается от большинства блок-схем для 8086, поскольку показывает реальную физическую реализацию процессора, а не ту, что представляет себе программист. В частности, на диаграмме показано два «регистра внутренних коммуникаций» среди регистров модуля интерфейса шины (справа) вместе с сегментными регистрами, совпадающими с 7 регистрами, которые можно рассмотреть на кристалле. Временные регистры, показанные ниже, физически являются частью АЛУ, поэтому в данной статье я их не рассматриваю.
В книжке «Разработка современных процессоров» обсуждаются сложные системы регистров в процессоре, начиная с 2000-х годов. Там написано, что сложность цепей быстро выходит за рамки трёх портов, а в некоторых передовых процессорах существуют регистровые файлы с 20 или более портами.
Многопортовая регистровая ячейка ниже создана на основе той же схемы из двух инверторов, однако у неё есть три разрядных шины (а не одна, как в предыдущем случае) и пять управляющих шин (вместо двух). Три шины чтения позволяют читать содержимое регистровой ячейки по любой из трёх разрядных шин, а две шины записи позволяют разрядной шине А или С вести запись в регистровую ячейку.
Многопортовая регистровая ячейка в процессоре 8086
На первый взгляд, регистровый файл 8086 выглядит как однородный набор регистров, однако при тщательном рассмотрении видно, что каждый регистр оптимизирован в зависимости от его функции. Некоторые из них — простые 16-битные регистры, и расположены наиболее компактно. К другим 16-битным регистрам можно обращаться как к двум 8-битным, что требует ещё одной управляющей шины. У наиболее сложных регистров есть два-три порта для чтения и один-два для записи. В каждом случае физическая реализация регистровой ячейки тщательно разработана так, чтобы занимать как можно меньше места, в связи с чем форма транзисторов часто получается сложной. Инженеры Intel сжимали схему расположения регистров как можно сильнее, чтобы уместить их все на доступной им площади.
У верхних регистров есть разное количество портов для чтения и записи: два регистра с 3 шинами чтения и 2 шинами записи, один регистр с 2 шинами чтения и 2 шинами записи, четыре регистра с 2 шинами чтения и 1 шиной записи. Три первых регистра — это, вероятно, счётчик программы, непрямой временный регистр и временный регистр операнда. Последние четыре — вероятно, сегментные регистры SS, DS, SS и ES. Также там есть три регистра буфера предварительной выборки команд, каждый с одной шиной для чтения и одной для записи.
Процессор 8088, использовавшийся в оригинальных компьютерах IBM PC, был практически идентичен 8086, кроме того, что у него была 8-битная внешняя шина вместо 16-битной — так стоимость системы получалась меньше. Размер буфера предварительной выборки у 8088 был 4 байта вместо 6 — вероятно, потому, что 4-х байт было достаточно для более медленной шины памяти 8088-го.
В отличие от 8086, регистры предварительной выборки у 8088 поддерживают независимую запись в 8-битные половинки (похоже на регистры A, B, C и D 8088-го, только эти ячейки выглядят по-другому). Всё потому, что 8088 запрашивал команды по одному байту за раз, а не по одному слову, из-за узкой шины. Поэтому регистры предварительной выборки должны поддерживать побайтовую запись, в то время, как 8086-й поддерживает предварительную выборку по словам.
Файл верхних регистров, состоящий из десяти 16-битных регистров. На фото видно кремний и поликремний. Вертикальные красные линии — остатки удалённого металлического слоя. Кликабельно.
Заключение
Хотя 8086 процессору уже 42 года, он до сих пор оказывает значительное влияние на современные компьютеры, поскольку архитектура х86 до сих пор очень часто используется. Регистры 8086 до сих пор существуют в современных компьютерах х86, хотя сегодня они уже имеют длину в 64 бита, а кроме этих регистров существует и множество других.
Кристалл 8086-го очень интересно изучать, поскольку его транзисторы можно рассмотреть под микроскопом. В своё время это был сложный процессор, поскольку на нём расположено 29 000 транзисторов, однако достаточно простой для того, чтобы отследить все цепи и понять, как они работают.