Динамическая поддержка расширений процессора в кросс-системе
В.В. Рубанов, А.И. Гриневич, Д.А. Марковцев, М.А. Миткевич
Аннотация.
В статье рассматривается задача моделирования расширений процессора в виде акселераторов (сопроцессоров) для автоматической настройки кросс-системы, включающей в себя ассемблер, компоновщик, симулятор, отладчик и профилировщик. Рассматриваемый подход основан на описании моделей акселераторов на разработанном языке спецификации с последующим использованием этих моделей кросс-системой во время ассемблирования, потактовой симуляции и отладки прикладных программ, содержащих команды акселераторов, не известные на этапе построения основного инструментария (определяемые соответствующими моделями). В статье рассматривается математическая модель поддерживаемых акселераторов и интерфейса с основным процессором. Описывается язык спецификации конкретных моделей акселераторов, дается обзор технологий настройки кросс-системы для поддержки описанных таким образом расширений.
1. Введение
В статье рассматривается задача моделирования расширений процессора в виде акселераторов (сопроцессоров) для автоматической настройки инструмен-тария кросс-разработки для поддержки этих расширений. Под инструмен-тарием кросс-разработки (кросс-системой) понимается набор программных компонентов (ассемблер, компоновщик, симулятор, отладчик и профилиро-вщик) для разработки прикладных программ с использованием хост-машины, отличной от целевой аппаратуры. Под поддержкой расширений кросс-системой подразумевается ассемблирование, потактовая симуляция и отладка прик-ладных программ, содержащих команды, не известные на этапе построения основного инструментария (реализуемых специфическими для пользователя акселераторами). Рассматриваемый подход основан на предоставлении пользо-вателю возможности описать модели акселераторов на разработанном языке спецификации с последующим использованием этих моделей для настройки компонентов кросс-системы.
Данная задача возникает в связи с тем, что многие современные аппаратные решения строятся на основе использования стандартного процессорного ядра со специализированными расширениями в виде акселераторов. Часть системы команд ядра зарезервирована для команд обращения к интерфейсу запуска инструкций акселераторов. Однако семантика реальных действий и вычис-лений, которые инициируют такие команды, определяется конкретными акселераторами и не зависит от основного процессора. Производитель ядра и производители акселераторов могут быть разными компаниями, при этом инструментарий кросс-разработки от производителя основного процессора должен уметь поддерживать неизвестные для него расширения аппаратуры, которые создаются заказчиками. В данной работе под расширениями процессора понимается добавление акселераторов, которые могут вводить в систему новые элементы памяти (регистры, памяти данных) и определять семантику команд запуска инструкций акселераторов. Аппаратура на базе основного процессора с акселераторами представляется для прикладного программиста как вычислительная система с единой системой команд и одной программой. Память системы состоит из памяти основного процессора, разделяемой памяти и локальных памятей акселераторов.
Для выделения класса поддерживаемых акселераторов и интерфейса с процессором была разработана абстрактная математическая модель, позво-ляющая моделировать состояние и поведение широкого класса акселераторов с потактовой точностью. Для описания конкретных моделей, в рамках данной абстрактной, предложен язык спецификации (ISE), разработаны средства визуального редактирования спецификаций на этом языке и средства анализа и выявления ошибок в спецификациях. Реализован подход интерактивной пере-настройки кросс-системы, заключающийся в настройке компонентов (ассемблер, дисассемблер, симулятор, отладчик) на основании интерпретации описаний моделей акселераторов. Система используется в коммерческой эксплуатации, в ней успешно реализованы модели реальных акселераторов.
Статья состоит из введения, трех глав и заключения. В первой главе описы-вается подход к моделированию акселераторов, вводится абстрактная модель акселератора и средства описания конкретных моделей на языке ISE. Во второй главе содержится описание технологии интерактивной перенастройки кросс-системы для поддержки заданных пользователем моделей акселератов. Третья глава содержит краткий обзор смежных работ. В заключении приводятся практические результаты, полученные при эксплуатации разработанной системы. Приводится план будущих направлений развития темы.
2. Моделирование расширений процессора
В данной главе рассматриваются вопросы моделирования расширений процес-сора в виде акселераторов. Для этого вводится абстрактная (математическая) модель акселератора, охватывающая достаточно широкий класс возможной аппаратуры (см. 2.1). В рамках этой абстрактной модели определяются сред-ства описания конкретных моделей акселераторов в виде файлов на специа-льном языке ISE (см. 2.2). Описанные таким образом модели акселераторов используются для автоматической конфигурации компонентов кросс-системы - симулятора, ассемблера, дисассемблера, отладчика и профилировщика (см. главу 3).
2.1. Абстрактная модель акселератора
В нашей модели акселератор является сопроцессором, команды которому выдаются основным процессором. Акселератор работает синхронно с процессором. Акселератор может иметь собственную локальную память и имеет доступ к общей памяти между процессором и всеми акселераторами.
2.1.1. Состояние акселератора
2.1.1.1. Память акселератора
Ячейка памяти представляет собой набор двоичных переменных (далее битов), с возможными значениями 0 или 1. Число битов определяет разрядность ячейки. Набор из одной или более ячеек одинаковой разрядности образует область памяти. Набор из одной или более областей образует память. Память будем обозначать большой буквой S. Состояние ячейки памяти определяется набором конкретных значений всех ее битов. Состояние памяти определяется состоянием всех ячеек ее областей. Состояние памяти будем обозначать маленькой буквой s. Обозначим через N сумму разрядностей всех ячеек памяти S, тогда память может находиться в одном из 2N состояний. Множество состояний памяти будем обозначать {s}. Заметим, что это множество однозначно задается структурой памяти. Дескриптор структуры памяти представляет собой следующий набор чисел: число областей O и набор из O пар (Wi, Si), задающих разрядность Wi ячеек области и их количество Si.
В нашей модели память системы состоит из памяти основного процессора SP, разделяемой памяти SS и локальных памятей акселераторов Sa:
, - число акселераторов
Рассмотрение памяти процессора не принципиально для данной статьи, так как акселератор имеет доступ только к разделяемой и своей локальной памяти. Пара из этих памятей формирует полную память акселератора:
SA={SS,Sa}
Множество возможных состояний памяти акселератора обозначим как {S}A={S}Sx{S}a. Каждая область в локальной и разделяемой памяти характе-ризуется скоростью доступа - числом, означающим, сколько тактов проходит после записи в ячейку этой области, прежде чем измененное значение может быть прочитано; до этого момента при чтении считывается старое значение.
Обычно в памяти акселератора можно выделить следующие области:
Набор из одной или более памятей данных
Набор из одного или более регистровых файлов
Одиночные регистры
2.1.1.2. Управляющее состояние
Акселератор имеет фиксированное количество управляющих слотов, совокупность которых обозначается pA. Каждый слот имеет номер, который далее будет отождествляться с соответствующим слотом. Каждый слот Li представляет собой пару целочисленных переменных (полей): поле номера команды nf и поле состояния команды t. Множество значений поля команды {nf} конечно. Ноль всегда принадлежит {nf}. Существует взаимно однозначное соответствие между {nf} и множеством дескрипторов команд, определение которого будет дано ниже. Поэтому мы будем отождествлять номер и соответсвующий дескриптор f. Множество значений поля состояния команды есть натуральные числа (включая 0). Состояние слота с номером n обозначается ln=(nf,t) и определяется значениями полей этого слота. Множество возможных состояний слота {l}n={nf}xN. Слот в состоянии (0, 0) называется свободным, в ином случае активным. Управляющим состоянием p акселератора называется совокупность состояний всех его управляющих слотов. Множество управляющих состояний акселератора обозначим {p}A={l}NE, где Ns число слотов акселератора. Активные слоты соответствуют выполняющимся командам акселератора, число управляющих слотов задает максимальное количество параллельно выполняющихся команд. В состоянии активного слота значение поля номера команды задает выполняющуюся команду, а значение поля состояния команды соответствует количеству тактов, прошедших с начала выполнения этой команды.
2.1.1.3. Состояние акселератора
Состояние акселератора a задается парой из состояния памяти и управляющего состояния: a={s, p}. Множество состояний акселератора обозначим как {a}A={S}Ax{p}A.
Элементом состояния акселератора называется любая ячейка памяти акселератора или любой управляющий слот. Состоянием элемента называется соответственно состояние ячейки или слота. Параллельной композицией функций φ1,φ2,...,φn (заданных на множестве состояний акселератора) назовем функцию ω = φ1||φ2||...||φn(также заданную на множестве состояний акселератора), получаемую следующим образом: пусть множество всех элементов состояния акселератора, Ai - множество элементов, состояние aα которых было изменено функцией .
Если пересечение всех Ai,i=1..n не пустое множество, то значение функции ω не определено. В ином случае значение ω задается следующим образом:
, здесь a`α и a`α - новое и старое состояние элемента соответственно
2.1.2. Модель акселератора
Операцией [элементарной] называется, заданная на множестве состояний памяти акселератора {s}A (см. 2.1.1.1) функция ψ, формирующая следующее состояние памяти акселератора на основе предыдущего. Операции соответствуют действиям, которые могут быть выполнены за один такт (например, сложение двух регистров):
ψ : {s}A -> {s}A
Множество операций акселератора обозначим ΨA={ψ}. Для любого акселератора в этом множестве присутствует так называемая пустая операция, не изменяющая состояние и обозначаемая ψ0.
Каждая элементарная операция характеризуется функциональными ресурсами, которые необходимы для выполнения этой операции. Обозначим множество всех ресурсов акселератора как RA, а множество всех его подмножеств (включая пустое) как pA. Функция rA, отображающая множество операций ΨA на множество pA, называется функцией ресурсов. Она задает набор ресурсов для каждой операции в ΨA:
rA : ΨA -> PA
Обозначим множество всех подмножеств в ΨA, которые состоят из операций, использующих не пересекающиеся ресурсы, как ΩA:
Таким образом, элемент множества ΩA задает группу операций {ψi}, которые могут выполняться параллельно (в рамках одного такта). Применением параллельной композиции (см. выше) этот элемент задает функцию на множестве состояний памяти акселератора {s}A. Далее элементы множества ΩA будем отождествлять с задаваемыми ими функциями и называть комплекс-операциями. Заметим, что в этом смысле .
Определим два управляющих действия: продвижения next и окончания end. Каждое представляет собой параметрическую функцию на множестве управляющих состояний акселератора. Параметром функции является номер слота . Действие next увеличивает на 1 значение поля состояния команды t для слота, заданного параметром nl.
Действие end переводит соответствующий слот в холостое состояние.
Множество из этих управляющих действий обозначим UA={next,end}.
Дескриптором команды акселератора называется функция f, вычисляющая пару из комплекс-операции и управляющего действия на основании состояния памяти акселератора и состояния команды (см. 2.1.1.2):
Множество дескрипторов команд акселератора обозначается IA={fi}. Это множество конечно и каждому элементу f приписывается номер (например, в порядке возрастания машинного кода в соответствии с отображением, задаваемым функцией декодирования, см. ниже). При этом для дескриптора команды всегда верно следующее (единственность конца команды):
Дескриптор команды f однозначно задает функцию потактового поведения команды bf, определенную на множестве состояний акселератора и параметризуемую номером слота nl. Значение функции bf не определено, если значение поля номера команды в соответствующем слоте nl не совпадает с номером соответствующего дескриптора f. В ином случае функция bf(nl):{aA} -> {aA} задается следующим образом:
На основании состояния памяти s и значения поля состояния команды t в слоте c номером nl c помощью дескриптора команды определяется пара из комплекс-операции ω и управляющего действия u:
{ω,u} = f{s,t}
C помощью ω определяется следующее состояние памяти s`=ω(s), а управляющее действие задает следующее управляющее состояние p`=u(nl,p). Пара (s`,p`) задает значение bf(nl,s,p).
Таким образом, множество дескрипторов команд однозначно задает множество функций потактового поведения BA, имеющее столько же элементов.
Множество кодов инструкций акселератора CA={ci} представляет собой множество двоичных чисел одинаковой разрядности. Каждый элемент этого множества соответствует одному из возможных значений поля код инструкции акселератора в машинном коде команды запуска акселератора (см. 2.1.3.1).
Функция декодирования dA задает отображение множества кодов инструкций акселератора CA на множество дескрипторов команд IA:
dA:CA -> IA
Функция декодирования однозначно задает декодер акселератора - функцию DA:
DA:CAx{p}A -> {p}A:
Функция DA определяется следующим образом: если , то , иначе значение DA не определено. Иными словами, в случае наличия свободного управляющего слота декодер инициирует состояние этого слота в (f,1), где f определяется по коду инструкции с помощью функции декодирования dA.
Тактовая функция TA на множестве состояний акселератора {a}A, определяет изменение состояния акселератора на каждом такте:
TA:{a}A -> {a}A
Эта функция однозначно задается параллельной композицией (см. 2.1.1.3) функций потактового поведения bf, соответствующих дескрипторам команд f, заданным в поле nf каждого активного управляющего слота. Иными словами для каждого такта управляющее состояние акселератора определяет набор активных команд, характеризуемых функциями потактового поведения. Параллельная композиция этих функций задает отображение TA (поведение акселератора) для текущего такта. Если активных слотов нет, то состояние акселератора не меняется.
Абстрактная модель акселератора MA определяется следующими описанными выше элементами:
MA={SA,PA,CA,DA,TA}
2.1.3. Симуляция акселератора
Для симуляции акселератора, заданного моделью MA (см. 2.1.2), необходим генератор тактов, а также определенное начальное состояние памяти . В начальном управляющем состоянии p0 все слоты свободны. В рассматриваемой системе акселераторы и основной процессор работают тактово-синхронно (тактовый генератор единый для всей системы), то есть такт работы акселератора равен такту работы процессора. Кроме тактового генератора, единственным внешним событием для акселератора является выдача очередной команды основным процессором (см. 2.1.3.1 ниже).
2.1.3.1. Запуск команд акселератора
В рассматриваемой модели аппаратуры множество команд основного процессора должно иметь непустое подмножество, представляющее собой команды запуска акселераторов. Такие команды инициируют запуск определенной инструкции соответствующего акселератора. С точки зрения основного процессора команда запуска акселераторов определяется тремя полями машинного кода (порядок полей несущественен, также поля не обязательно должны быть непрерывными):
{КОП, номер акселератора, код инструкции акселератора}
Действия основного процессора при выполнении команды запуска акселератора заключаются в активации акселератора с номером в соответствующем поле и выдаче этому акселератору кода инструкции акселе-ратора для дальнейшего декодирования и выполнения команды в самом акселераторе параллельно с работой процессора. Для основного процессора выполнение команды запуска акселератора всегда занимает один такт. В терминах абстрактной модели выдача команды акселератора основным процессором заключается в передаче кода инструкции акселератора в функцию декодера акселератора DA ( CA это подмножество множества значений поля код инструкции акселератора). За один такт процессор может выдать не более одной команды акселератора. Заметим, что код инструкции акселератора в свою очередь может содержать КОП команды акселератора и операнды.
Акселератор может параллельно выполнять несколько многотактовых команд, в том числе с одинаковым дескриптором. То есть основной процессор может выдавать новую команду акселератора, до того как отработали предыдущие команды. В рамках рассматриваемой модели это возможно, если все операции, выполняемые параллельно на каждом такте, используют непересекающиеся ресурсы (см. 2.1.2). На практике это возможно, если позволяет конвейер и функциональные устройства акселератора, при этом ответственность за корректную (своевременную) выдачу команд акселератора лежит на прикладном программисте.
2.1.3.2. Тактовое поведение акселератора
В ответ на событие от тактового генератора, в рассматриваемой модели действия акселератора сводятся к изменению состояния в соответствии со своей тактовой функцией TA. Эта функция определяет поведение акселератора на каждом такте.
2.1.3.3. Обмен данными и синхронизация с процессором
Обмен данными между процессором и акселераторами осуществляется через разделяемую (общую) память (см. 2.1.1.1). Заметим, что дополнительная информация от процессора к акселератору может также поступать в виде параметров инструкции (см. 2.1.3.1). Заметим, что разные акселераторы не имеют доступа к локальной памяти друг друга.
Разделение доступа к общей памяти в нашей модели соответствует типу CREW (Common Read Exclusive Write). Это означает, что процессор и акселераторы могут одновременно (в рамках текущего такта) читать из ячейки памяти, однако одновременная запись запрещена. В рассматриваемой модели области памяти могут иметь задержку записи, характеризуемую скоростью доступа к памяти (см. 2.1.1.1). По умолчанию, все области памяти имеют задержку 1, то есть изменения могут быть прочитаны только на следующем такте (flip-flop модель). Заметим, что если задержка больше ноля, то возможна одновременная запись и чтение одной и той же ячейки, при чтении считывается предыдущее значение.
Команды акселератора могут занимать фиксированное или переменное (в зависимости от данных) число тактов. С точки зрения прикладного программиста (компилятора) существует три способа синхронизации вычислений основного процессора и результатов работы определенной команды акселератора:
Когда команда акселератора всегда имеет фиксированное число тактов выполнения, программист может статически просчитать, когда будут готовы результаты вычислений (процессор и акселераторы работают синхронно, см. 2.1.3).
Акселератор в процессе выполнения может выставлять определенные флаги (менять ячейки) в общей памяти. Программа основного процессора может считывать значения этих флагов и определять готовность результатов вычислений акселератора.
Частным случаем пункта 2 является вызов акселератором прерывания основного процессора. Обработчик прерывания может прочитать результаты вычислений акселератора.
2.2. Средства описания конкретных моделей акселераторов
Для задания конкретной модели акселератора необходимо определить следующие параметры, множества и функции:
Соответствующие определения были даны в 2.1.1 и 2.1.2, где также было показано, что они однозначно задают все элементы абстрактной модели:
Для описания конкретных моделей акселераторов в ИСП РАН был разработан язык спецификации ISE (Instruction Set Extension). Кроме собственно спецификации соответствующих элементов конкретной модели акселератора (см. выше), в язык также входят средства описания дополнительной информации об ассемблерном синтаксисе команд акселератора, отображении ассемблерных команд в машинные коды и описание форматов для визуализации областей памяти в отладчике. Модель акселератора далее будет отождествляться со спецификацией этой модели на языке ISE.
2.2.1. Дескриптор структуры памяти
Существуют отдельные синтаксические конструкции для описания следующих типов областей памяти:
Памяти данных
Регистровые файлы
Одиночные регистры
С помощью этих конструкций можно задать дескриптор структуры памяти (см. 2.1.1.1).
Пример. Структура памяти простого акселератора:
две памяти данных LDM и TM размером 2048 слов каждая с разрядностью 16 и 64 бита со скоростью доступа 3 такта
Регистровый файл GRF из двух 16-ти разрядных регистров GR0 и GR1
Одиночный регистр-аккумулятор ACR разрядностью 36 бит
DECLARE_MEMORY(INT(16, 3), 2048) LDM;
DECLARE_MEMORY(INT(64, 3), 2048) TM;
DECLARE_REGISTERS_FILE(INT(16), 2) GRF;
DECLARE_REGISTER(UINT(36)) ACR;
// debugging names and registers file structure
MEMORY(LDM, "Acc LDM");
MEMORY(TM, "Acc TM");
REGFILE_BEGIN(GRF, "General Registers")
REGISTER(0, "GR0");
REGISTER(1, "GR1");
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);
FinishCycle();
}
Заметим, что две выдачи подряд этой команды процессором приведут к ситуации, когда одновременно будут исполняться две различные стадии этой функции (стадия умножения второй команды и стадия сложения первой команды). Такой эффект может быть использован для моделирования конвейера акселератора.
Пример 3. Команда свертки векторов, расположенных в памятях DM0 и TM0. Длительность команды зависит от данных (длина векторов задается регистром LOOPREG). Заметим, что в теле цикла за один такт выполняются несколько операций, использующих непересекающиеся ресурсы. Для синхронизации с процессором используется механизм прерывания:
ACC_FUNCTION CONV_ACC_DM0_TM0(INT<4> dreg, INT<4> treg) {
SMUL_16_16 (mulres, DM0[AR[dreg]++], TM0[AR[treg]++]);
FinishCycle();
while (LOOPREG>0) {
ADD_36_36 (ACC, ACC, mulres);
SMUL_16_16 (mulres,
DM0[AR[dreg]++], TM0[AR[dreg]++]);
LOOPREG--;
FinishCycle();
}
ADD_36_36 (ACC, ACC, mulres);
InterruptProcessor();
FinishCycle();
}
2.2.2.3. Функция декодирования
Функция декодирования dA задается описанием множества пар из формата машинного слова команды и ссылки на функцию поведения команды:
INSTRUCTION(< format_string>, < invoker_name>);
Формат машинного слова команды задается строкой в следующем алфавите:
Битовые символы: '0' и '1'
Параметрические символы: 'A-Z' и 'a-z'
Групповой символ: '*'
Разделительный символ: '-'
Символы из пунктов 1-3 называются значимыми символами. Заметим, что число значимых символов в строке формата команды должно быть равно разрядности машинного слова в системе.
Непрерывная цепочка параметрических символов задает операнд. Декодер акселератора выделит указанные биты и передаст полученное значение в функцию поведения команды в виде параметра pi. Различные операнды разделяются групповым или разделительным символом. Операнды нумеруются в порядке справа налево.
Битовые символы задают фиксированные значения в соответствующих позициях машинного слова. На месте параметрических и групповых символов в машинном коде команды может быть любое битовое значение. Разделительные символы используются для косметических целей, а также для отделения подряд идущих операндов.
Пример:
INSTRUCTION("11-**-0000-0000-0001-LREG-GREG", Move_LREG_GREG);
Функция поведения MoveLREG_GREG (см. пример 1 в 2.2.2.1) имеет два параметра по 4 бита каждый (LREG[4;7] и GREG[0;3]). Биты [20;21] могут принимать любые значения для данной команды (в данном примере эти биты относятся к коду акселератора и используются командой запуска акселератора основного процессора). Остальные биты фиксированы и составляют КОП инструкции аскелератора.
Заметим, что совокупность всех строк форматов машинного слова задает множество допустимых кодов инструкций данного акселератора (CA в 2.1.2).
Число управляющих слотов NS задается директивой SLOTS(< NS>).
2.3. Ассемблерный синтаксис команд акселератора
Отдельная секция файла описания модели акселератора отвечает за опреде-ление синтаксиса ассемблера для системы команд этого акселератора. Более точно, эта секция определяет синтаксис для подмножества системы команд основного процессора, соответствующего командам запуска инструкций этого акселератора (см. 2.1.3.1). Это полезно для адекватного отра-жения на уровне ассемблера соответствующей семантики команд, так как одни и те же (в смысле машинных кодов) команды основного процессора (для запуска акселераторов) могут иметь разную семантику, в зависимости от конкретной конфигурации акселераторов в системе, специфичной для каждого заказчика. В дополнение к определению семантики команд акселераторов (см. 2.2), воз-можность настраивать синтаксис для этих команд является важной функцио-нальностью рассматриваемой системы, позволяющей легко получать готовую для производственного использования кросс-систему, адаптированную для специфичной конфигурации "процессор + акселераторы пользователя".
Описание ассемблерного синтаксиса системы команд состоит из трех секций:
Секция типов операндов и псевдонимов
Секция команд
Секция ограничений (constraints)
Детальное рассмотрение средств описания синтаксиса команд выходит за рамки данной статьи. Ниже приводится только краткий обзор основных возможностей.
2.3.1. Отображение ассемблерных команд в машинное слово
Общий шаблон допустимого ассемблерного синтаксиса для команд акселератора задается в виде:
command ::= mnemonic [parameter {, parameter}*]
{|| mnemonic [parameter {, parameter}*]}*
mnemonic ::= const_string
parameter ::= operand
{[const_string] [operand]}*
operand ::= const_string
const_string ::= любой текст без запятых и пробелов
Примеры возможных команд:
DMOVE ACR1.h, DM0(DA0--), ACR1.L, TM0(TA0++)
MOVE GRA, DM1(TA0+25) || ADD GR3, ACR2.H
На языке ассемблера команда состоит из мнемоники (нескольких мнемоник для параллельных команд) и набора параметров, разделенных запятой. Каждый параметр может содержать несколько частей - операндов, принадлежащих к каким-либо из описанных типов. В рамках одного параметра операнды должны отделяться непустыми строками константных символов. Комбинация мнемоник ассемблерного синтаксиса отображается в поле КОП соответс-твующей команды. Операнды (operand) отображаются на поля-операнды машинного слова. Возможно задание отображения на не непрерывные поля (когда биты поля перемежаются битами других полей).
Пример:
.types
grn [gr0:0] [gr1:1] [gr2:2] [gr3:3]
const6b $ -32 31
.mnemonics
MOVE {grn#0;2},{const6b#2;4#8;2} % 0xA8C0 0xFCC0
Описание задает команду MOVE с двумя операндами. Первый операнд типа grn является регистром общего назначения, код регистра размещается в 2х битах начиная с 0-го. Второй операнд является константой в диапазоне [-32; 31] и располагается в машинном слове в двух частях: в 4х битах, начиная со 2-го, и 2х битах, начиная с 8-го. КОП равен 1010-10XX-11XX-XXXX.
2.3.2. Ограничения
2.3.2.1. На отдельные операнды
Ограничения на отдельные операнды определяются соответствующим типом, к которому принадлежит операнд. Однако для наглядной генерации ошибок можно задать более широкий тип для операнда и воспользоваться механизмом общих ограничений (см. 2.3.2.2) для выделения допустимых значений.
2.3.2.2. На взаимосвязь операндов команды
Ограничения на взаимосвязь операндов команды задаются в виде набора логических высказываний относительно сравнений арифметических выражений, которые могут содержать значения любых использованных в команде операндов. Считается, что ограничения выполнены, если все логические высказывания для данной инструкции принимают значение "истина".
Выражения ограничений поддерживают следующие операции:
Логические операции
&&, ||, !
Операции сравнения
<, >, <=, >=, ==, <>
Арифметические операции
+, -, *, /, %
Битовые операции
|, &, ^, ~
В выражениях могут быть использованы числовые константы и, собственно, ссылки на операнды. Если несколько операндов имеют одинаковый тип, то следует использовать псевдонимы типов для различения операндов в выражениях ограничений. Пример. Операнды 1 и 2 не должны быть равны:
ADD {GRs#8;4}, {GRt#4;4} % 0x796000 0xf9f000
(GRs <> GRt) % "Operands must be different for ADD"
Заметим, что с помощью описанного механизма также можно задавать ограничения на отдельные операнды. Таким образом, возможны две стратегии работы с ограничениями на значения операндов: с одной стороны можно создать систему общих типов и затем сужать множества значений с помощью логических высказываний, а с другой работать с большим количеством специфических типов. В первом случае можно достичь более конкретных сообщений об ошибках в операндах инструкции, во втором - упрощается описание системы команд. Пользователь может выбрать любую стратегию.
2.3.2.3. На комбинации команд
Каждой команде можно назначить некоторый набор свойств и задать для них значения и области активации. В качестве значения свойства может выступать либо константа, либо значение одного из операндов команды. Область активации задает диапазон соседних команд, на котором данное свойство активно. Область активации по умолчанию [1;1] затрагивает только текущую команду. Механизм описания свойств (дополненный предикатами совместимости - см. ниже) фактически является модифицированным описанием таблиц использования ресурсов (reservation tables).
Пример:
MAC {acr#14;1},{grs#4;4},{grt#0;4} % 0x6c2000 0xffb800
[read_grn:grs, read_grn:grt, write_acr:acr:2;2]
Данная команда обладает следующими свойствами:
read_grn - двойное свойство со значениями равными значениям операндов grs и grt. Область активации по умолчанию затрагивает только текущую команду (здесь означает, что значения регистров, заданных операндами grs и grt, читаются на первом такте).
write_acr - значение свойства равно значению операнда acr. Область активации [2;2] затрагивает следующую команду (здесь означает, что значение acr будет записано на втором такте).
На механизме описания свойств базируется способ задания ограничений на использование ресурсов. Задается список предикатов совместимости свойств. Предикат совместимости свойств задает в квадратных скобках набор из пар свойств (пары разделяются запятыми, свойства в паре знаком =). Предикат истинен для пары команд, когда выполняются следующие ус