163 lines
13 KiB
TeX
163 lines
13 KiB
TeX
\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}
|
||
|