ВМ2: Особенности работы кэша
Особенности работы кэша
Любая команда перед декодированием попадает в кэш команд BIR (буферный регистр инструкций). Если кэш команд недействительный (предыдущее значение уже использовано, а новое еще не загружено), то блок декодирования команды будет ожидать загрузки нового значения в BIR. Существует несколько событий и состояний процессора, делающих кэш команд недействительным.
События отличаются от состояния тем, что события имеют кратковременный характер и длятся не более 1-2 тактов CLCI, а состояния могу длиться более продолжительное время.
События сбрасывающие кэш:
- RESET - событие сброса микропроцессора по ACLO.
- CLR_CEND - происходит после защелкивания текущего значения кэша по сигналу IR_STB в регистре инструкций IR. Это необходимо для того, чтобы сообщить кэшу, что кэшированную команду использовали, и можно кэшировать новую.
Состояния сбрасывающие кэш:
- BUF_RES - возникает в двух случаях:
- Если при записи в память, регистр адреса RA совпал регистром PC1. А регистр PC1 всегда указывает на следующее слово команды, в независимости от того, кэшировано оно в BIR или нет.
- От блока таймаута пришло событие TO_RPLY.
Отменяется это событие по RESET или же по записи в регистр R7, кроме шагов микропрограммы 0x01 (выборка кэшированной инструкции), и шагов 0x10 и 0x16 (кэширование следующего слова команды/данных в некоторых операциях с двумя операндами, когда источник расположен в памяти).
- WORD27 - состояние запрета кэша команд. Запрашивается некоторыми методами адресации, чтобы использовать кэшированное слово следующей инструкции в качестве данных.
Отменяется по RESET или ABORT, либо же по микрокоманде ожидания готовности BRD. Упрощенно использование этого состояния микропрограммой выглядит так:
- Запретить кэш. При этом автоматически PC1=PC2 (в обычном режиме PC2 опережает PC1 на 2, и указывает на следующий за кэшированным словом адрес).
- Использовать BIR по своему усмотрению, например, как смещение для адресации X(Rn).
- Запросить чтение в BRD какого-то слова (необязательный шаг).
- Ожидать готовности BRD (момента, когда слово прочитано) и отменить запрещение кэша.
Следует заметить, что отмена события запрещения кэша не делает содержимое кэша действительным, и микропрограмма выборки следующей команды должна быть запрошена не по адресу 0x01 (выборка кэшированной инструкции), а по адресу 0x21 (выборка некэшированной инструкции). Только после этого кэш команд станет опять действительным и может быть использован.
- IO_CMD - принудительный сброс BIR в микрокомандах 0x21 (выборка некэшированной инструкции) и в инструкции процессора RESET. Состояние длится до тех пор, пока блок ввода-вывода не освободится, и не начнет операцию чтения (кэширования) команды (сигнал IOP_STB). На протяжении всего этого состояния всякое завершение возможного предыдущего асинхронного цикла чтения в регистр BIR будет игнорироваться. Это сделано для того, чтобы не произошла ситуация следующего рода - в команде кэширования (0x21) запросили чтение BIR, а предыдущая микрокоманда тоже читала BIR, и асинхронный результат этого чтения с запозданием прилетел в кэш и нарушил всю логику работы.
Теперь перейдем к единственному сoбытию, которое делает кэш действительным. Это завершение чтения регистра BIR. Если ни одно из предыдущих событий и состояний не активно, то после чтения BIR, кэш становится действительным и может быть использован для декодирования команды. Чтение BIR запрашивается в следующих микрокомандах:
- 0x01 (выборка кэшированной инструкции). В момент защелкивания из BIR кода инструкции в регистр инструкции IR сразу инициализируется запрос чтения в BIR следующего слова.
- 0x10 и 0x16 (кэширование следующего слова команды/данных) в некоторых операциях с двумя операндами, когда источник расположен в памяти.
Ошибки использования кэша:
В некоторых микрокомандах содержатся ошибки, приводящие к сбою или ошибкам в работе кэша. Ошибка - это однократное событие, сбой - это устойчивое состояние.
- Ошибка команд расширенной арифметики EIS (MUL, DIV, ASH и ASHC). Из-а того, что порядок кодирования операндов в слове инструкции поменян местами относительно всех остальных команд, стандартные схемы определения модификации R7, если этот регистр задействован в качестве приемника - не работают. Из-за чего после окончания EIS-инструкции идет переход на микрокоманду 0x01 (выборка кэшированной инструкции) а не на микрокоманду 0x21 (выборка некэшированной инструкции). Это приводит к тому, что даже если R7 в ходе выполнения инструкции изменился, выборка следующей инструкции будет из кэша BIR, а там находится инструкция следующая за EIS. Однако, далее работа кэша восстанавливает в нормальном режиме.
- Ошибка адресации (R7) в качестве источника в двухоперандных команд, приводящая к сбою в работе кэша.
При работе с кэшем обязательно соблюдать следующее правило - сперва сделать недействительным текущее значение кэша (не важно, использовалось оно или нет), и только потом запрашивать чтение нового значения в кэш. Если эту последовательность не соблюсти, то произойдет ситуация наложения новых данных в кэше на старые, результат которого будет зависеть от времени прихода асинхронного ответа на запрос чтения контроллера ввода-вывода.
Выполнение микрокоманды 0x01 (выборка кэшированной инструкции) может начинаться как минимум тремя способами (четвертый относится к блоку таймаута, и здесь не рассматривается):
- Кэш недействительный, ожидаем чтение нового значения BIR, которое запросила предыдущая микрокоманда 0x21 (выборка некэшированной инструкции).
- Кэш действительный, можно сразу использовать значение BIR. Фоновых асинхронных запросов чтения шины нет.
- Кэш действительный, можно сразу использовать значение BIR. Не окончен фоновой запрос чтения шины в регистр BIR. Является последствием сбоя в работе кэша.
Рассмотрим возникновение ситуации описанной в третьем пункте.
Микрокоманда выполнения операции с двумя операндами, когда источник находится в памяти, имеет ошибку следующего вида:
Типы адресаций источника (R7)+, @(R7)+, X(Rn) и @X(Rn) имеют специальные обработчики, использующие BIR в качестве данных и сбрасывающие кэш.
Типы адресаций источника (R7), -(R7), @-(Rn) специальных обработчиков не имеют, и выполняются для всех регистров одинаково. Кэш не сбрасывается.
Вторым этапом микропрограмма определяет, нужно ли делать кэширование только что использованного BIR, или не надо. И определяет она это по признаку RI2, который установлен, если адресация источника (R7), (R7)+, -(R7), @(R7)+, @-(R7), X(Rn), @X(Rn). Как видно, адресации (R7), -(R7), @-(Rn) тоже попадают в обработчик компенсации, хотя кэш НЕ использовали и НЕ сбрасывали.
Обработчик компенсации запрашивает цикл чтения BIR по адресу PC2, затем делает PC1=PC2, и PC2=PC2+2.
Далее, если приемник - регистр, выполняется цикл ALU для заданной инструкции, и если приемник не равен R7, идет переход на адрес 0x01 (выборка кэшированной инструкции). Таким образом, если асинхронный цикл чтения BIR, запрошенный обработчиком компенсации, успел завершиться до защелкивания BIR в IR, кэш продолжит нормальную работу. Если же цикл чтения BIR завершился после защелкивания уже имеющегося BIR в IR, то кэш сразу же станет действительным, но все равно будет выдан запрос чтения BIR. Таким образом, декодироваться и выполняться будет инструкция запрошенная в предыдущем цикле, т.е. с отставанием на одно слово. И этот процесс будет повторяться, пока какая-либо команда не сделает кэш недействительным одним из описанных выше способов.
В случае, если приемник - память, то после компенсации будет переход на микрокоманду 0x17 и декодирование адресации приемника.
Что происходит с указателями PC1 и PC2 после обработки адресаций источника (R7), -(R7), @-(Rn):
Код:
(R7):
RA=PC1 IO_RD, IO_IN // Инициировать цикл чтения шины
PC2=PC1
-(R7):
PC2=PC1-2
RA=PC2 IO_RD, IO_IN // Инициировать цикл чтения шины
@-(R7):
PC2=PC1-2
RA=PC2 IO_RD, IO_IN // Инициировать цикл чтения шины
//----------------------------------------------------------------------
WAIT_BRD // Ожидание готовности чтения BRD
ACC=BRD
RA=ACC IO_RD, IO_IN // Инициировать цикл чтения шины
Как видно, никакого нарушения в логике работы в этих местах не будет, и все последующие нарушения происходят исключительно из-за отсутствия сброса кэша.