\documentclass[a4paper,fontsize=14bp]{article}

\input{../common-preamble}
\input{../bmstu-preamble}
\input{../fancy-listings-preamble}
\numerationTop

\titlespacing*{\section}{\parindent}{1ex}{1em}

\setlength{\parindent}{4pc} % exaggerated for the example

\begin{document}
\thispagestyle{empty}
\makeBMSTUHeader
\captionsetup[tabular]{labelsep=space, 
  justification=raggedright, singlelinecheck=off}

\makeReportTitle{домашней}{1}{Команды микропроцессора}{Микропроцессорные устройства обработки сигналов}{}{проф. каф. ИУЗ, д.т.н. \\В.С. Выхованец}
\newpage
\thispagestyle{empty}
\tableofcontents
\addtocontents{toc}{\vspace{2ex}} % 6.2.3 В элементе «Содержание» номера подразделов приводят после абзацного отступа, равного двум знакам, относительно номеров разделов.
\newpage
\pagestyle{fancy}
\section{Задача} 
Целью выполнения домашнего задания является изучение архитектуры и организации микропроцессора и выбор методов и средств реализации низкоуровневой функции, заданной в теме домашнего задания.

\textbf{Темой домашнего задания} является умножение и сложение с насыщением и округлением: \code{long \_smacr(long src1, int src2, int src3)}.

Выполнение задания разделено на следующие этапы:
\begin{enumerate}[label=\arabic*),ref=\arabic*]
\item ознакомление с методическим материалом, учебным пособием \cite[с. 6-68]{dsp:lectures} и технической документацией \cite{ti:dsp-mnemonics}, поиск и изучение команд микропроцессора, позволяющих эффективно реализовать заданную функцию;
\item описание найденных команд и их настройка для реализации разрабатываемой низкоуровневой функции;
\item описание методики разработки низкоуровневой функции.
\end{enumerate}

\section{Выполнение}
Для выполнения домашнего задания необходимо:
\begin{itemize}
\item ознакомиться с рекомендованной литературой;
\item разработать и описать алгоритм решения задачи;
\item найти и изучить команды микропроцессора, необходимые для решения задачи;
\item подготовить тестовые данные для проверки реализации алгоритма;
\item оформить\cite{gost:texts} отчет\cite{gost:links} по домашнему заданию\cite{bmstu:dsp-methodics1}.
\end{itemize}
Основным результатом домашнего задания является методика разработки низкоуровневой функции для умножения и сложения с насыщением и округлением.

\subsection{Описание алгоритма низкоуровневой функции}
В микропроцессоре используется арифметика с фиксированной запятой, поэтому умножение дробных и целых чисел производится по одному и тому же принципу, представленному в общем виде формулами
\begin{equation}
  \begin{gathered}
    X_{Q1.15} = -s_x + 2^{-15} \sum_{i=0}^{14} x_i \cdot 2^i,  Y_{Q1.15} = -s_y + 2^{-15} \sum_{i=0}^{14} y_i \cdot 2^i, \\
    Z = 2^{-30} \big( -s_x + 2^{15} \sum_{i=0}^{14} x_i \cdot 2^i\big) \big( -s_y + 2^{15} \sum_{i=0}^{14} y_i \cdot 2^i \big), \\
    Z = 2^{-30}(X_{Z16} \cdot Y_{Z16}) = 2^{-30} Z_{Z32}, Z_{Q1.31} = 2 \cdot Z, \\
    Z_{Q1.31} = -s_Z + 2^{-31} \sum_{i=0}^{30} z_i \cdot 2^i, \\
    Z_{Q1.31} = Z_{Z32} < < 1, \\
    Z_{Q1.15} = Z_{Z32} > > 15,
  \end{gathered}
  \label{math:multiply}
\end{equation}
где $ X_{Q1.15} $ - первый операнд в формате Q1.15, $ Y_{Q1.15} $ - второй операнд в формате Q1.15, $ Z_{Q1.15} $ - результат вычислений в формате Q1.15, $-s_x$ - старший разряд первого операнда, обозначающий знак числа, $ x_i$ - каждый следующий разряд первого операнда, $-s_y$ - старший разряд второго операнда, обозначающий знак числа, $ y_i$ - каждый следующий разряд второго операнда. Таким образом для получения корректного результат умножения двух чисел в формате Q1.15 необходимо отсечь от полученного 32-разрядного результата младшие 15 разрядов, предварительно удалив самый старший разряд.

Насыщение - это процесс для операций с фиксированной запятой, при котором происходит преобразование результата умножения на максимально возможное представимое число. При отрицательном результате происходит замена на самое маленькое представимое число (например, \code{0xFF80000000} – минимальное число в Q1.31), а при положительном - на самое большое доступное (например, \code{0x007FFFFFFF} – максимальное число в Q1.31). Пример насыщения в таблице \hrf{table:saturation} демонстрирует также разницу двоичных представлений чисел разной разрядности.
\begin{table}[H]
  \captionsetup{labelsep=endash}
  \centering
  \caption{Пример насыщения}
  \label{table:saturation}
  \begin{tabular}{|lclcl|}
    \hline
    Q9.31            &           &                  &         & Q1.31          \\ [0.5ex] 
    0xFE80\_0000\_09 &           &                  & $\neq$  & 0x80\_0000\_09 \\ 
    0x0180\_0000\_09 &           &                  & $\neq$  & 0x80\_0000\_09 \\
    0xFE80\_0000\_09 & $\approx$ & 0xFF80\_0000\_09 & =       & 0x80\_0000\_00 \\ 
    0x0180\_0000\_09 & $\approx$ & 0x007F\_FFFF\_FF & =       & 0x7F\_FFFF\_FF \\
    \hline
  \end{tabular}
\end{table}


\subsection{Прототип низкоуровневой функции}
Согласно документации \cite[с. 77 (3-33)]{ti:dsp-prog-guide}, прототип низкоуровневой функции и описание аргументов функции на языке Си имеют вид, представленный в таблице \hrf{table:prototype}.

\begin{table}[H]
  \captionsetup{labelsep=endash}
  \centering
  \caption{Прототип и описание действия функции}
  \label{table:prototype}
  \begin{tabular}{|p{55mm}|p{110mm}|} 
    \hline
    Прототип функции & Верхнеуровневое описание \\ [3ex]
    \hline
    \multirow{2}{54mm}{\code{long \_smacr(long src, int op1, int op2)}} & Функция осуществляет умножение операторов \code{op1} и \code{op2}, сдвиг полученного результата влево на один разряд, складывает результат со значением параметра \code{src}, округляет результат, добавляя число 215 и присваивает значение 0 в младшие 16 разрядов, (устанавливаются биты SATD, SMUL и FRCT).\\
    \hline
  \end{tabular}
\end{table}

Параметры функции в таблице \hrf{table:prototype} имеют типы \code{long} и \code{int}, то есть представлены в формате Q1.15 и Q1.31, соответственно. Двоичные представления чисел в данных форматах \cite{dsp:lectures} представлены в таблицах \hrf{table:qbin-15} и  \hrf{table:qbin-31} соответственно.

\begin{table}[H]
  \captionsetup{labelsep=endash}
  \setlength\tabcolsep{1.5pt}
  \centering
  \caption{Формат представления чисел с фиксированной запятой (Q1.15)}
  \label{table:qbin-15}
  \begin{tabular}{|c|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|} 
    \multirow{3}{*}{Q1.15} & $2^{0}$ & $2^{-1}$ & $2^{-2}$ & $2^{-3}$ & $2^{-4}$ & $2^{-5}$ & $2^{-6}$ & $2^{-7}$ & $2^{-8}$ & $2^{-9}$ & $2^{-10}$ & $2^{-11}$ & $2^{-12}$ & $2^{-13}$ & $2^{-14}$ & $2^{-15}$ \\
    &$15$ & $14$ & $13$ & $12$ & $11$ & $10$ & $9$ & $8$ & $7$ & $6$ & $5$ & $4$ & $3$ & $2$ & $1$ & $0$ \\
    \cline{2-17}
    &S & X & X & X & X & X & X & X & X & X & X & X & X & X & X & X \\
    \hline
  \end{tabular}
\end{table}

\begin{table}[H]
  \captionsetup{labelsep=endash}
  \setlength\tabcolsep{1.5pt}
  \centering
  \caption{Формат представления чисел с фиксированной запятой (Q1.31)}
  \label{table:qbin-31}
  \begin{tabular}{|c|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|} 
  \multirow{3}{*}{Q1.31} & $2^{0}$ & $2^{-1}$ & $2^{-2}$ & $2^{-3}$ & $2^{-4}$ & $2^{-5}$ & $2^{-6}$ & $2^{-7}$ & $2^{-8}$ & $2^{-9}$ & $2^{-10}$ & $2^{-11}$ & . . . & $2^{-25}$ & $2^{-26}$ & $2^{-27}$ & $2^{-28}$ & $2^{-29}$ & $2^{-30}$ & $2^{-31}$\\
   & $31$ & $30$ & $29$ & $28$ & $27$ & $26$ & $25$ & $24$ & $23$ & $22$ & $21$ & $20$ & . . . & $6$ & $5$ & $4$ & $3$ & $2$ & $1$ & $0$ \\
    \cline{2-21}
   & S & X & X & X & X & X & X & X & X & X & X & X & . . . & X & X & X & X & X & X & X\\
    \hline
  \end{tabular}
\end{table}

Для очищения младших 16ти разрядов может быть использована макрокоманда\cite[стр. 138]{ti:dsp-c-compiler}, представленная в листинге \hrf{lst:macros}.
\begin{lstlisting}[language=C,style=CCodeStyle,caption={Макрокоманда, очищающая младшие разряды},label={lst:macros}]
#define mac_r(a,b,c) (short)(_smacr((a),(b),(c)) >> 16)
\end{lstlisting}

\subsection{Передача аргументов и возврат результата}
При вызове функции на языке Си, передача значений аргументов осуществляется в регистры и на стек по следующим правилам \cite[с. 125]{ti:dsp-c-compiler}:
\begin{itemize}
\item для функций, объявленных с переменным числом не типизированных аргументов, последний явно объявленный аргумент помещается на стек, за ним следуют оставшиеся аргументы, адрес этого аргумента может быть использован как ссылка для доступа к неявно переданным аргументам;
\item структура из двух слов или менее рассматриваются как 32-разрядный аргумент;
\item структура из более, чем двух слов передаётся по ссылке, компилятор передаст адрес структуры как указатель;
\item в основном, когда аргумент передаётся в функцию, компилятор присваивает его определённому классу и помещает в регистр (если доступен), согласно класса. Компилятор использует три класса:
  \begin{enumerate}[label=\arabic*),ref=\arabic*]
  \item 24-разрядный указатель на данные (\code{int*}, \code{long*}, и так далее);
  \item 16-разрядные данные (\code{char}, \code{short}, \code{int});
  \item 32-разрядные данные (\code{long}, \code{float}, \code{double}, указатель на функцию).
  \end{enumerate}
Если аргумент является указателем на любой тип данных, он считается указателем на данные. Если аргумент может быть помещён в 16-разрядный регистр, он считается 16-разрядными данными. Во всех остальных случаях данные считаются 32-разрядными. 40-разрядные данные передаются с использованием всего регистра, а не только его младших 32 разрядов.
\end{itemize}

Аргументы передаются в регистры в порядке, в котором они указаны в прототипе функции и помещаются, согласно класса, в следующие регистры:
\begin{itemize}
\item 24-разрядный указатель в регистрах \code{(X)AR0}, \code{(X)AR1}, \code{(X)AR2}, \code{(X)AR3} и \code{(X)AR4};
\item 16-разрядные данные в регистрах \code{T0}, \code{T1}, \code{AR0}, \code{AR1}, \code{AR2}, \code{AR3}, \code{AR4};
\item 32- или 40-разрядные данные в регистрах \code{AC0}, \code{AC1}, \code{AC2}.
\end{itemize}

Если доступные регистры для размещения аргументов отсутствуют, то не поместившиеся аргументы помещаются на стек. Стек по умолчанию выровнен по чётной границе. Затем каждый аргумент выравнивается на стеке согласно его класса. В случае необходимости вставляются пустоты для дополнительного выравнивания аргументов.

В ячейке \code{*SP(0)} размещается адрес возврата из функции, в \code{*SP(1)} – 1-й аргумент функции, не поместившийся в регистрах, и т.д., где \code{SP} – это указатель стека операндов, а в круглых скобках указано смещение относительно этого указателя в двойных словах.

Возврат результата выполнения функции осуществляется через регистры:
\begin{itemize}
\item данные разрядностью 16 бит размещаются в регистре \code{T0};
\item данные разрядностью 32 или 40 бита размещаются в регистре \code{AC0};
\item указатели разрядностью 24 бит размещаются в регистре \code{(X)AR0};
\item структура длиной более 32 бит возвращается через первый аргумент
\item функции – указатель на структуру, если он \code{0x0}, то структура не возвращается.
\end{itemize}

Вызываемая функция при использовании должна сохранять и восстанавливать регистры \code{T2}, \code{T3}, \code{(X)AR5}, \code{(X)AR6} и \code{(X)AR7}, а регистры \code{T0}, \code{T1}, \code{(X)AR0}, \code{(X)AR1}, \code{(X)AR2}, \code{(X)AR3}, \code{(X)AR4}, \code{AC0}, \code{AC1}, \code{AC2}, \code{AC3} может использовать без сохранения. Все другие специальные регистры микропроцессора при использовании подлежат обязательному сохранению и восстановлению, а именно: \code{RETA}, \code{BKx}, \code{BRCx}, \code{BRS1}, \code{BSAx}, \code{RSAx}, \code{REAx}, \code{RPTC}, \code{CSR}, \code{TRNx}, \code{(X)DP}, \code{(X)CDP}, \code{STx\_55}, где вместо \code{x} подставляется номер соответствующего регистра.

Сохранение регистров производится в автоматической (локальной) памяти функции, выделяемой на стеке перед адресом возврата путем уменьшения указателя стека SP на число двойных слов выделяемой памяти. Локальная память освобождается перед возвратом из функции путем увеличения указателя стека SP на число выделенных двойных слов. После выделения локальной памяти доступ к аргументам осуществляется с учетом длины выделенной памяти. Например, после выделения двух двойных слов адрес возврата из функции может быть адресован как \code{*SP(2)}, первый аргумент в стеке – как \code{*SP(3)}, и т.д.

Очистку стека с аргументами производит вызывающая функция после вызова вызываемой. В соответствии с вышеописанным для функции с прототипом, указанным в таблице \hrf{table:prototype} аргументы размещаются в порядке следования в регистрах \code{AC0}, \code{T0} и \code{T1}, а результат будет помещён в регистр \code{AC0}. Стек для размещения аргументов не используется.

\subsection{Описание и форматы команд микропроцессора}
Из документации на компилятор\cite[с. 134]{ti:dsp-c-compiler} получены следующие сведения: функция устанавливает биты (флаги) \code{SATD}\footnote{Saturation Mode (D unit)}, \code{SMUL}\footnote{Saturation-on-multiplication mode}, \code{FRCT}\footnote{Fractional mode (fixed-point mathematics in C)}. Возвращает насыщенную сумму \code{src} и fractional-mode произведение параметров \code{op1} и \code{op2}. Сумма округляется так, как если бы была вызвана функция \code{_sround}\cite[с. 136]{ti:dsp-c-compiler}.
%\footnote{Returns the value \code{src} rounded by adding $2^{15}$ using saturating arithmetic (biased round to positive infinity) and clearing the lower 16 bits. The upper 16 bits of the Q31 result can be treated as a Q15 value.}.

\subsubsection{Выбор команд}
В наборе команд микропроцессора TMS320C55x \cite{ti:dsp-mnemonics} имеется команда, позволяющая реализовать умножение с насыщением и округлением. \code{MAC} – данная инструкция выполняет умножение и суммирование.
\subsubsection{Синтаксис команд}
Команда MAC имеет следующий синтаксис \cite[с. 273]{ti:dsp-mnemonics}:
\begin{center} \code{MAC[R] ACx, Tx, ACy[, ACy]},\end{center}
где MAC – мнемоника команды умножения со сложением, R – признак округления результата операции, Tx - 16-разрядные регистры T0, T1, ACx и ACy – регистр аккумулятор AC0-AC3.

Необязательный параметр (5) заключён в квадратные скобки.
\subsubsection{Операции команд}
Эта инструкция выполняет умножение и сложение. Входящие операнды умножителя ACx(32−16) и значение Tx знаково расширяются до 17 битов по формуле (\hrf{eq:expanding})
\begin{equation}
  ACy = ACy + (ACx * Tx).
  \label{eq:expanding}
\end{equation}
Команда работает со следующими особенностями:
\begin{itemize}
\item если выставлен флаг \textbf{FRCT}, вывод умножителя сдвигается влево на один разряд;
\item обнаружение переполнения при умножении зависит от флага \textbf{SMUL};
\item 32-разрядный результат умножения знаково расширяется до 40 бит и добавляется к аккумулятору-источнику \textbf{ACy};
\item округление производится согласно \textbf{RDM}, если к инструкции применяется необязательное ключевое слово \textbf{R};
\item обнаружение переполнения при сложении зависит от \textbf{M40}. Если обнаружено переполнение, конечный аккумулятор выставляет статусный бит \textbf{ACOVy};
\item когда обнаруживается переполнение при сложении, аккумулятор насыщается согласно \textbf{SATD}.
\end{itemize}
\subsubsection{Форматы команд}
Команда \code{MAC[R] ACx, Tx, ACy[, ACy]} имеет следующий формат (opcode):

\begin{center} \verb|0101011E DDSSss0%| \end{center}
где двоичными цифрами показаны поля кодов команд \cite[с. 779-788]{ti:dsp-mnemonics}, DD – поле регистра-аккумулятора ACy, SS – поле регистра-аккумулятора ACx, ss – поле временного регистра-источника, \% – поле округления.

Двухразрядное поле регистра-аккумулятора DD кодируется следующим образом:
\begin{itemize}
\item 00 – регистр-аккумулятор AC0;
\item 01 – регистр-аккумулятор AC1;
\item 10 – регистр-аккумулятор AC2;
\item 11 – регистр-аккумулятор AC3.
\end{itemize}

Двухразрядное поле регистра-аккумулятора SS (ACw, ACx, ACy, ACz) кодируется следующим образом:
\begin{itemize}
\item 00 – регистр-аккумулятор AC0;
\item 01 – регистр-аккумулятор AC1;
\item 10 – регистр-аккумулятор AC2;
\item 11 – регистр-аккумулятор AC3.
\end{itemize}
  
Двухразрядное поле временного регистра-источника ss (Tx, Ty) кодируется следующим образом:
\begin{itemize}
\item 00 – временный регистр T0;
\item 01 – временный регистр T1;
\item 10 – временный регистр T2;
\item 11 – временный регистр T3.
\end{itemize}

\subsection{Методика разработки функции}
Входными операндами команд, выполняемых умножителями-аккумуляторами \cite[с. 30]{dsp:lectures}, могут быть (рисунок \hrf{pic:mac}):
\begin{itemize}
\item 17 разрядов регистров аккумуляторов AC0-AC3 (с 32 до 15);
\item числа во временных регистрах T0-T3, расширенные до 17 разрядов;
\item константы из кода команд, расширенные до 17 разрядов;
\item содержимое 16-разрядной ячеек памяти, расширенное до 17 разрядов.
\end{itemize}
\begin{figure}[H]
  \centering
  \includegraphics[height=5cm]{01lab-rpt-mac.png}
  \caption{Умножение с накоплением}
  \label{pic:mac}
\end{figure}
Умножение с накоплением чисел разной разрядности происходит как показано на рисунке \hrf{pic:mac}. Для повторения этого действия в самостоятельно написанной функции необходимо переместить параметр, переданный в регистре \code{T0} в регистр большей разрядности \code{AC1} (строка \hrf{line:moving-to-hi}). Также необходимо выставить флаги работы с дробными числами и насыщения (строки \hrf{line:frac} и \hrf{line:satd}), предварительно сохранив на стеке старое значение регистра статуса \code{ST1_55}\cite[с. 614]{ti:dsp-mnemonics}. Такое поведение описано в полном листинге ассемблерной команды (\hrf{code:prog-asm}).

\begin{lstlisting}[style=ASMStyle,caption={Описание функции на языке ассемблера}, label={code:prog-asm}]
_my_smacr:
 PSH mmap(ST1_55)
 BSET FRCT <@\label{line:frac}@>
 BSET SATD <@\label{line:satd}@>
 MOV T1,HI(AC1) <@\label{line:moving-to-hi}@>
 MACR AC1, T0, AC0
 POP mmap(ST1_55)
 RET
\end{lstlisting}

\newpage
\printbibliography[heading=bibintoc, title={Список литературы}, resetnumbers=1]

\end{document}
