Когда инженеры разрабатывают архитектуру набора команд, по какой процедуре или протоколу, если таковые имеются, они следуют при назначении определенных двоичных кодов в качестве инструкций. Например, если у меня есть ISA, который говорит, что 10110 - инструкция загрузки, откуда взялось это двоичное число? Был ли он смоделирован из таблицы состояний для конечного автомата, представляющего операцию загрузки?
Изменить: После проведения дополнительных исследований, я думаю, что я пытаюсь спросить, касается того, как назначаются коды операций для различных инструкций процессора. ADD может быть обозначен кодом операции 10011; инструкция загрузки может быть обозначена как 10110. Какой мыслительный процесс используется для назначения этих двоичных кодов операций для набора команд?
источник
Ответы:
Во многих случаях выбор является довольно произвольным или основан на «везде, где он подходит лучше всего», поскольку ISA растут со временем. Тем не менее, MOS 6502 является прекрасным примером микросхемы, где на дизайн ISA сильно повлияла попытка выжать как можно больше из ограниченных транзисторов.
Посмотрите это видео, объясняющее, как 6502 был перепроектирован, особенно с 34:20 и далее.
6502 - это 8-битный микропроцессор, представленный в 1975 году. Несмотря на то, что у него было на 60% меньше вентилей, чем у Z80, он был в два раза быстрее, и хотя он был более ограниченным (с точки зрения регистров и т. Д.), Он восполнял это с помощью элегантный набор инструкций.
Он содержит всего 3510 транзисторов, которые были извлечены вручную небольшой группой людей, ползающих по нескольким большим пластиковым листам, которые впоследствии были оптически сжаты, образуя различные слои 6502.
Как вы можете видеть ниже, 6502 передает код операции и данные синхронизации в ПЗУ декодера, а затем передает их в компонент «логики случайного управления», цель которого, вероятно, состоит в том, чтобы перекрывать вывод ПЗУ в определенных сложных ситуациях.
В 37:00 в видео вы можете увидеть таблицу ПЗУ декодирования, которая показывает, каким условиям должны удовлетворять входы, чтобы получить «1» для данного контрольного выхода. Вы также можете найти его на этой странице .
Вы можете видеть, что большинство вещей в этой таблице имеют X в разных позициях. Давайте возьмем для примера
Это означает, что первые 3 бита кода операции должны быть 011, а G должен быть 2; Остальное не важно. Если это так, вывод с именем RORRORA станет верным. Все коды операций ROR начинаются с 011; но есть и другие инструкции, которые также начинаются с 011. Они, вероятно, должны быть отфильтрованы модулем «случайной логики управления».
Таким образом, в основном, коды операций были выбраны так, чтобы инструкции, которые должны были делать то же самое, что и друг друга, имели что-то общее в их битовой структуре. Вы можете увидеть это, посмотрев таблицу кодов операций ; все инструкции OR начинаются с 000, все инструкции Store начинаются с 010, все инструкции, использующие адресацию нулевой страницы, имеют форму xxxx01xx. Конечно, некоторые инструкции, похоже, не подходят, потому что цель состоит не в том, чтобы иметь полностью регулярный формат кода операции, а в том, чтобы обеспечить мощный набор команд. И именно поэтому «логика случайного управления» была необходима.
На странице, о которой я упоминал выше, говорится, что некоторые строки вывода в ПЗУ появляются дважды: «Мы предполагаем, что это было сделано, потому что у них не было способа направить вывод какой-либо строки туда, куда они хотели, поэтому они помещают одну и ту же строку в другую Ещё раз. " Я могу только представить, как инженеры вручную рисуют эти ворота, внезапно осознавая недостатки в дизайне и пытаясь придумать способ избежать повторного запуска всего процесса.
источник
Это зависит от того, сколько лет ISA.
На ранних этапах разработки вручную и, тем более, когда процессоры были собраны из дискретной логики, логический дизайн был бы на первом месте и был бы сведен к минимуму, а затем битовые шаблоны ISA были бы теми значениями, которые требовались для того, чтобы сделать это минимальным. логическая работа.
Таким образом, может существовать особый шаблон сигналов управления, который позволяет некоторым мультиплексорам подключать выход ALU ко входу файла регистра GP, еще несколько сигналов управления, которые инструктируют ALU складывать, вычитать, И, ИЛИ и т. Д., И несколько адресные биты в регистровом файле. Эти три группы сигналов будут формировать поля внутри инструкции. Каждая группа будет храниться вместе, и их подробное значение вытекает из дизайна для этого блока (ALU и т. Д.), Но группы могут быть в любом порядке, вплоть до разработки декодера команд. (x86 достаточно стар, чтобы вы могли обнаружить кое-что из этого, если вы посмотрите в нужном месте - это был не совсем новый дизайн, но взятый из более старого 8080)
Более поздние ISA могут быть «очищены» и сделаны более регулярными и более простыми в использовании, с аппаратными средствами для преобразования между ними и фактическими управляющими сигналами аппаратного уровня, иногда через «микрокод». Они называются «CISC» или «Кодирование набора сложных команд». Префикс инструкции x86 «Rep» является простым примером этого - он заставляет следующую инструкцию повторяться несколько раз, чтобы избавить от необходимости писать цикл FOR.
Позже (в 1980-х) появилось движение к более простому стилю прямого кодирования (RISC - Reduced Instruction Set Coding), который вы можете увидеть в процессорах ARM. Это было обусловлено небольшим размером ASIC в то время и желанием установить на них 32-битные процессоры, следовательно, не было резервной емкости для декодеров со сложным набором команд, чтобы снизить нагрузку на весь процессор примерно до 20 000 шлюзов. (Был также временный прирост производительности, потому что люди еще не разработали методики для быстрого создания декодеров CISC - это произошло примерно в 1995 году с Pentium Pro)
И в настоящее время это не имеет значения - процессоры читают несколько инструкций одновременно и посвящают миллионы транзисторов их декодированию, переупорядочиванию и выполнению как можно большего количества одновременно, чтобы ускорить программы, которые могли быть написаны для самых старых стиль ISA.
источник
Если вы сгруппируете похожие инструкции вместе, появятся шаблоны. Это очень очевидно в ARM, где руководство ISA фактически показывает, какой бит командного слова соответствует функции, выбору регистра и т. Д. Но это также может быть выведено для X86 .
В конечном счете, «функциональная» часть кодов операций входит в некоторый двоичный декодер, который фактически активирует определенную функцию или последовательность конвейерных операций. Они обычно не связаны с содержимым любого конечного автомата, если только мы не рассматриваем инструкции переменной длины, которые требуют конечного автомата для декодирования.
источник
Кто-то в какой-то момент сел и определил их.
Хороший ISA сделает декодер максимально простым.
Например, с помощью инструкции ALU можно разрешить отправку некоторых битов кода операции непосредственно в линии управления ALU.
источник
Как правило, вы бы разбили свой ISA на функциональные группы. Имеет смысл (либо для логической оптимизации, либо просто аккуратно), что дополнительные пары различаются по изменению одного бита (загрузка по сравнению с хранилищем) и что у вас есть некоторая иерархия битов, которая влияет на дерево решений декодирования.
В конце концов, произвольное распределение битов для функционального блока (в отличие от размещения полей «данных» в инструкции будет иметь лишь небольшое влияние на общую эффективность проектирования), но у вас есть много вариантов, как «оптимизировать» свою кодировку ISA в зависимости от того, что вы считаете важным параметром.
источник
Кодировка команд - это ужасный компромисс между ними.
Делая декодирование простым, для этого вам нужен простой набор полей, каждое из которых может быть декодировано отдельно и направлено в отдельную часть механизма исполнения.
Упаковка как можно большего количества функциональных возможностей в ограниченный размер командного слова. Это приводит к таким вещам, как специальные постоянные форматы, которые могут кодировать различные общие числа.
Прямая и обратная совместимость. Если вы назначаете функциональность каждому возможному коду операции, вы не оставляете себе места для дальнейшего расширения архитектуры. Если вы добавляете к существующей архитектуре, вы должны вставить свои новые инструкции в запасные коды операций.
источник
У Рэнди Хайда отличное (хотя и несколько устаревшее) искусство сборки. Он подробно описан в наборе команд x86 в главе 3.3.4 «Блок управления и наборы инструкций» и далее.
Затем он демонстрирует довольно броский и подробно, как первая пара заглушек обозначает инструкцию, следующие заглушки кодируют источник и назначение. Конечно, сегодня никто больше не «подключается», но для действительно старых ISA биты в коде операции в основном выполняют ту же работу, что и ранее.
Вы получите что-то вроде этого:
источник