‮Сдвиг по фазе (kincajou) wrote,
‮Сдвиг по фазе
kincajou

Category:

worklog: вычисление адреса перехода

BEQ, BNE, BLT, BLTU, BGE и BGEU - команды условного перехода (например, в конструкции if/else).

Операция сравнения ("равно", "не равно", "меньше", "меньше беззнаковое", "больше или равно" и "больше или равно беззнаковое") выполняется над исходными регистрами rs1 и rs2 и, в случае выполнения условия, к текущему PC прибавляется 12-битное смещение (закодированное прямо в самой этой команде), т.е. переходв озможен на расстояние до +-4К инструкций. Записи в регистр нет.

JAL и JALR - команды безусловного перехода.

JAL извлекает смещение (20 бит) из своего опкода и прибавляет его к текущему PC, в регистре назначения сохраняется значение [PC+4] (т.е. адрес инструкции, следующей за текущей) чтобы можно было перейти обратно. Т.е. возможны переходы на расстояние до +-1М от текущей инструкции.

JALR извлекает 12-битное смещение и прибавляет его к регистру rs1 (base), результат заносится в PC, а в регистре назначения сохраняется значение [PC+4]. Если смещение равно нулю, то осуществляется просто переход по адресу из регистра rs1, а если регистр назначения это r0 (нулевая "затычка"), тогда эту инструкцию можно использовать, например, для возврата из функций.

Команды LUI ("load upper immediate") и AUIPC ("add upper immediate to PC") используются для записи 20-битных констант в регистры. Братец LUI просто заносит в старшие биты указанного регистра 20 бит своего кода, а AUIPC действует ещё хитрее: 20 (старших) бит кода суммируются с текущим PC и результат загружается в регистр назначения. То есть, если выполнить такой условный код (не в каноничной нотации RISC-V):
AUIPC R3, 1000 ; помещаем в R3 результат суммирование [PC+1000]
JALR R2, R3, 20 ; сохраняем [PC+4] в R3, к R3 прибавляем 20 и загружаем результат в PC
...

То мы прыгнем по адресу PC+1000+20, а адрес следующей после JALR инструкции будет сохранён в R2.

Если вместо AUIPC использовать LUI, то переход будет по фиксированному адресу. AUIPC позволяет простым способом реализовать перемещаемый код, т.к. вся адресация становится относительной.

Проблема в том, что раз процессор конвейерный, то на момент выполнения команды JALR результат предыдущей операции AUIPC ещё "едет" по завершающим стадиям конвейера и в R3 лежит что-то совсем не то. И надо либо ждать полного выполнения инструкции (а это ещё два такта для классического пятистадийного конвейера), либо надо как-то извлекать значение результата вычислений прямо с выхода АЛУ, не дожидаясь полного окончания цикла.

Вощем, вырисовывается ещё один блок, который будет совмещать в себе функции обхода конвейера и заодно работать кросс-мультиплексором для команд условного перехода (где одновременно выполняется и сравнение двух каких-то регистров, и суммирование константы со значением PC, т.е. задействованы сразу и АЛУ, и компаратор).

Посчитал-прикинул. Никак не меньше чем 9 шин по 32 бита, 6 на вход в блок и 3 на выход. Схемотехнически всё просто, но растащить 288 сигналов по двухслойной плате будет интересной задачкой...

Вряд ли я буду делать BTB и прочие хитрые штуки, поэтому после каждого перехода (условного или безусловного) надо будет сбрасывать конвейер - потеря производительности неизбежна, но если не использовать обход, тогда она будет ещё больше.
Tags: risc-v, worklog
Subscribe

  • Абсолютли!

  • Мета

    Канал о фейлах .. эхм.. как бы это.. сам.

  • Неужели

    "Протон", который уже давно заменён на "Ангару" и больше не летает, сегодня должен вытащить "Науку", пролежавшую более 20 лет на Земле, и…

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments