Статья: Динамическая поддержка расширений процессора в кросс-системе
REGFILE_END()
2.2.2. Описание поведения
К семантике поведения акселератора относятся следующие элементы модели mA: множество ресурсов RA, функция ресурсов rA, множество операций ΨA, множество дескрипторов команд IA и функция декодирования dA (вместе с CA).
2.2.2.1. Операции
Для задания операций из ΨA используется язык C++. Ячейки памяти акселератора доступны в качестве глобальных переменных (регистровые файлы и памяти в виде массивов). Для удобства описания могут объявляться собственные локальные переменные. Также могут быть использованы возможности специальной библиотеки (например, N-битные типы данных INT< N>, UINT< N>, типы данных с фиксированной точкой FIXED< I,F>, операции битовых манипуляций и т.п.). Используемые в операции ресурсы обозначаются в виде вызова функции UseResources(resources) (тем самым задается функция rA). В существующей реализации список используемых в данной операции ресурсов передаются в виде битовой строки, где каждый ресурс соответствует определенному биту. Множество ресурсов RA задается в виде перечисления (enum) со значениями элементов по степеням двойки:
enum Resources {MAC_ADDER=1, MAC_MULTIPLIER=2, ALU_ADDER=4};
Пример 1. Операция по сложению двух 36-ти разрядных чисел:
void ADD_36_36(INT<36>& res, INT<36> a, INT<36> b) {
UseResources(MAC_ADDER);
res = a + b;
}
Пример 2. Операция по перемножению двух 16-ти разрядных знаковых чисел:
void SMUL_16_16(INT<32>& res, INT<16> a, INT<16> b) {
UseResources();
res = a * b;
}
Заданная на C++ операция может быть оформлена в виде отдельной функции (см. примеры выше) или встраиваться непосредственно в тело функции поведения команды (см. примеры в 2.2.2.2).
2.2.2.2. Дескрипторы команд
Дескрипторы команд акселератора из IA задаются соответствующими функциями поведения команд. Функция поведения может принимать аргументы в виде параметров инструкции pi. Тем самым одна функция поведения может описывать набор дескрипторов (один дескриптор соответствует одному конкретному набору значений параметров). Тело функции поведения может описываться на языке C++. Отображение в операции для соответствующих значений состояния команды t неявно задается путем использования специальной функции FinishCycle(). Вызовы данной функции отделяют операции внутри функции поведения, относящиеся к последовательным тактам исполнения (значениям параметра t дескриптора команды). Для описания динамического характера выбора операций в зависимости от состояния акселератора (аргумент дескриптора s) в описании функции поведения команды допускается использование управляющих конструкций языка C, в частности циклов и ветвлений (см. пример 3 ниже). Вызов функции FinishCycle() означает окончание всех операций для текущего такта команды и соответствует управляющему действию next. Возврат из функции поведения команды соответствует управляющему действию end. Использо-вание такого решения позволяет эффективно описывать дескрипторы команд, тем самым определяя потактовое поведение команд акселератора.
Пример 1. Однотактовая команда перемещения между регистрами, содержащая единственную операцию, задаваемую конструкцией
GRF[greg] = LRF[lreg]:
ACC_FUNCTION Move_LREG_GREG(INT<4> lreg, INT<4> greg) {
GRF[greg] = LRF[lreg];
FinishCycle();
}
Пример 2. Двухтактовая команда перемножения и аккумуляции результата. На первом такте происходит перемножение операндов (операция SMUL_16_16 - см. пример 2 в 2.2.2.1), на втором аккумуляция результата (операция ADD_36_36 - см. пример 1 в 2.2.2.1):
ACC_FUNCTION MAC_LREG_GREG(INT<4> grs, INT<4> grt) {
SMUL_16_16 (mulres, GRF[grs], GRF[grt]);
FinishCycle();
ADD_36_36 (ACC, ACC, mulres);