Триггеры-защёлки: реверс-инжиниринг регистра команд в Intel 8086
Микропроцессор Intel 8086 – один из самых влиятельных чипов. Порождённая им архитектура х86 и по сей день доминирует среди настольных и серверных компьютеров. И всё же этот чип ещё достаточно прост для того, чтобы его цепи можно было изучать под микроскопом и разбираться в них. В этой статье я объясню реализацию динамической защёлки [одноступенчатый триггер] – схемы, удерживающей один бит. В 8086 есть более 80 защёлок, разбросанных по всему чипу, и удерживающих различные важные биты статуса процессора, но я сконцентрируюсь на восьми из них, реализующих регистр команд и хранящих выполняющуюся команду.
У 8086-го есть более 80 защёлок. Некоторые из них хранят значения контактов AD (address/data) или управляющих контактов. Другие хранят текущий адрес микрокода и микрокоманды, а также адрес возврата из подпрограммы микрокода. В третьих хранятся биты исходного и выходного регистра команд, и АЛУ-операция команды. Во многих хранятся статусы внутреннего состояния, в которых я пока ещё разбираюсь.
Кристалл 86, где показан 8-битный регистр команд
На фото выше показан кремниевый кристалл процессора 8086 под микроскопом. Я удалил металлический и поликремниевый слои, чтобы было видно транзисторы – всего их порядка 29 000 штук. На выделенном участке располагается 8-битный буфер команд, состоящий из восьми защёлок. Этот процессор 1978 года был ещё достаточно простым для того, чтобы единственный 8-битный регистр занимал на нём относительно большую площадь. На увеличении показаны кремний и транзисторы, из которых состоит единственная защёлка.
Как работает динамическая защёлка
Защёлка – один их важнейших элементов 8086, поскольку защёлки отслеживают то, чем занят процессор. Защёлки можно делать разными способами; в 8086 используется компактная цепь, известная, как динамическая защёлка. Динамическая защёлка зависит от работы двухфазного генератора тактовых импульсов, который часто использовался для управления микропроцессорами той эпохи. Двухфазный генератор тактовых импульсов выдаёт два тактовых сигнала, активных по очереди. В первой фазе основной тактовый сигнал высокий, а сопутствующий тактовый сигнал – низкий. Потом они меняются местами. Цикл повторяется на тактовой частоте, к примеру, 5 МГц.
Многие микропроцессоры используют логические элементы И-НЕ (NAND gates) для формирования RS-триггеров. RS-триггер обычно занимает больше места, чем динамическая защёлка, особенно если к нему добавляются дополнительные цепи для поддержки тактовой частоты. Также популярны D-триггеры (триггеры задержки), однако они получаются ещё более сложными и используют шесть затворов. Во многих случаях достаточно проходного транзистора; он может хранить значение в течение одного такта, но длительного хранения не обеспечивает.
Для процессоров всегда выбирают максимально возможную тактовую частоту. Первый 8086 работал на частоте до 5 МГц, а позже 8086-1 поддерживал уже до 10 МГц. Однако из-за использования динамической логики у 8086 есть ещё и минимальная тактовая частота: 2 МГц. Если генератор тактовых импульсов будет работать медленнее, появится риск утечки заряда с проводников до того, как схемы обратятся к нему, что приведёт к ошибкам.
Защёлка в процессоре 8086 состоит из четырёх проходных транзисторов и двух инверторов. Защёлка работает на перемежающихся тактовых сигналах.
На схеме выше показана типичная защёлка в 8086. Она состоит из двух инверторов и несколько проходных транзисторов. Для наших целей проходной транзистор можно считать выключателем: если на затвор приходит 1, транзистор передаёт сигнал далее. Если приходит 0, транзистор блокирует сигнал. Проходной транзистор управляются несколькими сигналами: загрузка (load), загружающий бит в защёлку; удержание (hold), удерживающий имеющееся значение бита; тактовый сигнал (clock) первой фазы и тактовый сигнал второй, инвертированной.
На диаграмме ниже показано, как в защёлку загружается значение (в данном случае, это 1). Для сигнала загрузки повышается напряжение, что позволяет входному сигналу (1) пройти через транзистор. Поскольку тактовый сигнал высокий, сигнал проходит через второй транзистор к инвертору, который выдаёт 0. В этот момент третий (тактовый) транзистор блокирует сигнал.
Входной сигнал загружается в защёлку при высоком уровне сигнала загрузки
В следующей тактовой фазе сигнал генератора тактовых импульсов становится высоким, благодаря чему сигнал 0 достигает второго инвертора, который выдаёт 1. Поскольку сигнал «удержание» высокий, сигнал возвращается назад, но блокируется транзистором генератора тактовых импульсов. Динамическим эту цепь делает то, что в данный момент на первый инвертор не поступает входящих сигналов. Его вход остаётся 1 (показано серым) из-за имеющейся у цепи ёмкости. Когда-нибудь этот заряд утечёт, значение потеряется, но до этого момента произойдёт новое переключение генератора тактовых импульсов.
Когда сигнал генератора тактовых импульсов становится высоким, значение проходит через второй инвертор. Вход на первый инвертор (серый) поддерживается благодаря ёмкости цепи.
После переключения состояния генератора тактовых импульсов вход на второй инвертор обеспечит ёмкость цепи (см. ниже). Сигнал возвращается назад, перезаряжая и обновляя вход на первый инвертор. При последующих переключениях тактовой частоты защёлка будет переключаться между этой и предыдущей диаграммой, сохраняя хранящееся в ней значение и поддерживая выходной сигнал в стабильном состоянии.
Ключом к работе защёлки служит наличие двух инверторов, поддерживающих выходной сигнал в стабильном состоянии. Нечётное количество инверторов вызвало бы осцилляции – эта особенность используется генератором подкачки заряда 8086. Также пары инверторов использует набор регистров 8086 для хранения битов. Однако в наборе регистров два инвертора соединены напрямую, без проходных транзисторов, управляемых генератором тактовых импульсов, что даёт более компактную, но трудную в управлении систему хранения.
Когда сигнал тактовой частоты высокий, значение проходит через первый инвертор.
Реализация в кремнии
8086 и другие процессоры той эры создавались на основе транзисторов типа N-МОП. Они изготавливались из кремниевой подложки, к которой в процессе легирования добавлялись примеси мышьяка или бора, формировавшие транзисторы. Сверху кремния находился поликремний, создававший затворы транзисторов и проводники, связывавшие все компоненты между собой. Ещё один слой, металлический, обеспечивал дополнительные токопроводящие связи. Современные процессоры, для сравнения, используют технологию КМОП, комбинирующую технологии N-МОП и P-МОП, а металлических проводящих слоёв у них больше одного.
Как в ИС реализуется N-МОП транзистор (МОП-структура)
На диаграмме выше показана структура транзистора. Транзистор можно считать выключателем, позволяющим току протекать от одного участка (исток) к другому (сток). Транзистор управляется затвором, сделанным из кремния особого типа – поликремния. Подача напряжения на затвор позволяет току течь между истоком и стоком, а подтягивание затвора к 0 В блокирует ток. От кремния затвор отделён изолирующим слоем оксида – из-за этого затвор работает как конденсатор, что видно на примере динамической защёлки.
Инвертор (ниже) сделан из N-МОП транзистора и резистора. При низком сигнале транзистор отключён, поэтому подтягивающий резистор подтягивает выходной сигнал наверх. При высоком сигнале транзистор включается, соединяя выход с землёй и подтягивая выход вниз. Таким образом цепь инвертирует входящий сигнал.
Подтягивающий резистор в N-МОП затворе реализуется при помощи транзистора особого типа. Транзистор с собственным каналом [depletion-mode transistor] работает как резистор, но занимает меньше места и имеет большую эффективность.
На схеме показано, как из транзистора и резистора получается инвертор. На фото видно, как схема реализована на чипе. Металлический слой удалён, чтобы было видно поликремний и кремний.
На фото справа показано, как в 8086 физически реализован инвертор. Желтоватые участки – это токопроводящий кремний с примесями, а пятнистые – это поликремний сверху. Транзистор получается там, где поликремний пересекает кремний с примесью. Поликремний формирует затвор транзистора, а участки кремния с обеих сторон дают исток и сток транзистора. Большой поликремниевый прямоугольник формирует подтягивающий вверх резистор между +5 В и выходом. Можно сопоставить строение этих физических структур со схемой.
На диаграмме ниже показана реализация защёлки на чипе. Отмечены проходной транзистор и два инвертора; первый инвертор описан выше. Поликремниевые проводники соединяют компоненты друг с другом. Дополнительные соединения обеспечивал металлический слой (удалён для фото). Сложная форма транзисторов позволяет наиболее эффективно использовать пространство.
Микроскопическое фото защёлки в процессоре 8086. Металлический слой с проводниками удалён, однако видны его следы в виде красноватых вертикальных линий. Фото повёрнуто на 180°, чтобы соответствовать схеме.
В защёлке используются выходные буферы, не отмеченные на схеме, дающие высокотоковые сигналы для выхода и инвертированного выхода. У этих буферов смешное название, «супербуферы» – потому что они выдают ток гораздо выше, чем у типичного N-МОП инвертора. Проблема N-МОП инвертора в том, что он работает медленно при управлении какой-либо цепью с высокой ёмкостью. Поскольку супербуфер даёт больший ток, он переключает сигнал гораздо быстрее. Достигает он этого, заменяя подтягивающий резистор транзистором, дающим больший ток. Минус в том, что подтягивающий транзистор требует инвертор для работы, поэтому схема супербуфера получается сложнее. Поэтому супербуфер используются только по необходимости – обычно при отправке сигнала на много затворов или при управлении длинной шиной.
Реализация супербуфера в защёлке 8086. Отметьте, что соединение с +5 В и землёй перенесены на самые правые транзисторы.
На диаграмме выше приведена схема супербуфера в защёлке 8086. В отличие от обычного супербуфера, в этом есть и инвертирующий, и не инвертирующий супербуфер. Чтобы разобраться в схеме, отметьте, что центральный резистор и транзистор формируют инвертор. Выход инвертора соединяется с верхними транзисторами, а не инвертированный вход соединяется с нижними транзисторами. Тогда, если вход 1, включаются нижние транзисторы, а если вход 0, то благодаря инвертору включаются верхние транзисторы. Тогда, если вход 1, нижние транзисторы притянут выход вверх, а соответствующий ему выход – вниз. Если вход 0, тогда верхние транзисторы притянут выход вниз, а соответствующий ему выход – вверх.
Проблема N-МОП инвертора в том, что у подтягивающего вверх резистора ток ограничен. Когда на выходе 0, транзистор в инверторе быстро и с относительно большим током подтягивает выход вниз. Однако если на выходе 1, выход подтягивается наверх гораздо более слабым подтягивающим резистором.
Супербуфер похож на КМОП-инвертор, поскольку у него есть подтягивающий вверх транзистор и подтягивающий вниз транзистор. Разница в том, что КМОП использует транзисторы типов P-МОП и N-МОП, а у P-МОП транзистора инвертированный вход затвора. И наоборот, для супербуфера N-МОП требуется отдельный инвертор. Иначе говоря, КМОП инвертор использует два транзистора, а эффективность у супербуфера гораздо меньше, поскольку ему требуется четыре транзистора.
Супербуфер использует транзистор с собственным каналом для подтягивания вверх и транзистор с индуцированным каналом [enhancement mode transistor] для подтягивания вниз. Пороговое напряжение транзистора с собственным каналом ниже нуля, что позволяет подтягивать его выход до 5 В, и не отключаться при менее высоком напряжении. Когда выход низкий, транзистор с собственным каналом всё ещё будет включён, и будет работать как обычный подтягивающий вверх в обычном инверторе, поэтому через него будет течь определённый ток. Подробнее о супербуфере можно почитать по ссылке.
Регистр команд
Как и большинства процессоров, у 8086 есть регистр команд, где хранится текущая выполняемая команда. В 8086 регистр команд хранит первый байт команды (которая может состоять из нескольких байт), поэтому он сделан из восьми защёлок. Можно было бы подумать, что они будут идентичными, однако каждая из них имеет свою форму. Схема расположения элементов процессора 8086 высоко оптимизирована, поэтому форма каждой защёлки сделана такой, чтобы наилучшим образом использовать доступное пространство из-за ограничений окружающих её проводников. В частности отметьте, что некоторые защёлки соединяются вместе, и имеют общее питание и землю. Видимо, по той же причине защёлки идут не подряд.
Все 8 защёлок несколько разной формы, оптимизированной с учётом окружающих проводников. Ранее в статье описывалась защёлка №1, повёрнутая на 180°. Красные вертикальные линии – следы удалённого слоя металла.
Команда путешествует по 8086 извилистым путём. Процессор использует увеличивающую быстродействие предварительную выборку, загружая команды из памяти перед тем, как они потребуются. Они хранятся в очереди команд, 6-байтной очереди, расположенной в середине набора регистров. У современных процессоров, для сравнения, командный кэш может достигать размера нескольких мегабайт.
При выполнении команды она сохраняется в регистре команд, примерно в центре чипа. Относительно большие расстояния и объясняют необходимость использования супербуфера. Регистр команд скармливает команду в «ПЗУ групповой расшифровки». Это ПЗУ определяет высокоуровневые характеристики команды – однобайтовая она, или многобайтовая, или это префикс команды. И это лишь небольшая часть сложной системы обработки команд 8086. Другие защёлки хранят части команд, отмечая использования регистра и операции АЛУ, а отдельная цепь управляет движком микрокода – но это я буду описывать отдельно.
Кристалл 8086, отмечены ключевые компоненты для обработки команд. По периметру распаечные провода соединяют кристалл с внешними контактами.
Заключение
8086 активно использует динамические защёлки для хранения внутренних состояний. Их видно под микроскопом, и их цепи можно отследить и понять. Кристалл 8086 интересно анализировать, поскольку, в отличие от современных процессоров, его транзисторы достаточно крупные, чтобы их было видно под микроскопом. Для своего времени это был сложный процессор с 29 000 транзисторами, однако всё же достаточно простой для того, чтобы его цепи можно было отследить и понять.