Часть 3
Дизайн отличаемого собственного RISC ЦПУ.
В этой главе обсуждается дизайн и архитектура отличаемого собственного CJG (в честь автора статьи, разработка с помощью LLVM) RISC ЦПУ. Глава 3.1 объясняет выбор создаваемого дизайна, глава 3.2 описывает реализацию этой архитектуры, и глава 3.3 описывает все инструкции в деталях.
3.1 Архитектура набор команд
Первым этапом в проектировании RISC CJG должно быть, указание свой архитектуры набора команд (ISA). ISA был разработан, чтобы быть достаточно простым (речь в данном контексте про CJG), чтобы реализовать в аппаратном обеспечении и описать ISA для LLVM, в то же время включить достаточное количество инструкций и функций, чтобы он мог (ЦПУ) выполнять сложные программы. Архитектура представляет собой 32-битную шину данных, дизайн регистр-регистр. Каждый операнд имеет ширину 32 бита, и все инструкции по обработке данных могут работать только с операндами, расположенными в регистровом файле.
3.1.1 Регистровый файл
Файл регистра состоит из 32 отдельных, 32-разрядных регистров, обозначенных как r0 – r31. Все регистры имеют общее назначение (РОН), за исключением регистра r0-r2, которые обозначаются, как регистры специального назначения. Первым регистром специального назначения является регистр состояния (SR), который хранится в r0. Регистр состояния содержит биты условия, которые автоматически устанавливаются процессором после инструкции по управлению. Заданные биты условий представляют собой результат арифметической операции: перенос, отрицательный результат, переполнение или нулевой результат. Биты регистра состояния можно увидеть на рисунке 3.1. Таблицу, описывающую биты регистра состояния, можно увидеть в таблице 3.1.
31 – 4 | 3 | 2 | 1 | 0 |
Не используется | Z | V | N | C |
Рисунок 3.1: Биты статусного регистра (регистры состояния)
Бит | Описание |
C | Бит переноса. Это значение равно 1, если результат команды выполнения совершил перенос, и установлен 0 в противном случае |
N | Отрицательный бит. Это значение равно 1, когда результат команды манипуляции производит отрицательное число (результат устанавливается в 31 бите) и устанавливает значение 0 в противном случае |
V | Бит переполнения. Это значение равно 1, когда арифметическая операция приводит к переполнению (например, когда положительный + положительный результат отрицательный) и устанавливается в 0 в противном случае |
Z | Нулевой бит. Это значение равно 1, когда результат команды манипуляции производит результат равный 0, и устанавливает значение 0 в противном случае |
Таблица 3.1: Описание битов статусного регистра
Следующим регистром специального назначения является регистр счетчика программы (PC), который хранится в r1. Этот регистр хранит текущее значение счетчика команд, который является адресом действующей инструкции, слово в памяти. Этот регистр защищен от записи и не может быть перезаписан никакими инструкциями по управлению. PC может быть изменен только инкрементом во время выборки инструкции (см. раздел 3.2.1.1) или инструкцией по управлению потоком (см. раздел 3.3.3). Биты PC можно увидеть на рисунке 3.2.
31 – 16 | 15 – 0 |
Не используется | Биты счетчика программы |
Рисунок 3.2: Биты счетчика программы
Конечным регистром специального назначения является регистр указателя стека (SP), который хранится в r2. Этот регистр хранит адрес, указывающий на вершину стека данных. Указатель стека автоматически увеличивается или уменьшается, когда значения попадают на стек или забираются из стека. Биты SR можно увидеть на рисунке 3.3.
31 – 6 | 5 – 0 |
Не используется | Биты указателя стека |
Рисунок 3.3: Регистр указателя стека
3.1.2 Дизайн стека
Есть два аппаратных стека в дизайне CJG RISC. Один стек используется для сохранения PC и SR на протяжении вызовов и возвратов (стек вызова). Другой стек используется для хранения переменных (стека данных). Большинство процессоров используют стек данных, расположенный в пространстве памяти данных, однако для упрощения реализации использовался аппаратный стек. Оба стека глубиной 64 слова, однако они работают немного по-другому. Стек вызова не имеет указателя внешнего стека. Данные которые кладутся и вынимаются из стека используют сигналы внутреннего контроля. Стек данных, однако, использует регистр SP для доступа к его содержимому, действующему подобно структуре памяти. Во время инструкции по вызову PC, а затем SR помещаются на стек вызова. Во время возвращения инструкции они достаются назад в их соответственно регистры. Стек данных управляется инструкциями push и pop. Инструкция push помещает значение в стек в месте расположения SP, затем автоматически увеличивает указатель стека. Инструкция pop сначала уменьшает указатель стека, затем выводит значение в месте расположения указателя стека в регистр назначения. Эти инструкции описаны далее в разделе 3.3.2.
3.1.3 Архитектура памяти
Существует два основных архитектуры дизайна памяти, используемые при проектировании процессоров: Гарвардская и фон Неймана. Гарвардская использует две отдельных физических шины данных для доступа к данным и памяти инструкций. Архитектура фон Неймана использует только одну шину для доступа к данным и памяти инструкций. Без использования кэширования памяти, традиционные архитектуры фон Неймана не могут получить параллельный доступ, как к инструкциям, так и к памяти данных. Архитектура Гарварда была выбрана, чтобы упростить внедрение и избежать необходимости останавливать процессор во время доступа к памяти данных. Кроме того, Архитектура Гарварда обеспечивает полную защиту от обычных атак памяти (например, переполнение буфера/стека) в отличие от более сложной архитектуры фон Неймана [18]. Никакие кэши данных или инструкций не были реализованы, чтобы сохранить сложность памяти низкой. Оба типа памяти имеют байтовую адресацию с 32-разрядной шиной данных и 16-битной шины адреса. Верхние 128 адресов памяти данных зарезервированы для периферийных устройств ввода-вывода.
3.2 Аппаратная реализация
CJG RISC полностью разработана на языке описания аппаратуры Verilog (HDL) на уровне регистровых передач (RTL). Процессор реализован в виде четырехступенчатого конвейера, а основными компонентами являются генератор частоты, регистровый файл, арифметический логический блок (ALU), сдвигатель и два стека. Упрощенная функциональная структурная схема процессора видна на рисунке 3.4.
Рис. 3.4: CJG базе RISC процессора функциональная блок-схема
Состояние конвейера | Конвейер | ||||||
IF | I0 | I1 | I2 | I3 | I4 | I5 | … |
OF | I0 | I1 | I2 | I3 | I4 | … | |
EX | I0 | I1 | I2 | I3 | … | ||
WB | I0 | I1 | I2 | … | |||
Цикл частоты | 1 | 2 | 3 | 4 | 5 | 6 | … |
Рисунок 3.5: Четырехступенчатый конвейер
Получить инструкцию -> Получить операнд -> Выполнить -> Записать назад |
Рисунок 3.6: Блок-схема четырехступенчатого конвейера
3.2.1 Проектирование конвейера
Конвейер, представлен стандартным четырехступенчатым конвейером с инструкцией получить (IF), получение операнда (OF), выполнить (EX), и записать обратно (WB). Эту структуру конвейера можно увидеть на рисунке 3.5 где In представляет одиночную инструкцию распространяющуюся по конвейеру. Кроме того, блок-схему конвейера можно увидеть на рисунке 3.6. Во время тактовых циклов 1-3 конвейер заполняется инструкциями и не имеет максимальной эффективности. Для тактов 4 и выше, конвейер полностью заполнен и происходит эффективное выполнение инструкций в размере 1 IPC (инструкций за такт). ЦП будет продолжать выполнять инструкции со скоростью 1 IPC, пока не возникнет переход или инструкция вызова, в такой момент ЦП остановится.
3.2.1.1 Инструкция получения (fetch)
Выборка инструкций – это первый машинный цикл конвейера. Инструкция получения имеет наименьшую логику любого этапа и одинакова для каждой инструкции. Этот этап отвечает за загрузку следующего слова инструкции из памяти инструкции, увеличение счетчика программы, так что он указывает на следующее слово инструкции, и остановку процессора, если встречается вызов или переход инструкции.
3.2.1.2 Получение операнда
Получение операнда – есть второй машинный цикл конвейера. Этот этап содержит большую часть логики на любом из этапов конвейера, из-за логики переадресации данных, реализованной для устранения опасности зависимости данных. Для примера рассмотрим инструкцию In, которая изменяет Rx регистр, затем инструкция In+1, которая использует в качестве операнда Rx (Rx представляет какую-либо общую модифицируемую цель регистрации). Без каких-либо логика пересылки данных, In+1 не будет получать правильное значение, потому что In до сих пор был в стадии выполнения конвейера, и Rх не будет обновлена с правильным значением до завершения записи. Логика пересылки данных устраняет эту опасность, извлекая значение на выходе этапа выполнения, а не из Rx. Опасности зависимости данных могут также возникнуть из-за менее распространенных ситуаций, таких как, инструкция изменяющая SP, за которой следует инструкция стека. Поскольку инструкция стека должна модифицировать указатель стека, то она должна быть передана также. Альтернативным подходом к решению этих опасностей, зависимости данных для приостановления выполнение ЦП до завершения записи требуемого операнда. Это компромисс между увеличением циклов останова и увеличением сложности логики пересылки данных. Логика переадресации данных была реализована для минимизации циклов останова, однако для этого варианта проектирования не был рассчитан углубленный анализ эффективности.
3.2.1.3 Исполнение
Исполнение является третьим машинным циклом конвейера и в основном отвечает за три функции. Первая функция подготавливает любые данные для каждого из элементов АЛУ или модуль сдвига для записи за “кулисами”. Вторая функция обрабатывает чтение вывода памяти для данных. Третья функция – отвечаете за обработку всех данных, которые были удалены из стека, а также настройка указателя стека.
3.2.1.4 Обратная запись
Этап обратной записи-это четвертый и последний машинный цикл конвейера. Этот этап отвечает за запись любых данных из этапа выполнения обратно в регистр назначения. Этот этап также отвечает за обработку логики управления потоком для условного перехода, а также вызовы и возвраты (как описано в разделе 3.3.3).
3.2.2 Сваливание
ЦП останавливается, когда встречается инструкция перехода или вызова. Когда процессор останавливается конвейер освобождает/выталкивает текущую инструкцию, а затем PC устанавливается в место назначения либо прыгает на вызов. Как только ЦП успешно осуществляет скачек или вызов в новое местоположение, конвейер начнет заполнять снова.
3.2.3 Тактовые фазы
Процессор содержит модуль тактового генератора, который генерирует две тактовые фазы φ1 и φ2 (Рисунок 3.7), от такта основной системы. Такт φ1 ответствен за всю логику конвейера пока φ2 выполняется, за клок памяти и для памяти инструкции и данных. Кроме того, клок φ2 используются для стеков вызовов и данных.
Рисунок 3.7: Фазы синхронизации
3.3 Детали инструкций
В этом разделе перечислены все инструкции, показана значимость битов слова инструкций и описаны другие конкретные детали, относящиеся к каждой инструкции.
3.3.1 Загрузка и хранение
Инструкции по загрузке и хранению отвечают за передачу данных между памятью данных и файлом регистра. Кодировка слова инструкции показана на рисунке. 3.8.
31 – 28 | 27 – 22 | 21 – 17 | 16 – 15 | 15 – 0 |
Опкод | Ri | Rj | Управление | Адрес |
Рисунок 3.8: Загрузка и хранение инструкций (размер – слово)
Существует четыре различных режима адресации, которые ЦП может использовать для доступа к определенному местоположению памяти. Эти режимы адресации вместе с тем, как они выбраны, описаны в таблице 3.2, где Rx соответствует регистру Rj в слове инструкции загрузки и хранения. Подробная информация о загрузке и хранении описана в таблице 3.3.
Режим | Rx (Rx соответствует Rj для инструкций по загрузке и хранению, и Ri для инструкций по управлению потоком) | Управление | Эффективное значение адреса |
Register Direct/Регистрация | Not 0 | 1 | Значение регистра, регистров Rx |
Absolute/Абсолютный | 0 | 1 | Значение в поле адреса |
Indexed/Индексированный | Not 0 | 0 | Значение операнда регистра Rx + значение в поле адреса |
PC Relative/Родственник PC | 0 | 0 | Значение регистра PC + значение в поле адреса |
Таблица 3.2: Описания режима адресации
Инструкция | Мнемоника | Опкод | Функции |
Загрузить | LD | 0x0 | Загрузите значение в память по действующему адресу или периферийному устройству ввода-вывода в регистр Ri |
Сохранить | ST | 0x1 | Храните значение регистра Ri в памяти на эффективном адресе или периферийном устройстве ввода-вывода |
Таблица 3.3: Детали загрузки и хранения инструкций
3.3.2 Передача данных
Инструкции данных ответственны за перемещение данных между файлом регистра, полем слова инструкции, и стеком. Кодировка слова инструкции показана на рисунке 3.9.
31 – 28 | 27 – 22 | 21 – 17 | 16 – 15 | 15 – 0 |
Опкод | Ri | Rj | Управление | Константа |
Рисунок 3.9: Слово инструкции по передаче данных
Подробные инструкции по передаче данных приведены в таблице 3.4. Если бит управления установлен в 1, то операнд источника для копирования и отправки инструкций берется из 16-бит поля константы и знака расширения, в противном случае исходный операнд является регистром обозначающий Rj .
Инструкции | Мнемоники | Опкод | Функция |
Копирования/Copy | CPY | 0x2 | Скопируйте значение из исходного операнда в регистр Ri |
Отправки/Push | PUSH | 0x3 | Оправка значения из исходного операнда на вершину стека, а затем увеличивает указатель стека |
Извлечения/Pop | POP | 0x4 | Уменьшите указатель стека, а затем извлечь значение из верхней части стека в Ri регистр. |
Таблица 3.4: Детали инструкции по передаче данных
3.3.3 Управление потоком
Инструкции по управлению потоком отвечают за настройку последовательности инструкций, выполняемых процессором. Это позволяет нелинейной последовательности инструкций быть решенными, с помощью результата предыдущих инструкций. Цель инструкции перехода состоит в том, чтобы условно переместиться в разные места памяти инструкций. Это позволяет принимать решения в программном потоке, что является одним из требований для Тьюринго-завершенной вычислительной машины[19]. Кодировка слова инструкции показана на рисунок 3.10.
31-27 | 26-22 | 21 | 20 | 19 | 18 | 17 | 16 | 15-0 |
Опкод | Ri | C | N | V | Z | O | Управление | Адрес |
Рисунок 3.10: Слово инструкции по управлению потоком
ЦП использует четыре различных режима адресации для вычисления эффективного адреса назначения, аналогичного инструкциям по загрузке и хранению. Эти режимы адресации вместе с тем, как они выбраны, описаны в таблице 3.2, где Rx соответствует регистру Ri в слове инструкции по управлению потоком. Дополнительный уровень управления добавляется в битовые поля C, N, V и Z, расположенные на битах 21-18 в слове инструкции. Эти биты только влияют на инструкцию перехода и описаны в таблице 3.5. Столбцы C, N, V и Z в этой таблице соответствуют значению битов в слове инструкции управления потоком, а не значению битов в регистре состояния. Однако в логике, чтобы решить, следует ли перейти (в машинном цикле обратной записи), используется фактическое значение бита в регистре состояния (соответствующее тому, который выбран кодом условия). Подробные данные инструкции по управлению потоком описаны в таблице 3.6.
C | N | V | Z | Мнемоники | Описание |
0 | 0 | 0 | 0 | JMP/JU | Безусловный переход |
1 | 0 | 0 | 0 | JC | Прыгнуть, если перенос |
0 | 1 | 0 | 0 | JN | Прыгнуть, если отрицание |
0 | 0 | 1 | 0 | JV | Прыгнуть, если переполнение |
0 | 0 | 0 | 1 | JZ/JEQ | Прыгнуть, если ноль, или равно |
0 | 1 | 1 | 1 | JNC | Прыгнуть, если нету переноса |
1 | 0 | 1 | 1 | JNN | Прыгнуть, если нет отрицания |
1 | 1 | 0 | 1 | JNV | Прыгнуть, если нет переполнения |
1 | 1 | 1 | 0 | JNZ/JNE | Прыгнуть, если не ноль или не равно |
Таблица 3.5: Описание условия перехода
Инструкции | Мнемоника | Опкод | Функция |
Прыгнуть Jump | J{CC}
Значение {CC} зависит от кода условия; |
0x5 | Условно установите PC на эффективный адрес |
Вызов Call | CALL | 0x6 | Поместите PC, а затем SR на стек вызовов, установите PC на эффективный адрес |
Возврат Return | RET | 0x7 | Переместите верхнюю часть стека вызовов в SR, затем введите следующее значение в PC |
Таблица 3.6: Детали инструкции по управлению потоком
3.3.4 Инструкции манипуляции
Инструкции по манипулированию несут ответственность за манипулирование данными в файле регистра. Для большинства инструкций по манипуляции требуется три операнда: один целевой и два исходных операнда. Любая инструкция манипуляции, требующая двух исходных операндов, может либо использовать значение в регистре, либо немедленное значение, расположенное в слове инструкции, в качестве второго исходного операнда. Кодировка слова инструкции для этих вариантов показана в рисунке 3.11 и 3.12 соответственно. Все инструкции манипуляции имеют возможность изменять биты условия в SR после их деятельности, и они все высчитаны через ALU.
31 – 27 | 26 – 22 | 21 – 17 | 16 – 12 | 11 – 0 |
Опкод | Ri | Rj | Rk | 0 |
Рисунок 3.11: Регистр-регистр манипулирование, инструкция, размер слово
31 – 27 | 26 – 22 | 21 – 17 | 16 – 1 | 0 |
Опкод | Ri | Rj | немедленный | 1 |
Рисунок 3.12: Регистр-слово, инструкции немедленного манипулирования
Инструкции | Мнемоника | Опкод | Функции |
Add/Сложение | ADD | 0x8 | Сохранить Rj + SRC2 в Ri |
Subtract/Вычитание | SUB | 0x9 | Сохранить Rj − SRC2 в Ri |
Compare/Сравнение | CMP | 0xA | Вычислить Rj – SRC2 и отменить результат |
Negate/Отрицание | NOT | 0xB | Сохранить ~ Rj в Ri
Символ ~ представляет собой оператор унарного логического отрицания |
AND/И | AND | 0xC | Сохранить Rj & SRC2 в Ri
Символ & представляет собой логический оператор И |
Bit Clear/отчистка бита | BIC | 0xD | Сохранить Rj & ~SRC2 в Ri |
OR/ИЛИ | OR | 0xE | Сохранить Rj | SRC2 в Ri
Символ & представляет собой логический оператор ИЛИ |
Exclusive OR/Исключающее или | XOR | 0xF | Сохранить Rj ^ SRC2 в Ri
Символ & представляет собой логический оператор XOR |
Signed Multiplication/знаковое умножение | MUL | 0x1A | Сохранить Rj × SRC2 в Ri |
Unsigned Division/беззнаковое деление | DIV | 0x1B | Сохранить Rj ÷ SRC2 в Ri |
Таблица 3.7: Детали инструкций по манипулированию
Подробные сведения о инструкциях по манипулированию приведены в таблице 3.7. Значение SRC2 либо представляет регистр Rk для инструкции по манипулированию регистром, либо немедленное значение (знак-расширенный до 32-бит) для инструкции по манипулированию регистром-немедленное.
3.3.4.1 Сдвиг и поворот
Сдвиг и поворот инструкции являются специализированным случаем манипуляции инструкции. Они высчитаны через модуль сдвигателя, и вращение-через-перенос инструкций, имеют возможность изменять бит C внутри SR. Сдвиги логического сдвига всегда будут сдвигаться в битах со значением 0 и отбрасывать смещенные биты. Арифметический сдвиг будет сдвигаться в битах с тем же значением, что и самый значительный бит в исходном операнде, чтобы сохранить правильный знак данных. Как и в других инструкциях по манипулированию, эти инструкции могут использовать содержимое регистра или немедленное значение из слова инструкции для второго исходного операнда. Кодировка слова инструкции для этих вариантов показана на рисуноке 3.13 и 3.14, соответственно.
31-27 | 26-22 | 21-17 | 16-12 | 11-4 | 3-1 | 0 |
Опкод | Ri | Rj | Rk | 0 | Режим | 0 |
Рисунок 3.13: Регистр-регистр сдвига и поворот слова инструкции
31-27 | 26-22 | 21-17 | 16-11 | 10-4 | 3-1 | 0 |
Опкод | Ri | Rj | Немедленный | 0 | Режим | 1 |
Рисунок 3.14: Регистр-слово инструкции немедленного манипулирования
Поле режим в инструкции сдвига и поворота выберите тип сдвига или поворота для выполнения. Все инструкции будут выполнять операцию, определенную полем mode/режим в регистре Rj в качестве исходных данных. Количество битов, что данные будут сдвигателем или вращаться (SRC2) определяется либо значение в регистре Rk или немедленное значение в слове инструкции в зависимости от того, если это регистр-регистр или регистр-немедленное слово инструкции. Сведения о смене и повороте описываются в таблице 3.8.
Инструкции | Мнемоника | Опкод | Режим | Функция |
Сдвиг вправо логический | SRL | 0x10 | 0x0 | Сдвиг Rj правый логически по битам SRC2 и сохраняется в Ri |
Сдвиг влево логический | SLL | 0x10 | 0x1 | Сдвиг Rj левый логически выводится битами SRC2 и сохраняется в Ri |
Сдвиг правой арифметики | SRA | 0x10 | 0x2 | Сдвиг Rj правильно арифметически по битам SRC2 и сохраняется в Ri |
Повернуть вправо | RTR | 0x10 | 0x4 | Поверните Rj по битам SRC2 и сохраняется в Ri |
Повернуть влево | RTL | 0x10 | 0x5 | Поверните Rj, оставленный битами SRC2, и сохраняется в Ri |
Поворот вправо через перенос | RRC | 0x10 | 0x6 | Поверните Rj прямо через перенос битами SRC2 и сохраняется в Ri |
Поворот влево через перенос | RLC | 0x10 | 0x7 | Поверните Rj, оставшуюся через перенос битами SRC2, и сохраняется в Ri |
Таблица 3.8: Сдвиг и поворот детали инструкции
Дизайн простого 32 битного RISC ЦПУ и бэкенд LLVM компилятора.