20.04.2013

Исследование кристалла: недокументированные флаги микропроцессора 8085

image

У микропроцессора 8085 есть два недокументированных флага состояния: V и K. Эти флаги можно исследовать, приглядевшись к кристаллу микросхемы, и их функция, как выясняется, отличается от предыдущих толкований.

Автор: Ken Shirriff

У микропроцессора 8085 есть два недокументированных флага состояния: V и K. Эти флаги можно исследовать, приглядевшись к кристаллу микросхемы, и их функция, как выясняется, отличается от предыдущих толкований. К тому же реализация этих флагов говорит о том, что это было сделано намеренно, и тем самым возникает закономерный вопрос, почему эти флаги не задокументированы и не поддерживались компанией Intel. Наконец, изучение схем реализации флагов позволяет узнать любопытные детали физического процесса работы микропроцессора.

У микропроцессора 8085, как и большинства его собратьев, есть флаговый регистр, в котором хранится информация о состоянии операции. Флаговый регистр состоит из восьми бит: бит 0 хранит флаг переноса, бит 2 хранит флаг четности, бит 3 всегда установлен в 0, бит 4 хранит дополнительный перенос (полуперенос), бит 6 хранит нулевое состояние, и бит 7 хранит знаковый знак. В вышеупомянутом списке пропущены биты 1 и 5. Рассмотрим их повнимательнее.

Еще в 1979 году пользователи установили, что эти флаговые биты выполняют реальные функции [1]. Бит 1, также называемый V-флаг, хранит флаг переполнения операций со знаковыми числами, то есть показывает, умещается ли в 1 байт результат сложения или вычитания знаковых чисел [2]. Бит 5 плохо изучен, и у него есть несколько имен: K, X5 или UI. В случае операций увеличение/уменьшения этот бит указывает на 16-битное переполнение или потерю значащих разрядов, однако в случае арифметических операций имеет совершенно другое значение. Флаг описан в [1][3] как:

K = O1·O2 + O1·R + O2·R, где:

O1 = знак операнда 1

O2 = знак операнда 2

R = знак результата операции

Для вычитания и сравнений, замените знак O2 на противоположный.

Далее в этой статье я покажу, что это описание ошибочно. На самом деле К-флаг является результатом взаимоисключающего ИЛИ со знаком результата, и цель K-флага – сравнение чисел со знаком.

Схемы для K и V флагов.

Следующая схема демонстрирует цепь для K и V флагов микропроцессора 8085. V-флаг представляет собой взаимоисключающее ИЛИ между переносом в старшем бите и вне старшего бита. Это стандартная формула для вычисления переполнения [2] при сложении или вычитании чисел со знаком (микропроцессор 6502 вычисляет то же самое переполнение другим способом). Флаг V заполняется и после других арифметических операций, однако в этом случае не является полезным [4]. Регистр-защелка хранит значение V-флага под управлением сигнала store_v_flag. Кроме того, значение флага может быть считано с шины и сохранено в регистре под управлением сигнала bus_to_flags; так работает инструкция POP PSW, которая извлекает флаги из стека. В конце концов, супербуфер с тремя состояниями (большой треугольник) записывает значение флага в шину, когда это необходимо.

Схема K-флага показана справа. Первая его функция – переполнение/отрицательное переполнение для инструкции INX/DEX. Реализация этого механизма довольно проста: управляющая линия carry_to_k_flag устанавливает в K-флаг перенос от счетчика инкремента/декремента. Следующая функция K-флага – чтение информации с шины данных для инструкции POP PSW (как и в случае с V-флагом). И, наконец, последняя функция K-флага – результат проверки чисел со знаком. K-флаг является результатом операции взаимоисключающего ИЛИ между V-флагом и знаковым битом результата операции. В случае с вычитанием или проверкой K-флаг равен 1, если второе значение больше первого [5]. K-флаг используется в других арифметических операций, однако бесполезен за исключением проверки или вычитания знаковых чисел. [4]

На рисунке показана схема микропроцессора 8085 для не задокументированных K и V флагов. Флаги генерируются на основе битов переноса и результатов АЛУ. К-флаг может быть установлен битом переноса от счетчика инкремента/декремента.

Назначение K-флага было непонятным: «Он не похож ни на один стандартный флаговый бит» [1]. Понятно, что он используется для инкремента/декремента, однако в случае с арифметическими операциям, зачем выполнять взаимоисключающее ИЛИ между флагом переполнения и битом знака? Оказывается, K-флаг полезен для сравнений знаковых чисел. Когда вы сравниваете два знаковых значения, первое меньше второго, если взаимоисключающее ИЛИ знакового бита и переполнения равно 1 [6]. Вот что на самом деле вычисляет K-флаг.

Глядя на схему, показанную выше, очевидно, что V и K-флаги были умышленно добавлены в микросхему. (В отличие от микропроцессора 6502, где не задокументированные коды операций имеют непредсказуемые результаты из-за нестабильной работы цепи с непредвиденными входными сигналами [7]). Почему компания Intel использовала цепь флагов, ни слова не сказав об этом в документации? По моей теории было принято решение не поддерживать K или V флаги в процессоре 8086 и, таким образом, для совместимости документации они убрали описания этих флагов из документации на процессор 8085, однако оставили цепь в микросхеме.

Кристалл

На рисунке показан микропроцессор 8085 с шиной данных, АЛУ, логической схемой флагов, регистрами и счетчиком инкремента/декремента.

Далее в этой статье будет показано, как работают цепи V и K флагов с более детальным изучением схем кристалла. На картинке выше показана микросхема процессора 8085 и компоненты, которые мы будем обсуждать. В верхнем левом углу находится АЛУ (арифметико-логическое устройство), где происходят вычисления (подробности). Шина данных является основной артерией микросхемы, соединяя информационные выводы (левый верхний угол), АЛУ, регистры данных, флаговый регистр и дешифратор команд (правый верхний угол). В левом нижнем углу расположен блок 16-битных регистров. Ниже блока регистров расположена цепь 16-битного инкремента/декремента, которая управляет увеличением программного счетчика, а также используется 16-битными инструкциями инкремента/декремента. В правом нижнем углу у цепи инкремента/декремента есть выходной сигнал переноса. Его мы коснемся во время обсуждения K-флага. По некоторым причинам у АЛУ младший бит находится справа, а у регистров младший бит находится слева.

Логическая схема флагов находится под АЛУ вместе мощными формирователями прямо наверху шины данных. По-видимому, флаги расположены в случайном порядке со знаковым битом 7 слева и битом 6 (нулевое состояние) справа. Поскольку схема логики переноса сложна (обрабатывая не только арифметические операции, но и сдвиги, циклические сдвиги, инвертирование переноса и десятичную коррекцию), то ее разместили справа от АЛУ, где для нее достаточно места.

Подробное рассмотрение схемы V-флага

Теперь рассмотрим цепь V-флага в увеличенном масштабе, на схеме выше она отмечена как V1. Глядя на кристалл под микроскопом, мы видим металлический слой микросхемы, содержащий в основном горизонтальные соединения (см. белые линии ниже). В нижней части микросхемы находится 8-битная шина данных. Другие провода: питание, «земля» и набор сигналов. В то время как у современных процессоров может быть десять и более металлических слоев, у микропроцессора 8085 всего лишь один слой. Под металлическим слоем можно увидеть некоторые цепи.

На рисунке показан металлический слой микропроцессора 8085, увеличенный в месте нахождения цепи V-флага.

Если удалить металлический слой, становится виден кремниевый слой. Пятнисто-зеленые/лиловые участки являются чистым кремнием. Розовые участки – легированный кремний N-типа. Сероватые участки – поликристаллический кремний, который служит в качестве соединительных проводов. Когда поликремний пересекает легированный кремний, образуются транзисторы, которые на рисунке обозначены светло-зелеными участками. Обратите внимание, что транзисторы занимают малую часть микросхемы; основная ее часть отведена под соединения. Маленькие квадраты – переходы, соединения с металлическим слоем.

На рисунке показана цепь V-флага микропроцессора 8085. Под металлическим слоем находится кремний/поликремний. Шина данных не видна, поскольку она находится в металлическом слое, в нижней трети изображения. Прямоугольники внизу соединяются шину данных и регистры.

МОП-транзисторы

В контексте нашей дискуссии МОП-транзисторы можно считать простыми переключателями, которые закрываются, если на входе затвора 1 и открываются, если на входе затвора 0. МОП-транзистор реализован путем смешения двух диффузионных областей и поликремниевой перемычки над затвором. Изоляционный слой предотвращает прохождение тока между затвором и остальной частью транзистора. На рисунке ниже диффузионные области n+ отмечены розовым цветом, поликремниевый проводник затвора матово-зеленым цветом, а изолирующий слой диоксида кремния – цветом морской волны.

Логическая схема ИЛИ-НЕ

Логическая схема ИЛИ-НЕ является фундаментальным блоком микропроцессора 8085. Это довольно простая схема, которая может входить в состав более сложной логической цепи. Сама схема состоит из двух транзисторов и нагрузочного транзистора. Если на вход какого-либо транзистора (или обоих) подается 1, тогда соответствующий транзистор замыкается на «землю». Иначе, оба транзистора открыты и на нагрузочном транзисторе появляется выходной сигнал. На схеме нагрузочный транзистор обозначен как резистор, однако, на самом деле это транзистор, работающий в режиме обеднения для лучшей производительности.

Увеличив одиночный блок ИЛИ-НЕ микропроцессора 8085, мы увидим, как реализован логический элемент. Большую часть схемы занимают соединения, а транзисторы лишь небольшую ее часть. Слева оба транзистора подсоединены к «земле», а справа соединены между собой. По техническим причинам нагрузочный транзистор более крупный, чем два предыдущих [8].

Чтобы понять механизм работы цепи, проследите путь от «земли» к каждому транзистору, и далее через затвор на выходной провод. Видно, что от «земли» к выходу идут два провода, и если на каком-либо проводе входной сигнал равен 1, тогда на выходе будет 0.

Расположение логического элемента выбрано для наибольшей эффективности, с учетом ограниченности площади расположения питания (VCC), «земли» и других соединений. В итоге мы видим слегка необычную схему. Питание, «земля» и входные сигналы находятся в металлическом слое выше (не показанным здесь). Они соединены с цепью через переходы между металлическим слоем и кремнием.

На рисунке показаны компоненты элемента ИЛИ-НЕ микропроцессора 8085. Если на каком-либо входе единичный сигнал, соответствующий транзистор замыкается на «землю», иначе, на выходе нагрузочного транзистора появляется ненулевой выходной сигнал.

Логические элементы типа исключающее ИЛИ

Логический элемент типа исключающее ИЛИ (когда на выходе 1, если только на одном из входов 1) является ключевым компонентом схемы флага. На его примере показывается, как можно реализовать сложную логику, используя простые элементы. На схеме ниже показывается реализация элемента «исключающее ИЛИ» из элементов «ИЛИ-НЕ» и «И-НЕ»; легко проверить, что если обоих входах 0 или 1, тогда на выходе будет 0.

Возможно, вы задаетесь вопросом, почему в микропроцессоре используется так много «странных» элементов, вместо «нормальных» элементов типа «И». Все дело в том, что логический элемент «И-НЕ» можно легко реализовать при помощи полевых транзисторов, даже проще чем обычный элемент типа «И». Два самых правых транзистора реализуют логику «И-НЕ», если на обоих входах 1, тогда выход замыкается на «землю». Транзистор слева реализует другую часть логики «ИЛИ-НЕ» - если на входе 1, то нагрузочный транзистор замыкается на «землю».

На схеме ниже показана логическая схема, реализующая логику исключающее ИЛИ, которая используется для генерации K-флага. Слева – элемент «ИЛИ-НЕ», справа – «И-НЕ». Обе цепи выделены пунктирной линией. Как и прежде, цепь в основном состоит из соединительных проводов, а транзисторы занимают малую часть схемы (зеленые участки, между розовыми диффузионными областями).

Логический элемент типа исключающее ИЛИ, собранный из элементов «ИЛИ-НЕ» и «И-НЕ». Если на обоих входах 0, на выходе элемента «ИЛИ-НЕ» будет 1, и следующий транзистор замкнет выходной провод на землю (то есть на выходе будет 0). Если на обоих входах по 1, транзисторы составляющие конструкцию «И-НЕ» замыкают выходной провод на «землю», иначе, на выходе будет ненулевой сигнал.

Флаговый регистр-защелка

Каждый бит флага хранится в простом регистре-защелке, реализованном на двух инверторах. Для хранения значения 1 правый инвертор выдает значение 0, поступающее на инвертор слева, который выдает 1. Выходной сигнал левого инвертора вновь поступает на правый инвертор. 0 хранится аналогичным образом (только входной сигнал противоположен). Когда синхронизирующие импульсы низкой амплитуды проходной транзистор открыт, разрывая цикл. В этом режиме можно записать входные данные. Выходной сигнал (/out) снимается c дополнительного вывода с инвертора.

Вы можете спросить, почему же регистр не теряет данные, когда синхронизирующие импульсы низкой амплитуды. Это интересный трюк, называемый динамической логикой. Поскольку затвор МОП-транзистор содержит изолирующий слой, у него очень большое сопротивление. Следовательно, на затворе какое то время [9] будет оставаться электрический заряд в тот период, пока проходной транзистор открыт. Когда проходной транзистор закрывается, электрический заряд обновляется.

На рисунке показана схема регистра-защелки, которая используется в микропроцессоре 8085 для хранения флага. Защелка работает на двух инверторах. Когда синхроимпульсы низкой амплитуды, в регистр можно записать новое значение.

Далее мы рассмотрим схему реализации V-флага. Она полностью совпадает со схемой выше. Два инвертора выделены пунктирными линиями. Красные стрелки показывают направление потока данных через цепь. Как и прежде, провода и нагрузочные транзисторы занимают большую часть кремниевого участка.

Каждый флаг в микропроцессоре 8085 хранится регистре-защелке на двух инверторах. На рисунке показана схема для V-флага. Красные стрелки показывают направление потока данных.

Управление шиной данных посредством супербуфера

Другая интересная особенность схемы флага – «супербуфер». Большинство транзисторов в микропроцессоре 8085 передают сигнал на короткое расстояние. Однако при передаче данных по шине через всю микросхему требуется намного больше мощности. Для этого и используется супербуфер. В супербуфере один транзистор понижает выходной сигнал, а другой транзистор повышает (в отличие от стандартного логического элемента, где для повышения амплитуды сигнала используется нагрузочный транзистор, работающий в режиме обеднения). К тому же, оба эти транзистора значительно крупнее, поскольку работают с токами большей величины [8]. Транзисторы показаны на схеме ниже в нижней ее части.

Еще одна особенность супербуфера – три состояния. В третьем состоянии (помимо первых двух, когда на выходе единичный и нулевой выходной сигнал) на выходе отсутствует сигнал. Таким образом, флаги не влияют на шину данных за исключением случаев, когда это необходимо. На схеме видно, что если на управляющем входе значение 1, то на выходе обоих элементов «ИЛИ-НЕ» значение 0 и оба транзистора в нерабочем состоянии.

На рисунке показана цепь супербуфера, который используется в микропроцессоре 8085 для управления шиной данных.

На следующей схеме показаны два управляющих транзистора, а также провод, используемый для чтения флага с шины данных (элементы «ИЛИ-НЕ» не показаны). Обратите внимание на величину транзисторов в сравнении с рассмотренными ранее. Для каждого флагового бита требуется подобный супербуфер. Даже для бита 3, который всегда равен 0, требуется большой транзистор для передачи нуля по шине. Удивительно то, что даже подобными флагам требуется место на кристалле.

Каждый флаг в микропроцессоре 8085 использует супербуфер для передачи значения по шине данных. На рисунке показаны два больших транзистора, которые управляют V-флагом по шине данных 1

Объединяем все вместе

Мы рассмотрели детали реализации логического элемента типа исключающее ИЛИ, который вычисляет K-флаг. Также был рассмотрен регистр-защелка и супербуфер, используемый в цепи V-флага. Следующий рисунок показывает общую схему, где все части соединены вместе. Регистр защелка и формирователь для К-флага находятся справа за пределами изображения. Схемы соединены между собой посредством металлического слоя (на рисунке не показан). Сравните эту схему с принципиальной схемой, представленной вначале статьи, чтобы понять, как реализованы компоненты. Два логических блока типа исключающее ИЛИ реализованы совершенно по-разному, поскольку их макеты были оптимизированы под используемые сигналы.

На рисунке показаны отдельные блоки микропроцессора 8085, реализующие недокументированные V и K флаги. АЛУ формирует биты переносов (carry6 и carry7) и результат выражения (result7). Правый логический элемент типа исключающее ИЛИ вычисляет V-флаг, а логический элемент по середине – K-флаг. Справа находится регистр-защелка для V-флага и супербуфер, которые передает значение флага по шине данных. Регистр-защелка и супербуфер для K-флага находятся также справа (на схеме не показаны).

Если внимательнее присмотреться к кремниевому кристаллу, транзисторам и логическим элементам, то становится понятен механизм работы сложных цепей. Удивительно то, что сложные компьютеры, используемые нами, состоят из таких простых компонент. Конечно, современные процессоры с миллиардами транзисторов более сложны, чем микропроцессор 8085, состоящий из тысяч транзисторов, однако, базовые принципы работы остаются теми же.

Если материал этой статьи оказался для вас интересным, вы можете ознакомиться с моими предыдущими статьями по анализу флага переполнения в микропроцессоре 6502 или АЛУ в микропроцессоре 8085. Также, возможно, вас заинтересует книга The Elements of Computing Systems, где объясняется, как сконструировать компьютер, начиная с булевой логики.

Благодарности

Изображения микросхемы взяты с сайта visual6502.org. Команда visual6502 проделала большую работу, окуная микросхемы в кислоту для удаления внешнего слоя и сделав много фотоснимков кристалла с близкого расстояния. Павел Зима (Pavel Zima) сконвертировал фотографии в изображения печатных плат, сеть транзисторов и имитационную модель микропроцессора 8085.

Примечания и ссылки

[1] Не задокументированные инструкции и флаги микропроцессора 8085 были обнаружены Вольфгангом Денхардтом (Wolfgang Dehnhardt) и Вилли М. Соренсеном (Villy M. Sorensen) в процессе программирования на ассемблере 8085 и подробно описаны в статье Unspecified 8085 op codes enhance programming, раздела Engineer's Notebook, журнала «Electronics», 18-го января 1979 года стр. 144-145.

[2] Подробное описание флага переполнения смотрите в моей статье The 6502 overflow flag explained mathematically. Существует несколько способов вычисления переполнения, и микропроцессор 6502 использует другой метод.

[3] Компания Tundra Semiconductor разработала микросхему CA80C85B, КМОП-версию 8085. Что интересно, не задокументированные опкоды и флаги описываются в даташитах: CA80C85B datasheet, 8000-series components.

Самым интересным является то, что описания «новых» флагов и инструкций почти полностью скопированы из статьи Денхардта. Разница лишь в том, что появились ошибки, отсутствуют вводные слова и переименован K-флаг в UI-флаг. К тому же, как я говорил ранее, формула расчета K/UI флагов не всегда верна. Кажется, несмотря на производство микросхемы, в компании Tundra не до конца понимали, как работали схемы.

[4] Использование V-флага имеет смысл для сложения и вычитания чисел со знаком, а K-флага для вычитания и сравнения чисел со знаком. Многие другие операции изменяют этот флаг, однако в этих случаях он бесполезен.

V-флаг равен 0 для операций RRC, RAR, AND, OR и XOR, поскольку у этих операций постоянные значения переноса находятся внутри АЛУ (подробности). Операции RLC и RAL работают только с аккумулятором, добавляя его значение к самому себе, что можно рассматривать как суммирование: V-флаг устанавливается в случае, если результат операций чисел со знаком больше байта. Для команды DAA (десятичная коррекция) V-флаг работает также, как и при суммировании: V-флаг будет установлен только при переносе старшего значащего разряда (старшая цифра переходит от 7 к 8). Хотя в BCD-числах отсутствует знак, и V-флаг для операции DAA бесполезен. Более полезен V-флаг для операции DAD, поскольку отражает 16-битное знаковое переполнение и вычисляется по результатам сложения старших разрядов. Для инструкции INR переполнение возникает при переходе от значения 0x7f к 0x80 (от 127 к -128); заметьте, что переходу от 0xff к 0x00 соответствует переход от -1 до 0, что является не знаковым переполнением, а беззнаковым. Аналогичным образом инструкция DCR устанавливает V-флаг при переходе от шестнадцатеричного значения 80 к 7f (от -128 к 127), что является также беззнаковым переполнением.

В случае с K-флагом есть несколько особых случаев. Для инструкций AND, OR и XOR K-флаг равен биту знака, поскольку V-флаг равен 0. Обратите внимание, что K-флаг для инструкций INR/DCR рассчитывается полностью по-другому, чем для инструкций INX/DCX. Для инструкций INR и DCR K-флаг вычисляется как исключающее ИЛИ между флагами S и V (S^V) и почти всегда равен S. Для инструкции DAA K-флаг устанавливается, если S^V – истинно, что не имеет полезных применений, поскольку BCD-значения беззнаковые.

Опубликованная формула K-флага ошибочна для инструкции XOR, если оба аргумента отрицательные.

[5] Следующая таблица иллюстрирует 8 возможных случаев при сравнении знаковых значений A и B. Входные сигналы: старший бит A, старший бит B и перенос бита 6 при вычитании B из A. Выходные сигналы: флаг переноса, отрицательного переноса (противоположный биту переноса), знака, переполнения и K-флаг. Пример приведен для каждого случая. Обратите внимание, K-флаг устанавливается если А меньше В, когда числа обрабатываются как знаковые.

Входы

Выходы

Пример

A7

B7

C6

C

B

S

V

K

Шестнадцатеричное выражение

Знаковое сравнение

0

1

0

0

1

0

0

0

0x50 - 0xf0 = 0x60

80 - -16 = 96

0

1

1

0

1

1

1

0

0x50 - 0xb0 = 0xa0

80 - -80 = -96

0

0

0

0

1

1

0

1

0x50 - 0x70 = 0xe0

80 - 112 = -32

0

0

1

1

0

0

0

0

0x50 - 0x30 = 0x120

80 - 48 = 32

1

1

0

0

1

1

0

1

0xd0 - 0xf0 = 0xe0

-48 - -16 = -32

1

1

1

1

0

0

0

0

0xd0 - 0xb0 = 0x120

-48 - -80 = 32

1

0

0

1

0

0

1

1

0xd0 - 0x70 = 0x160

-48 - 112 = 96

1

0

1

1

0

1

0

1

0xd0 - 0x30 = 0x1a0

-48 - 48 = -96

[6] Детальное объяснение знакового сравнения дается в статье Брюса Кларка (Bruce Clark) Beyond 8-bit Unsigned Comparisons, раздел 5.

[7] Недопустимые опкоды микропроцессора 6502 детально рассматриваются в статье How MOS 6502 Illegal Opcodes really work. В модели 6502 результаты недопустимых опкодов непредсказуемы, поскольку логика микросхемы работает нестабильно, когда на входе неожиданные сигналы. Напротив, в модели 8085 не задокументированные опкоды подобно флагам введены намеренно.

[8] Ключевым параметром производительности МОП-транзистора является отношение ширины к длине затвора. Грубо говоря, ток транзисторов пропорционален этому отношению. (Ширина – это ширина стока или истока, а длина – расстояние от истока к стоку, проходящее через затвор). Для наилучшей производительности инвертора отношение ширины к длине нагрузочного транзистора должно приблизительно составлять 1/4 от отношения ширины к длине входного транзистора (См. Introduction to VLSI Systems, Mead, Conway, стр. 8). Как результат, нагрузочные транзисторы большие и массивные в сравнении с понижающими транзисторами. Еще одно следствие – у мощных транзисторов в супербуфере очень широкий затвор. В блоке регистров микропроцессора 8085 имеются некоторые транзисторы, где отношение ширины к длине подобрано очень тщательно, чтобы один из транзисторов был «ведущим» в случае, если оба транзистора одновременно открыты. (Именно поэтому имитационная модель микропроцессора 8085 более сложная, чем у модели 6502, поскольку необходимо учитывать размеры транзисторов).

[9] Одним из последствий использования динамических буферов проходного транзистора является то, что если тактовая частота слишком мала, с течением времени произойдет утечка заряда и потеря данных. Поэтому микропроцессор 8085 имеет минимальную тактовую частоту 500 кГЦ. Модель 6502 также имеет минимальную тактовую частоту. Модель Z-80 напротив сделана на статической логике и не имеет минимальной тактовой частоты – тактовые импульсы можно замедлять настолько, насколько это необходимо.

comments powered by Disqus