\makeReportTitle{лабораторной}{№ 3}{Разработка и интеграция пользовательских инструкций в состав ядра Nios II}{Проектирование цифровых устройств на \\ программируемых логических интегральных схемах (ПЛИС)}{}{С.В. Фёдоров}
\newpage
\pagestyle{fancy}
\section{Цель}
Освоить методику использования в составе системы на кристалле пользовательских периферийных модулей и пользовательских инструкций. Реализовать и отладить программное обеспечение системы на кристалле.
\section{Задачи}
\begin{itemize}
\item Изучить методики расширения набора команд процессора пользовательскими инструкциями.
\item Реализовать программное обеспечение, использующее пользовательские инструкции на примере инструкции вычисления количества единиц в двоичном числе.
\item Сравнить быстродействие с программной реализацией на базовом наборе команд.
\item Выполнить индивидуальное задание.
\end{itemize}
\section{Выполнение работы}
По шагам из методического материала был создан проект в САПР Quartus Prime (доступен по \href{https://git.iovchinnikov.ru/ivan-igorevich/fpga-lab-2/commits/branch/lab3}{ссылке}).
Созданная пользовательская инструкция доступна для обращения из программного кода в прикладном проекте.
\section{Индивидуальное задание}
В качестве индивидуального было дано следующее задание: описать пользовательскую инструкцию, принимающую на вход два 32-разрядных значения и возвращающая минимальное, максимальное, верхнее медианное и нижнее медианное значения. Схема получения данных на рис. \hrf{pic:indi-scheme}. Исходные данные представляют собой два 32-разрядных слова, каждое из которых необходимо разделить на четыре 8-разрядных слова, отсортировать все восемь 8-разрядных слов по возрастанию и взять их минимум (1), максимум (4) и медианы (2, 3).
Поскольку сложность самой быстрой сортировки $O(N*\lg_2(N))$, принято решение опираться на то, что значений в искомом множестве всегда фиксированное число. Сложность задания состоит в том, чтобы получить медианы не отсортированного множества за время меньшее, чем $O(N*\lg_2(N))$. Отсутствие необходимости разработки для множеств не фиксированной длины позволяет воспользоваться несколькими способами получения медианных значений.
\subsection{Описание схемотехнического решения}
Дан исходный числовой ряд (восемь байт, полученных из двух 32-разрядных переменных), например
Однако, дополнительные тесты показали, что алгоритм работает не для всех возможных вариантов начального распределения значений во множестве. Исходные коды модуля \hrf{lst:mediancomb} и вспомогательного \hrf{lst:lessmore} приведены в приложении \hrf{appendix:src}.
Конечный вариант модуля вычисления медиан, минимума и максимума представлен в листинге \hrf{lst:mmm}. Модуль осуществляет проход по сформированной шине из 8-разрядных значений, являющихся результатом конкатенации двух входящих 32-разрядных значений. Создаётся вспомогательный массив для отметок о проверке значения. Основной цикл опирается на сведения о том, что значений всегда восемь, поэтому итераций внешнего цикла нужно шесть (на первой будет найден минимум и максимум, на четвёртом и пятом - медианы, на шестом очищена сервисная шина). Основной цикл проходит по всей 64-разрядной временной шине и выставляет флаги минимума и максимума по следующему условию: \textit{проверяемый} элемент минимальный (максимальный), если он меньше (больше) \textit{найденного} на предыдущем шаге минимального (максимального) элемента или \textit{найденный} уже проверен\footnote{условие добавлено для первой итерации цикла в случаях, когда первой элемент является минимальным или максимальным.} и если проверяемый элемент не был проверен ранее.
Два входящих слова записываются во временный указатель и интерпретируются, как указатель на восемь 8-разрядных переменных \code{alt_u8}, далее цикл работает с ними как с массивом данных. На каждом шаге цикла ищется минимальный и максимальный элемент. Найденные элементы меняются местами с теми числами, которые находятся на месте действительно минимального и максимального элемента соответственно. Алгоритм являет собой совмещение \textit{сортировки выбором} и \textit{шейкерной сортировки}. Таким образом за четыре итерации получается сортированное множество, в котором необходимые значения берутся по индексу.
\begin{equation*}
\begin{gathered}
[31, 44, 216, 0, 132, 68, 18, 100] \to\\
[0, 44, 100, 31, 132, 68, 18, 216] \to\\
[0, 18, 100, 31, 44, 68, 132, 216] \to\\
[0, 18, 31, 68, 44, 100, 132, 216] \to\\
[0, 18, 31, 44, 68, 100, 132, 216]
\end{gathered}
\end{equation*}
Программная реализация алгоритма копирует исходные значения функцией \code{memset(dst, src, size)} и обрабатывает ситуацию, в которой найденный максимум равен найденному минимуму.
Пользовательская инструкция для процессора Nios II -- это эффективный инструмент ускорения работы программы и выноса некоторых алгоритмов поточной обработки данных в аппаратную часть.