RISC-V: варианты немедленного кодирования
В Руководстве по набору инструкций RISC-V, ISA уровня пользователя, я не мог понять раздел 2.3 "Варианты немедленного кодирования", стр. 11.
Существует четыре типа форматов команд R, I, S и U, затем есть варианты типов S и U, которые представляют собой SB и UJ, которые, как я полагаю, означают Branch и Jump, как показано на рисунке 2.3. Тогда есть типы Immediate, произведенные инструкциями RISC-V, показанными на рисунке 2.4.
Итак, мои вопросы: зачем нужны SB и UJ? и зачем тасовать Немедленные биты таким образом? что значит сказать "Непосредственное, произведенное инструкциями RISC-V"? и как они производятся таким образом?
2 ответа
Для ускорения декодирования базовый RISC-V ISA размещает наиболее важные поля в одном и том же месте в каждой инструкции. Как вы можете видеть в таблице форматов команд,
- Основной код операции всегда находится в битах 0-6.
- Регистр назначения, если он присутствует, всегда находится в битах 7-11.
- Первый регистр источника, если он присутствует, всегда находится в битах 15-19.
- Второй регистр источника, если он присутствует, всегда находится в битах 20-24.
Другие биты используются для младшего кода операции или других данных для инструкции (funct3
в битах 12-14 и funct7
в битах 25-31) и для немедленного. Сколько битов можно использовать для непосредственного использования, зависит от количества номеров регистров в инструкции:
- Инструкции с одним регистром назначения и двумя исходными регистрами (R-тип) не имеют немедленного действия, например, добавление двух регистров (
ADD
); - Команды с одним регистром назначения и одним регистром источника (I-типа) имеют 12 битов для непосредственного, например, добавление одного регистра с непосредственным (
ADDI
); - Инструкции с двумя исходными регистрами и без регистра назначения (S-типа), например, инструкции хранения, также имеют 12 битов для непосредственных данных, но они должны быть в другом месте, поскольку номера регистров также находятся в другом месте;
- Наконец, инструкции только с регистром назначения и без младшего кода операции (U-типа), например
LUI
, может использовать 20 бит для непосредственного использования (основной код операции и номер регистра назначения вместе должны иметь 12 бит).
Теперь подумайте с другой точки зрения об инструкциях, которые будут использовать эти непосредственные значения. Самым простым пользователям, I-немедленным и S-немедленным, требуется только 12-разрядное значение с расширенным знаком. Команды U-немедленного требуют непосредственных в старших 20 битах 32-битного значения. Наконец, инструкции перехода / перехода нуждаются в немедленном расширении знака в младших битах значения, за исключением младшего бита, который всегда будет нулевым, поскольку инструкции RISC-V всегда выровнены по четным адресам.
Но почему непосредственные биты перемешаны? Подумайте на этот раз о физической схеме, которая декодирует непосредственное поле. Поскольку это аппаратная реализация, биты будут декодироваться параллельно; каждый бит в непосредственном выходе будет иметь мультиплексор, чтобы выбрать, из какого входного бита он поступает. Чем больше мультиплексор, тем он дороже и медленнее.
Следовательно, "перетасовка" непосредственных битов в кодировке команд состоит в том, чтобы каждый выходной непосредственный бит имел как можно меньше опций входных битов команд. Например, непосредственный бит 1 может поступать только из командных битов 8 (S-немедленный или B-непосредственный), 21 (I-немедленный или J-непосредственный) или постоянного нуля (U-немедленный или R-тип команды, который не имеет непосредственного). Непосредственный бит 0 может поступать из командных битов 7 (S-немедленный), 20 (I-непосредственный) или постоянного нуля. Непосредственный бит 5 может исходить только от командного бита 25 или постоянного нуля. И так далее.
Бит 31 команды является особым случаем: для RV-64 биты 32-63 непосредственных битов всегда являются копиями бита команды 31. Такое сильное разветвление добавляет задержку, которая была бы еще больше, если бы также требовался мультиплексор, поэтому у него есть только одна опция (кроме константы ноль, которую можно обработать позже в конвейере, игнорируя всю немедленную).
Также интересно отметить, что только основной код операции (биты 0-6) необходим, чтобы знать, как декодировать немедленное, поэтому немедленное декодирование может быть выполнено параллельно с декодированием остальной части инструкции.
Итак, отвечая на вопросы:
- SB-тип удваивает диапазон ветвей, поскольку инструкции всегда выровнены по четным адресам;
- UJ-тип имеет тот же общий формат команд, что и U-тип, но непосредственное значение находится в младших битах, а не в старших битах;
- Непосредственные биты перетасовываются, чтобы уменьшить стоимость декодирования непосредственного значения путем уменьшения количества вариантов выбора для каждого выходного непосредственного бита;
- Таблица "немедленное создание с помощью инструкций RISC-V" показывает различные виды непосредственных значений, которые могут быть декодированы из инструкции RISC-V и откуда в инструкции берется каждый бит;
- Они создаются для каждого непосредственного выходного бита с использованием основного кода операции (биты 0-6) для выбора бита инструкции ввода.
Кодирование сделано для того, чтобы попытаться максимально упростить реальную аппаратную реализацию, а не дать читателю понять с первого взгляда.
На практике компилятор генерирует выходные данные, и поэтому не имеет значения, если пользователю будет нелегко это понять.
Когда это возможно, тип SB пытается использовать те же биты для тех же непосредственных битовых позиций, что и тип S, что сводит к минимуму сложность проектирования аппаратного обеспечения. Так что imm[4:1] и imm[10:5] находятся в одном и том же месте для обоих. Самый верхний бит непосредственных значений всегда находится в позиции 31, так что вы можете использовать этот бит, чтобы решить, нужно ли расширение знака. Опять же, это облегчает аппаратное обеспечение, потому что для нескольких типов команд верхний бит используется для выбора расширения знака.
Кодирование инструкций RISC-V выбрано для упрощения декодера.
2.2 Базовые форматы инструкций
RISC-V ISA сохраняет регистры источника (rs1 и rs2) и назначения (rd) в одной и той же позиции во всех форматах для упрощения декодирования. За исключением 5-битных непосредственных команд, используемых в инструкциях CSR (глава 9), немедленные операции всегда расширяются по знаку и обычно упаковываются в сторону самых левых наиболее доступных битов в команде и выделяются для уменьшения сложности оборудования. В частности, бит знака для всех непосредственных сообщений всегда находится в бите 31 инструкции для ускорения схемы расширения знака.
2.3 Варианты немедленного кодирования
Единственное различие между форматами S и B заключается в том, что 12-битное поле непосредственного ввода используется для кодирования смещений ветвлений, кратных 2, в формате B. Вместо того, чтобы сдвигать все биты в кодировке инструкций сразу влево на один аппаратно, как это обычно делается, средние биты (imm[10:1]) и знаковый бит остаются в фиксированных положениях, а младший бит в формате S (inst[7]) кодирует бит старшего разряда в формате B.
Точно так же единственное различие между форматами U и J состоит в том, что 20-битное непосредственное смещение сдвигается влево на 12 бит, чтобы сформировать U, и на 1 бит, чтобы сформировать J, непосредственно. Расположение битов команд в форматах U и J выбрано сразу для максимального перекрытия с другими форматами и друг с другом.
Причина перетасовки непосредственного в форматах SB/UL также была объяснена в спецификации RISC-V.
Хотя более сложные реализации могут иметь отдельные сумматоры для вычислений переходов и переходов и поэтому не получат выгоды от сохранения постоянного местоположения непосредственных битов для разных типов инструкций, мы хотели снизить стоимость оборудования для простейших реализаций. Путем ротации битов в кодировании команд B и J немедленно вместо использования динамических аппаратных мультиплексоров для умножения непосредственного на 2, мы сокращаем разветвление сигнала команды и немедленные затраты мультиплексора примерно в 2 раза. Скремблированное немедленное кодирование добавит незначительные статическая или опережающая компиляция. Для динамической генерации инструкций есть небольшие дополнительные накладные расходы, но наиболее распространенные короткие прямые переходы имеют прямое непосредственное кодирование.