BMSTU/02-dspmd-02-hw-report.tex

163 lines
13 KiB
TeX
Raw Normal View History

2023-01-27 22:32:16 +03:00
\documentclass[a4paper,fontsize=14bp]{article}
\input{../common-preamble}
\input{../bmstu-preamble}
\input{../fancy-listings-preamble}
\numerationTop
\newcolumntype{s}{>{\tiny{}}c}
\begin{document}
\thispagestyle{empty}
\makeBMSTUHeader
\makeReportTitle{домашней}{2}{Библиотечная подпрограмма}{Микропроцессорные устройства обработки сигналов}{}{проф. каф. ИУЗ, д.т.н. \\В.С. Выхованец}
\newpage
\thispagestyle{empty}
\tableofcontents
\addtocontents{toc}{\vspace{2ex}}
\newpage
\pagestyle{fancy}
\section{Задача}
Темой домашнего задания является изучение алгоритмов и исследование способов их реализации, выполняющих Вычисление арктангенсов \code{atan16} \cite[с. 32 (4-11)]{ti:dsp-lib-prog-ref}. Для выполнения домашнего задания необходимо:
\begin{enumerate}[label=\arabic*),ref=\arabic*]
\item ознакомиться с рекомендованной литературой \cite[с. 102-165]{dsp:lectures};
\item привести в отчете теоретические сведения по методам обработки сигналов;
\item описать алгоритм обработки сигналов и данных;
\item прокомментировать текст библиотечной функции;
\item оформить\cite{gost:texts} отчет\cite{gost:links} по домашнему заданию\cite{bmstu:dsp-methodics2}.
\end{enumerate}
Основным результатом домашнего задания является комментированный текст библиотечной функции на языке ассемблера, а также описание выполняемого ею алгоритма цифровой обработки сигналов и данных.
\section{Выполнение}
\subsection{Теоретические сведения}
Арктангенс (arctg или arctan) это обратная тригонометрическая функция. Арктангенс x определяется как функция, обратная к тангенсу x, где x любое число ($x\in\mathbb{R}$). Если тангенс угла у равен х ($\tan(y) = x$), значит арктангенс x равняется y:
\[ \arctan(x) = \tan^{-1} x = y, \text{причем} -\pi / 2 < y < \pi / 2.\]
При этом $\tan^{-1}x$ означает обратный тангенс, а не тангенс в степени -1. Функция арктангенс непрерывна на своей области определения, то есть для всех x. Функция арктангенс является нечетной:
\[ \arctan(x) = \arctan(\tan \arctan x) = \arctan(\tan(\arctan x)) = \arctan x.\]
График арктангенса получается из графика тангенса, если поменять местами оси абсцисс и ординат. Чтобы устранить многозначность, множество значений ограничивают интервалом, на котором функция монотонна. Такое определение называют главным значением арктангенса.
\subsection{Интерфейс библиотечной функции}
Согласно документации \cite[c. 32 (4-11)]{ti:dsp-lib-prog-ref} функция вычисления арктангенса вектора значений имеет прототип, представленный в листинге \hrf{lst:atan-proto}:
\begin{lstlisting}[language=C,style=CCodeStyle,caption={Прототип функции вычисления арктангенса},label={lst:atan-proto}]
\code{ushort oflag = atan16 (DATA *x, DATA *r, ushort nx)}
\end{lstlisting}
где \code{ushort} тип данных, определенный как \code{unsigned short}; \code{DATA} тип данных, являющийся синонимом \code{int}; \code{x} указатель на вектор исходных данных; \code{r} указатель на вектор выходных данных арктангенса \code{x} в диапазоне $[-\pi/4, \pi/4]$, при этом, \code{atan(1.0) = 0.7854 или 6478h}; \code{nx} число элементов в векторах \code{x} и \code{r}. Векторы входных и выходных данных функции представляют собой одномерные массивы, элементами которых являются 16-разрядные числа (целые или дробные),
пронумерованные в порядке увеличения их адресов в памяти данных (таблица \hrf{table:vectors}).
\begin{table}[H]
\captionsetup{labelsep=endash}
\centering
\caption{Общий вид вектора функции atan16}
\label{table:vectors}
\begin{tabular}{|c|c|c|c|c|c|c|}
\hline
Адрес & x(+0) & x+1 & x+2 & x... & x+(nx-2) & x+(nx-1) \\ [0.5ex]
\hline
Индекс & x[0] & x[1] & x[2] & x... & x[nx-2] & x[nx-1] \\ [1ex]
\hline
\end{tabular}
\end{table}
Длина векторов \code{nx} задается в формате N16 беззнаковом 16-разрядном целочисленном формате. Сами массивы, а также их элементы выравнены по границе слова. Разрешается использование одного и того же указателя для задания двух векторов\footnote{In-place processing allowed (r can be equal to x)}. Функция управляет флагом переполнения \code{oflag}, который выставляется в 1 или 0 если произошло или не произошло 32-разрядное переполнение, соответственно.
\subsection{Описание алгоритма}
Функция \code{atan16} подсчитывает значение арктангенса каждого элемента вектора \code{x}, Результат записывается в выходной вектор \code{r} в диапазоне $[-\pi/4, \pi/4]$ радиан. Например, если x = [0x7fff, 0x3505, 0x1976, 0x0], что
эквивалентно $\tan(\frac{\pi}{4})$, $\tan(\frac{\pi}{8})$, $\tan(\frac{\pi}{16})$, $\tan(0)$ в формате float, то вызов функции \code{atan16(x, r, 4);} должен выдать r = [0x6478, 0x3243, 0x1921, 0x0], что эквивалентно $\frac{\pi}{4}$, $\frac{\pi}{8}$, $\frac{\pi}{16}$, $0$.
Реализуемый функцией \code{atan16} алгоритм описан на языке программирования Cи и приведен на листинге \hrf{lst:atan-alg}.
\begin{lstlisting}[language=C, style=CCodeStyle, caption = {Алгоритм вычисления арктангенса}, label={lst:atan-alg}]
#define DATA int
#define ushort unsigned short
void atan(DATA* x, DATA* r, ushort nx) {
ushort i;
for (i = 0; i < nx; i++) {
r[i] = atan(x[i]);
}
}
\end{lstlisting}
В теле основного цикла функции выполняется извлечение очередных элементов вектороа \code{x} и передача их в функцию \code{atan()}, с последующим присваиванием результата в соответствующий индекс выходного вектора \code{r}. Для организации цикла используется целочисленная переменная \code{i}, которая задает индекс элементов векторов.
Комментированный текст библиотечной функции \code{atan()} на основе сведений о мнемониках \cite{ti:dsp-mnemonics} приведен в приложении \hrf{appendix:asm}.
\section{Выводы}
В домашнем задании 2 приведено описание библиотечной функции вычисления арктангенса вектора. Для функции вычисления значений арктангенса разработан алгоритм на языке Си и приведен комментированный текст его реализации библиотечной функцией на языке ассемблера для микропроцессора цифровой обработки сигналов TMS320C5515.
\newpage
\printbibliography[heading=bibintoc, title={Список литературы}, resetnumbers=1]
\newpage
\begin{appendices}
\renewcommand{\thesubsection}{\Asbuk{subsection}}
\subsection{Библиотечная функция atan()}
\label{appendix:asm}
\begin{lstlisting}[style=ASMStyle]
;<@\lh{dkgreen}{************************************************************}@>
;<@\lh{dkgreen}{* Version 3.00.00 }@>
;<@\lh{dkgreen}{************************************************************}@>
;<@\lh{dkgreen}{* Функция: atan16}@>
;<@\lh{dkgreen}{* Процессор: C55xx}@>
;<@\lh{dkgreen}{* Описание: реализация арктангенса}@>
;<@\lh{dkgreen}{* Использование: short atan16( DATA *x, DATA *r, int nx)} @>
;<@\lh{dkgreen}{* nx : число элементов x и r}@>
;<@\lh{dkgreen}{* r[i] = atan(x[i]) где x и r в формате Q15}@>
;<@\lh{dkgreen}{* return 0}@>
;<@\lh{dkgreen}{*}@>
;<@\lh{dkgreen}{* Производительность (бенчмарки):}@>
;<@\lh{dkgreen}{* Циклов: (5 * nx) + 14 (Асимптотическая сложность О(n))}@>
;<@\lh{dkgreen}{* Объём кода (в байтах): 49}@>
;<@\lh{dkgreen}{*}@>
;<@\lh{dkgreen}{************************************************************}@>
.mmregs ;<@\lh{dkgreen}{Разрешение MMR-регистров}@>
.cpl_on ;<@\lh{dkgreen}{Режим компилятора}@>
.arms_on ;<@\lh{dkgreen}{Сигнальный режим адресации}@>
;<@\lh{dkgreen}{-----------------------------------------------------------}@>
;<@\lh{dkgreen}{| Тело функции}@>
;<@\lh{dkgreen}{-----------------------------------------------------------}@>
.def _atan16
.text
_atan16:
; <@\lh{dkgreen}{* AR0 присваивается \_x}@>
; <@\lh{dkgreen}{* AR1 присваивается \_r}@>
; <@\lh{dkgreen}{* T0 присваивается \_nx}@>
PSH T3 ; <@\lh{dkgreen}{использовать временный регистр}@>
|| BSET FRCT ; <@\lh{dkgreen}{режим рациональных чисел}@>
SUB #1, T0 ; nx - 1
MOV T0, BRC0 ; <@\lh{dkgreen}{повторить nx раз}@>
MOV #2596 << #16, AC3 ; <@\lh{dkgreen}{старшие разряды AC3 = C5}@>
MOV #-9464 << #16, AC1 ; <@\lh{dkgreen}{старшие разряды AC1 = C3}@>
MOV #32617 << #16, AC2 ; <@\lh{dkgreen}{старшие разряды AC2 = C1}@>
; <@\lh{dkgreen}{Загрузка T3 на инструкцию раньше, чем умножение его}@>
; <@\lh{dkgreen}{использует, приведёт к задержке в один такт}@>
MPYMR T3=*AR0+, AC3, AC0 ; <@\lh{dkgreen}{непосредственное умножение значения из х}@>
|| RPTBLOCAL loop1 - 1 ; <@\lh{dkgreen}{и запустить цикл}@>
MACR AC0,T3,AC1,AC0; <@\lh{dkgreen}{вычислить смещение для следующего значения}@>
MPYR T3, AC0 ; <@\lh{dkgreen}{сохранить временный результат умножения}@>
|| MOV *AR0+, T1 ; <@\lh{dkgreen}{сместить указатель на следующее значение х}@>
MACR AC0,T3,AC2,AC0; <@\lh{dkgreen}{вычислить смещение для следующего значения}@>
MPYR T3, AC0 ; <@\lh{dkgreen}{сохранить временный результат умножения}@>
|| MOV T1, T3 ; <@\lh{dkgreen}{сохранить значение итератора}@>
MOV HI(AC0), *AR1+ ; <@\lh{dkgreen}{сохранить старшую часть результата вычислений}@>
|| MPYR T1, AC3, AC0 ; <@\lh{dkgreen}{следующая итерация}@>
loop1: ; <@\lh{dkgreen}{цикл}@>
POP T3 ;
|| BCLR FRCT ; <@\lh{dkgreen}{вернуться в режим обычного C}@>
MOV #0, T0 ; <@\lh{dkgreen}{вернуть значение ОК}@>
|| RET ; <@\lh{dkgreen}{(нет возможных ошибок)}@>
\end{lstlisting}
\end{appendices}
\end{document}