NML
Язык nML [43-44] изначально был разработан в Техническом университете Берлина в 1991 году и является пионером в области ADL-решений, ориентированных на высокоуровневое описание системы команд. В этом университете nML использовался в качестве способа описания аппаратуры для настраиваемого симулятора SIGH/SIM и компилятора CBC (с языка ALDiSP). Язык nML получил дальнейшее развитие в бельгийском научно-исследовательском центре микроэлектроники IMEC, где в рамках дочерней компании Target Compiler Technologies была создана коммерческая среда разработки [45], ориентированная на DSP-архитектуры. В эту среду входят компилятор CHESS (с языка C), симулятор CHECKERS, ассемблер, дисассемблер и компоновщик. Также поддерживается синтез шаблонов VHDL-описания.
В nML выделяются определения типов (type), элементов хранения данных (mem) и собственно иерархическое описание системы команд, задаваемое с помощью атрибутных грамматик в виде OR и AND-правил. Элементами грамматики служат операции (op) и режимы адресации (mode). Для операций обязательные атрибуты включают в себя описание поведения на расширенном подмножестве C (action), ассемблерного синтаксиса (syntax) и отображения в машинные коды (image). Для режимов адресации – только синтаксис и двоичный код. Корневая операция имеет фиксированное имя instruction.
Базовые типы данных nML включают в себя:
- int(n) - тип знаковых целых n-битных чисел в дополнительном коде;
- card(n) - тип n-битных беззнаковых чисел;
- float(n,m) - тип знаковых чисел с плавающей точкой с n-битной мантиссой и m-битным основанием, в соответствии со стандартом IEEE-754;
- fix(n,m) - тип знаковых чисел с фиксированной точкой, с n битами до и m битами после двоичной точки;
- bool - булевский тип; предопределены две константы true и false; при приведении к целому true получает значение -1, а false значение 0.
Пример 5 иллюстрирует описание в nML тривиального процессора с шестнадцатью 16-битными регистрами и парой команд сложения и вычитания:
type word = card(16) \ 16-битные данные type index = card(4) \ индекс для адресации 16 регистров
mem RF[16, word] \ 16 регистров размера word mem PC[1, word] \ регистр-счетчик команд
mode REG(i:index)=RF[i] \ режим прямой регистровой адресации syntax = format("R%d",i) \ синтаксис вида R0, R1, .., R15 image = format("%4b",i) \ тривиальное отображение номера \ регистра в 4 бита машинного слова
op instruction (x:instr_action) action = { PC = PC + 1; x.action; } syntax = x.syntax image = x.image
op instr_action = add_op | sub_op \ OR-правило
op add_op (dst:REG, src:REG) \ AND-правило action = { dst = dst + src; } syntax = format("ADD %s, %s”, dst.syntax, src.syntax) image = format(“0000 %s %s”, dst.image, src.image)
op sub_op (dst:REG, src:REG) action = { dst = dst - src; } syntax = format("SUB %s, %s”, dst.syntax, src.syntax) image = format(“0001 %s %s”, dst.image, src.image)
Пример 5. Тривиальный процессор в nML
Существенным ограничением nML является отсутствие механизмов описания многотактовых функциональных единиц и конвейеров. Кроме того, в nML поддерживаются только команды фиксированной длины, не поддерживается описание межкомандных зависимостей, и производительность симулятора, опубликованная в [17], невысока.