Разработка подпрограммы на языке ассемблера для ЦСП ADSP-2189, реализующей цифровой фильтр, страница 2

            Основная программа использует первый генератор адресов данных (DAG1). Распределение регистров следующее:

  • регистр-указатель I1 содержит указатель на выходной массив Y;
  • значение регистра-модификатора M1 равно 1, т.е. после обращения к ячейке памяти, на которую указывает I1, значение I1 изменится на 1 байт в сторону увеличения адреса;
  • значение регистра длины L1 равно размеру кольцевого массива Y (2048).

Подпрограмма conv использует второй генератор адресов данных (DAG2), так как используется массив h, хранящийся в памяти программ.

Распределение регистров следующее:

  • регистр-указатель I4 содержит указатель на массив содержащий отсчёты импульсной характеристики фильтра (указатель передаётся в подпрограмму через переменную h_addr);
  • значение регистра-модификатора M4 равно 1, т.е. после обращения к ячейке памяти, на которую указывает I4, значение I4 изменится на 1 байт в сторону увеличения адреса;
  • значение регистра длины L4 равно 0, так как массив h не кольцевой.
  • регистр-указатель I5 содержит указатель на массив содержащий отсчёты входного сигнала (указатель передаётся в подпрограмму через переменную X_point);
  • значение регистра-модификатора M5 равно -1, т.е. после обращения к ячейке памяти, на которую указывает I5, значение I5 изменится на 1 байт в сторону уменьшения адреса;
  • значение регистра длины L5 равно размеру кольцевого массива X (2048).

4 Исходный текст программы

#define N 2048 // размер входного и выходного массивов

#define K 64  // размер массива импульсной характеристики

.section/data     data1;

.VAR/CIRC X[N] = "x.dat";          //отсчётывходногосигнала

//.VAR/CIRCX[N] = "impulse.dat";   //для исследования импульсной характеристики

//.VAR/CIRCX[N] = "step.dat";      //для исследования переходной характеристики

.VAR/CIRC Y[N];                            //выходной массив

.VAR X_point;                      

.VAR Y_point;

.VAR h_addr;

.section/pm interrupts;                    // таблица векторов прерываний

_reset: JUMP start; nop; nop; nop; // 0x0000 сброс

       RTI; nop; nop; nop;         // 0x0004 irq2

       RTI; nop; nop; nop;         // 0x0008 irql1

       RTI; nop; nop; nop;         // 0x000c irql0

       RTI; nop; nop; nop;         // 0x0010 передатчик SPORT0

       RTI; nop; nop; nop;         // 0x0014 приемник SPORT0

       RTI; nop; nop; nop;         // 0x0018 irqe

       RTI; nop; nop; nop;         // 0x001c BDMA

       RTI; nop; nop; nop;         // 0x0020 передатчик SPORT1

       RTI; nop; nop; nop;         // 0x0024 приемник SPORT1

       RTI; nop; nop; nop;         // 0x0028 Timer

       RTI; nop; nop; nop;         // 0x002C Power down

.section/pm pm_da;

.VAR h[K] = "h.dat"; //отсчёты импульсной характеристики, хранящиеся в памяти

//программ

.section/pm program;

start:

       dis M_Mode;   //режим вычислений в формате с фиксированной точкой

       I1=Y;                //указатель на выходной массив Y

       L1=N;               

       M1=1;

       AX0=X;

       AY0=h;

       DM(X_point)=AX0;

       DM(h_addr)=AY0;

       CNTR=N;      

       DO LOOP_2 UNTIL CE;

              call conv;           //вызовподпрограммысвёртки

              AX0=DM(X_point);     //сдвиг указателя, хранящегося в X_point

              AR=AX0+1;

              DM(X_point)=AR;

              AX0=DM(Y_point);     //Y_point содержит результат вычислений

LOOP_2: DM(I1,M1)=AX0;             //записывается в выходной массив

end:

       jump end;

conv:                               // подпрограмма свёртки

       I4=DM(h_addr);       // указатель на массив h

       M4=1;

       L4=0;

       I5=DM(X_point);             // указатель на входной массив X

       L5=N; 

       M5=-1;

       CNTR=K;

       MR=0;

       DO LOOP_1 UNTIL CE; 

              mx0=pm(I4,M4);       // mx0=значение импульсной характеристики

              my0=dm(I5,M5);       // my0=значение входного сигнала

       LOOP_1:       MR=MR+mx0*my0(SS);//умножение с накоплением

       DM(Y_point)=MR1;                    //Y_point=результатвычислений

stop_conv: