- •Лабораторная работа №1 Архитектура нейромикропроцессоров семейства NeuroMatrix ® nm 640х и их функциональные возможности
- •1. Описание и порядок пользования программой nmcalculator
- •1.1 Общие сведения о программе
- •1.2 Формирование векторной команды
- •1.3 Разбиение рабочей матрицы и запись весовых коэффициентов
- •1.4 Установка входных значений
- •1.5 Генератор кода
- •2. Порядок выполнения работы
- •Лабораторная работа № 2
- •1.Порядок выполнения работы
- •2. Элементы языка ассемблера процессора nm 6403
- •2.1 Формат ассемблерных инструкций
- •2.2 Векторные инструкции процессора
- •2.3 Регистры процессора
- •2.3.1 Основные регистры
- •3. Примеры простейших программ Пример 1: Организация циклов и доступ к памяти
- •Пример 2: Копирование массива данных на скалярном процессоре
- •Пример 3: Копирование массива данных на векторном процессоре
- •Пример 4: Операция взвешенного суммирования
- •4. Порядок выполнения работы
- •5. Контрольные вопросы
- •Лабораторная работа № 3
- •2.3 Использование Меток в Макросах
- •2.4 Импорт Макросов из Макробиблиотек
- •3. Примеры простейших программ Пример 1: Пример использования макросов в программе
- •Пример 2: Создание Библиотеки Макросов
- •4. Порядок выполнения работы
- •Лабораторная работа №4 Кодирование и декодирование информации в нейромикропроцессоре NeuroMatrix ® nm 640х
- •Теоретическая часть
- •1.1 Описание алгоритма шифрования гост 28147-89
- •Замена по таблице
- •Сдвиг на 11 разрядов
- •Вторая итерация
- •Замена по таблице
- •Сдвиг на 11 разрядов
- •Третья итерация
- •Замена по таблице
- •Сдвиг на 11 разрядов
- •1.2 Реализация алгоритма шифрования на процессоре nm6403
- •Практическая часть
- •2.1 Реализация алгоритма гост 28147-89 на нейропроцессоре nm 6403/6404
- •2.2 Реализация алгоритма гост 28147-89 на эмуляторе векторе векторных команд
- •2.3 Варианты заданий
- •2.4 Удаленный доступа к плате NeuroMatrix
- •Список используемой литературы:
Пример 2: Создание Библиотеки Макросов
Исходный текст примера содержится в файле step13а.asm в каталоге:
..\Tutorial\Step13а
На примере демонстрируются возможности использования макросов, описанных в макробиблиотеках, способы создания библиотек. Кроме того, в одном из макросов описаны возможности условной компиляции.
Файл “macros1.asm” Макрос осуществляет копирование одного массива данных в другой.
macro AAA (Arg1, Arg2, Arg3)
own Loop: label;
gr1 = Arg3;
gr1--;
<Loop>
if > delayed goto Loop with gr1--;
gr2, ar2=[Arg1++];
[Arg2++]=ar2, gr2;
end AAA;
Файл “macros2.asm”
macro Push_Pop (Arg1)
.if Arg1 xor 1; // начало блока услованой компиляции
push ar0, gr0;
push ar1, gr1;
push ar2, gr2;
.endif; // конец блока условной компиляции
.if Arg1; // начало блока условной компиляции
pop ar2, gr2;
pop ar1, gr1;
pop ar0, gr0;
.endif; // конец блока условной компиляции
end Push_Pop;
Комментарии к Примеру
В макросе Push_Pop используются возможности условной компиляции. Если в качестве фактического параметра передается ноль, то регистровые пары сохраняются в стеке; если же передана единица, то происходит восстановление регистровых пар из стека. На этапе компиляции в каждом отдельном случае будет подставлен тот или иной фрагмент программного кода.
Блоки условной компиляции формируются с помощью директивы .if.
Создание библиотеки макросов
Для создания библиотеки, содержащей описания макросов AAA и Push_Pop в командной строке требуется ввести сначала:
asm -mmacros.mlb macros1.asm
Таким образом, создается библиотека macros.mlb, содержащая макрос ААА.
Для добавления в макробиблиотеку макроса Push_Pop в командной строке используется следующий вызов:
asm -mmacros.mlb -a macros2.asm
Более подробное описание макросов и примеров работы с ними приведено в приложении A.2.Использование Макросов в Языке Ассемблера.
После того, как сформирована макробиблиотека, можно осуществлять подстановку макросов в программу.
Файл “main.cpp”
// функция Copy объявлена внешней с Си-связыванием
extern "C" void Copy( long *Src, long *Dst );
long A[16]; // массив исходных данных
long B[16]; // массив результатов
int main()
{
for (int i=0; i<16; i++)
A[i] = 0x0807060504030201*i;
Copy( A, B ); // вызов функции Copy
return 0;
}
Файл “step13a.asm”
global _Copy: label; // объявление глобальной метки _Copy
import from macros.mlb;
begin ".textAAA"
<_Copy>
ar5 = ar7 – 2;
Push_Pop(0); // подстановка макроса (сохранение регистров)
ar0 = [--ar5]; // в ar0 адрес исходного массива А
ar1 = [--ar5]; // в ar1 адрес массива результата В
AAA(ar0, ar1, 16); // подстановка макроса ААА
Push_Pop(1); // подстановка макроса (восстановление регистров)
return;
end ".textAAA";
Компиляция Примера
Для компиляции примера необходимо в командной строке ввести команду:
nmcc -g -m Step15a.asm main.cpp –I..\Include -oStep15a.abs
где Include – каталог, в котором содержатся необходимые макробиблиотеки.
4. Порядок выполнения работы
Практическая часть работы предполагает разработку программы на ассемблере с использованием макросов. Программа должна содержать 2 макроса: первый заполняет блок памяти массивом из чисел (см. задание 1 предыдущей лабораторной работы), а второй выполняет обработку этого массива в соответствии с вариантом задания для бригады. Номер варианта задания для второго макроса соответствует номеру бригады.
Для отладки программы воспользуемся специальным отладчиком emudbg.exe, поставляемым вместе с пакетом разработчика для процессора NM 6403.
Задания:
1 Вычислить контрольную сумму блока памяти (количество единичных бит) и записать её сразу за концом блока.
Рекомендации по выполнению: Воспользуйтесь операцией взвешенного суммирования, разбив рабочую матрицу на 32 строки и 1 столбец. На первом этапе, вычислите сумму четных единичных бит (нумерация, как и для элементов блока памяти начинается с нуля, а ноль – четное число) блока памяти. Полученные восемь 64-разрядных частичных суммы запишите в память для их временного хранения. На втором этапе, вычислите сумму нечетных единичных бит. На третьем этапе, просуммируйте частичные суммы четных и нечетных бит. Выгрузите полученные восемь 64-разрядных частичных суммы в память для их временного хранения. На четвертом этапе, просуммируйте полученные частичные суммы на скалярном процессоре (см. разобранный пример для 11 варианта) и запишите результат в память. Для того чтобы получить доступ к четным/нечетным битам входа Х, необходимо воспользоваться блоком маскирования задав соответствующие векторы масок:
EvenMask: long = 05555555555555555hl; // маска для четных бит (0101).
OddMask: long = 0aaaaaaaaaaaaaaaahl; // маска для нечетных бит (1010).
Вектор масок следует хранить в ram , причем столько 64-разрядных слов, сколько раз выполняется векторная команда (в нашем случае – 8). Кроме того, при суммировании нечетных бит, необходимо подключить регистр сдвига, т.к. разрядность элементов входа Х – 2 бита. Во избежание путаницы, следует четко представлять последовательность выполнения всех этих операций в процессоре (см. предыдущую работу).
2 Прибавить всем четным элементам разрядностью 16 бит сегодняшнее число. Затем, вычислить сумму 0-го и 1-го 64-разрядных элементов и записать её сразу за концом блока.
3. Умножить каждый элемент блока памяти разрядностью 8 бит на количество человек в бригаде. Затем, найти разность между 2-ым и 0-ым 32-разрядными элементами и записать её сразу за концом блока 64-разрядным словом с обнулением старших 32 разрядов этого слова.
4. Вычесть из каждого нечетного элемента разрядностью 32 бита предыдущий (четный) элемент. Затем, найти результат логического «или» 0-го и 4-го элементов разрядностью 16 бит и записать его сразу за концом блока 64-разрядным словом с обнулением старших 48 разрядов этого слова.
5. Поменять местами соседние четные и нечетные 16-разрядные элементы. Затем, найти результат логического «и» 0-го и 1-го 64-разрядных слов и записать его сразу за концом блока.
6. Найти сумму всех четных 32-разрядных элементов. Затем, обнулить у всех 32-разрядных элементов блока биты, которые в полученной сумме равны нулю.
7. Проинвертировать побитно блок памяти, а затем найти результат логического «и» исходного и проинвертированного блока.
Рекомендации по выполнению: Воспользуйтесь операцией or или and в АЛУ, подключив инверсию входа Х, а на вход Y подав соответствующее значение в зависимости от используемой операции. В данном примере можно обойтись без выгрузки промежуточных результатов в память, воспользовавшись возможностью работы afifo одновременно как на чтение (из головы) так и на запись (в хвост).
8. Замените все неотрицательные 4-разрядные элементы нулём, а отрицательные – минус единицей. Затем, замените все -1 на 1, а нулевые элементы оставьте без изменений.
Рекомендации по выполнению: Для выполнения первой части задания воспользуйтесь операцией логической активации (см. предыдущую работу), а для замены -1 на 1 – операцией взвешенного суммирования. Подумайте, какие для этого понадобятся весовые коэффициенты. В данном примере можно обойтись без выгрузки промежуточных результатов в память, воспользовавшись возможностью работы afifo одновременно как на чтение (из головы) так и на запись (в хвост).
9. Выполнить арифметическую активацию всех 4-разрядных элементов порогами [-4; 3] (см. предыдущую работу). Затем найти результат «исключающего или» 0-го и 7-го (последнего) 64-разрядных элементов, и записать его сразу за концом блока.
10. Переставить в каждом 64-разрядном элементе 4-разрядные тетрады в обратном порядке, после чего проинвертировать побитно весь блок памяти.
11. Прибавить всем четным 16-разрядным элементам следующий за ними нечетный элемент, умноженный на 2 и уменьшенный на 1. После чего, найти результат операции исключающего или над 0-ым и 4-ым 16-разрядными элементами блока памяти, результат которой записать в память 64-разрядным словом сразу за концом блока с обнулением оставшихся 48 старших бит слова. Затем, найти сумму всех нечетных 8-разрядных элементов блока памяти в формате 32-разрядного слова.
Отладить по шагам полученную программу и убедиться в её правильности. Зафиксировать в отчете текст программы и результаты её работы.
