|
Нужна помощь разобраться с asm рутиной FIRа, Моя первая самостоятелсьная FIR рутина... |
|
|
|
Jun 3 2007, 18:35
|
Знающий
   
Группа: Свой
Сообщений: 921
Регистрация: 6-04-07
Из: Israel
Пользователь №: 26 822

|
После долгих моих тугодумных мук родил FIR код в asm который будет част проэкта (вызывается из кода С). Почему-то после добавления ее в проэкт (данного файла asm) - проэкт не компилируется - падает ессно на этой рутине выдавая кучу ошибок. Первая из них весьма странная мне, не могу понять что его не устраивает. Может подскажете чего я не вижу: Код .mmregs .global _p_buffer_in,_p_buffer_out,_dline,_fcoeff,_fir_ord,_p_buff_lenth .global _fir_processing
_fir_processing: ; saving regs content into stack pshm ar0; used as delay line and coeff. cycling addressing increment pshm ar1; holds input data array start address pshm ar2 ; holds pointer to filter coeff. array addressing pshm ar3; holds pointer to delay line array addressing pshm ar4; holds output data array start address pshm ar5; holds output data array nop nop ; Initialization stm #1,ar0 ;set increment step for cycling buffers mvdm *(_fir_ord),BK ;set cyclic buffer size (for delay line and coeff buffer) stm #_p_buff_in,ar1 ;load data_in array start address stm #_fcoeff,ar2 ;load coeff. array start address stm #_dline,ar3 ;load delay line array start address stm #_p_buffer_out,ar4 ;load output data buffer array address mvdm *(_p_buff_length)-1,brc ;load BRC with processing data block length (PROC_BUFFER_LENGTH) nop nop ; Filtration rptb fir_loop_end-1 ; repeat FIR routine for entire processing data buffer mvdd *ar1+,*ar3+% ; load next input sample from input proc. array into delay line array rptz a,_fir_ord-1 ; FIR order less 1 iterations per each input data sample mac *ar2+0%,*ar3+0%,a ; MAC operation on cyclic delay line and coeff. arrays rnd a ; round off value in acc. A to 16 bits sth a,*ar4+ ; store output value into data output array fir_loop_end: popm ar5 popm ar4 popm ar3 popm ar2 popm ar1 popm ar0 Первая ошибка которую выдает компилятор: Цитата > ERROR ! at line 29: [E0004] Expecting dual memory addressing mvdd *ar1+, *ar3+% Дальше еще есть кучу ошибок, подозреваю что некоторые завязаны на предыдущих, посему буду исправлять по одной от первой к последней с перекомпиляцией после каждой. Итак, что ему не нравиться в mvdd ? Она-то вроде перекидывает из памяти в память, и вроде у меня так и есть в коде....  Что я в упор не вижу ????? Кроме того, если видите у другие ошибки в коде алгоритма - буду благодарен за указание таковых... P.S. Все переменные в данном asm определены в основном С коде.
|
|
|
|
|
 |
Ответов
|
Jun 5 2007, 14:07
|
Частый гость
 
Группа: Свой
Сообщений: 103
Регистрация: 16-05-06
Пользователь №: 17 126

|
Да незачта.В своем проекте дописал чуть-чуть Код *.c ... const unsigned short fir_ord=150; ... *.asm .ref _fir_ord .ref _IN_BUFF .ref _OUT_BUFF ...;Only for test in Simulator stm #0x2000,ar4 stm #0x2100,ar3
stm #_IN_BUFF,ar2 stm #_OUT_BUFF,ar5
stm #151,bk stm #1,ar0 nop ;дальше Ваш код без изменений Filtration rptb fir_loop_end-1 ; repeat FIR routine for entire processing data buffer mvdd *ar2+,*ar3+0% ; load next input sample from input proc. array into delay line array ;ar3 указывает на самый старый отсчет все ОК ld #0, a ; reset A rpt *(_fir_ord) ; FIR order (here equal to the number of FIR coefs) ;iterations per each input data sample mac *ar4+0%,*ar3+0%,a ; MAC operation on cyclic delay line and coeff. arrays ;ar3 снова указывает на тот же самый старый отсчет все ОК add #1, 15, a ; Это я бы убрал на время отладки sth a,*ar5+ ; store output value into data output array fir_loop_end: Все должно работать ничего в Вашем куске не менял, указатели меняются как положено
Сообщение отредактировал BratherLU - Jun 5 2007, 14:14
|
|
|
|
|
Jun 5 2007, 14:52
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(Саша Z @ Jun 3 2007, 17:35)  Кроме того, если видите у другие ошибки в коде алгоритма - буду благодарен за указание таковых... Мне кажется, у вас имеется логическая ошибка в программе фильтрации. Данные вы кладёте в циклический буфер, это хорошо, но затем вы циклически крутите буфер коэффициентов, это плохо. Должно быть так. 1) Вы записали новое данное в циклический буфер, указатель стал указывать на самую старую выборку. 2) Установили начало буфера коэффициентов. 3) Обработали 151 сампл, выдали результат, указатель опять указывает на самую старую выборку. 4) Перешли к пункту 1, пока не закончатся исходные данные.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jun 5 2007, 15:58
|
Знающий
   
Группа: Свой
Сообщений: 921
Регистрация: 6-04-07
Из: Israel
Пользователь №: 26 822

|
Цитата(=GM= @ Jun 5 2007, 18:52)  Мне кажется, у вас имеется логическая ошибка в программе фильтрации. Данные вы кладёте в циклический буфер, это хорошо, но затем вы циклически крутите буфер коэффициентов, это плохо.
Должно быть так.
1) Вы записали новое данное в циклический буфер, указатель стал указывать на самую старую выборку.
2) Установили начало буфера коэффициентов.
3) Обработали 151 сампл, выдали результат, указатель опять указывает на самую старую выборку.
4) Перешли к пункту 1, пока не закончатся исходные данные. Да но буфер коефф. тоже можно крутить циклически таким образом избегая его переадресации в начале каждого цикла (каждого нового sample), т.е. таким образом экономим пункт 2).
|
|
|
|
|
Jun 5 2007, 18:13
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(Саша Z @ Jun 5 2007, 15:58)  Да но буфер коефф. тоже можно крутить циклически таким образом избегая его переадресации в начале каждого цикла (каждого нового sample), т.е. таким образом экономим пункт 2). Вот что должно получиться по классике (х1 - самая старая выборка)
Код x1 x2 x3 x4 x5 x6 x6 x8 x9 - буфер входных выборок k1 k2 k3 k4 k5 - буфер коэффициентов
На первом этапе j=0 вычисляем сумму y(j) = Σx(i+j)•k(i), i=0,1,…,5. То есть
y(0)=x(1)•k(1)+x(2)•k(2)+x(3)•k(3)+x(4)•k(4)+x(5)•k(5)
На втором этапе j=1 самая старая выборка х(1) уйдёт в небытие, получим
x2 x3 x4 x5 х6 х7 х8 х9 - буфер входных выборок k1 k2 k3 k4 k5 - буфер коэффициентов
y(1)=x(2)•k(1)+x(3)•k(2)+x(4)•k(3)+x(5)•k(4)+x(6)•k(5)
На третьем этапе j=2 самая старая выборка х(2) уйдёт в небытие, получим
x3 x4 x5 х6 х7 х8 х9 - буфер входных выборок k1 k2 k3 k4 k5 - буфер коэффициентов
y(2)=x(3)•k(1)+x(4)•k(2)+x(5)•k(3)+x(6)•k(7)+x(8)•k(5) Ну и так далее. А что у вас? Указатель передвигается на х(2) и одновременно другой указатель на k(2). Вроде бы не получается. По крайней мере, у меня с ходу не получилось.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jun 6 2007, 06:57
|
Знающий
   
Группа: Свой
Сообщений: 921
Регистрация: 6-04-07
Из: Israel
Пользователь №: 26 822

|
Цитата(=GM= @ Jun 5 2007, 22:13)  Вот что должно получиться по классике (х1 - самая старая выборка)
Код x1 x2 x3 x4 x5 x6 x6 x8 x9 - буфер входных выборок k1 k2 k3 k4 k5 - буфер коэффициентов
На первом этапе j=0 вычисляем сумму y(j) = Σx(i+j)•k(i), i=0,1,…,5. То есть
y(0)=x(1)•k(1)+x(2)•k(2)+x(3)•k(3)+x(4)•k(4)+x(5)•k(5)
На втором этапе j=1 самая старая выборка х(1) уйдёт в небытие, получим
x2 x3 x4 x5 х6 х7 х8 х9 - буфер входных выборок k1 k2 k3 k4 k5 - буфер коэффициентов
y(1)=x(2)•k(1)+x(3)•k(2)+x(4)•k(3)+x(5)•k(4)+x(6)•k(5)
На третьем этапе j=2 самая старая выборка х(2) уйдёт в небытие, получим
x3 x4 x5 х6 х7 х8 х9 - буфер входных выборок k1 k2 k3 k4 k5 - буфер коэффициентов
y(2)=x(3)•k(1)+x(4)•k(2)+x(5)•k(3)+x(6)•k(7)+x(8)•k(5) Ну и так далее. А что у вас? Указатель передвигается на х(2) и одновременно другой указатель на k(2). Вроде бы не получается. По крайней мере, у меня с ходу не получилось. Ну давайте смотреть... Начнем пожалуй как и вы, с базисной функции которую нужно имплементировать, т.е. конволюции сигнала с transfer function фильтра, то бишь его коеффициентами: y[n] = x[n]h[0] + x[n-1]h[1] + x[n-2]h[2] +....+x[n-(N-1)]h[N-1] где: x - samples вхдпдного сигнала, h - коефф. transfer function фильтра, y - ессно выходные samples. значит: y[0] = x[0]h[0] + 0h[1] + 0h[2]+ ...+ 0 = x[0]h[0] y[1] = x[1]h[0] + x[0]h[1] y[2] = x[2]h[0] + x[1]h[1] + x[0]h[2] y[3] = x[3]h[0] + x[2]h[1] + x[1]h[2] + x[0]h[3] и т.д. В аккумуляторе каждый раз выполняется: y[n] = h[n]х[n-i] где i - индексация коефф. фильтра. Кстати, в такой реализации коефф. фильтра должны располагаться в прямом порядке в буфере - т.е. по возрастающим адресам (как и в буфере линии задержки кида подгружаются входные данные), изначально буфер задержки конечно-же обнулен. Как мы знаем, всегда выполняется полное-кол-во итераций (согласно порядку/длинне фильтра) для каждого нового sample, значит pointer в буфере коефф. должен всегда проходить полный цикл и к началу следующего возвращаться обратно на первый коеффициент. Что и делает циркулярная адресация буфера коеффициентов. Длинна цирк. адресации буфера коефф. и линии задержки - одинакова (что дает возможность одновременной циркуляции по единиму циклу в BK), но в линию задержки, как вы правильно сказали, каждый новый цикл подгружается новый input. В вашем примере вы ведь тоже в буфере коефф. каждый раз (после каждого цикла) возвращаетесь на начало (т.е. на первый коефф.), но делаете видимо это отдельной инструкцией загрузки pointerа начала буфера коеффициентов.
|
|
|
|
|
Jun 6 2007, 09:10
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(Саша Z @ Jun 6 2007, 05:57)  Ну давайте смотреть... Начнем пожалуй как и вы, с базисной функции которую нужно имплементировать, т.е. конволюции сигнала с transfer function фильтра, то бишь его коеффициентами:
y[n] = x[n]h[0] + x[n-1]h[1] + x[n-2]h[2] +....+x[n-(N-1)]h[N-1]
где: x - samples вхдпдного сигнала, h - коефф. transfer function фильтра, y - ессно выходные samples.
значит: y[0] = x[0]h[0] + 0h[1] + 0h[2]+ ...+ 0 = x[0]h[0] y[1] = x[1]h[0] + x[0]h[1] y[2] = x[2]h[0] + x[1]h[1] + x[0]h[2] y[3] = x[3]h[0] + x[2]h[1] + x[1]h[2] + x[0]h[3] и т.д.
В аккумуляторе каждый раз выполняется: y[n] = h[n]х[n-i] где i - индексация коефф. фильтра. Кстати, в такой реализации коефф. фильтра должны располагаться в прямом порядке в буфере - т.е. по возрастающим адресам (как и в буфере линии задержки кида подгружаются входные данные), изначально буфер задержки конечно-же обнулен. Как мы знаем, всегда выполняется полное-кол-во итераций (согласно порядку/длинне фильтра) для каждого нового sample, значит pointer в буфере коефф. должен всегда проходить полный цикл и к началу следующего возвращаться обратно на первый коеффициент. Что и делает циркулярная адресация буфера коеффициентов. Длинна цирк. адресации буфера коефф. и линии задержки - одинакова (что дает возможность одновременной циркуляции по единиму циклу в BK), но в линию задержки, как вы правильно сказали, каждый новый цикл подгружается новый input. В вашем примере вы ведь тоже в буфере коефф. каждый раз (после каждого цикла) возвращаетесь на начало (т.е. на первый коефф.), но делаете видимо это отдельной инструкцией загрузки pointerа начала буфера коеффициентов. Бестолковое объяснение надо сказать, но вы правы в одном, сдвиг есть. Я сказал, что указатель передвигается на х(2) и одновременно другой указатель на k(2), это так. Но в команде mvdd *ar2+,*ar3+0% не обратил внимания на последний значок "%", означающий циклическую адресацию с индексом 1. Так что, когда указатель данных переходит на х(2) и одновременно другой указатель на k(2), данная команда для нового цикла передвигает указатель данных на х(3). Кстати, вам везде можно делать такую адресацию *arn+% вместо *arn+0%, поскольку у вас индекс равен 1, заодно и ar0 не надо мучить.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jun 6 2007, 09:33
|
Знающий
   
Группа: Свой
Сообщений: 921
Регистрация: 6-04-07
Из: Israel
Пользователь №: 26 822

|
Цитата(=GM= @ Jun 6 2007, 13:10)  Бестолковое объяснение надо сказать, но вы правы в одном, сдвиг есть.
Я сказал, что указатель передвигается на х(2) и одновременно другой указатель на k(2), это так. Но в команде mvdd *ar2+,*ar3+0% не обратил внимания на последний значок "%", означающий циклическую адресацию с индексом 1. Так что, когда указатель данных переходит на х(2) и одновременно другой указатель на k(2), данная команда для нового цикла передвигает указатель данных на х(3).
Кстати, вам везде можно делать такую адресацию *arn+% вместо *arn+0%, поскольку у вас индекс равен 1, заодно и ar0 не надо мучить. Объяснять я умею плохо, согласен, но не понял что вы имеете ввиду во втором параграфе (вы не заметили % или я не заметил ?). В целом в самой рутине ошибки нет, думаю вы уже поняли, исключая тот факт о котором упомянул =BH=, сейчас себя перепроверяю - есть подозрение что он прав насчет расположения коефф. в буфере, сейчас с этим разбираюсь. МОя рутина работает как надо (фильтр проверен по анализу результата в Матлабе на тестовом сигнале), но кажется меня спасло симметричность фильтра (был-бы он анти-симметричен - видимо не работал бы без инверсии расположения коеффициентов). Сейчас проверяю... P.S. ar0 не мучается. В него одноразово загружена 1 и все. Хотя оно может работать и как вы сказали (может быть), т.е. без ar0, я еще слабо знаю семантику данного ассемблера. Цитата(-=ВН=- @ Jun 6 2007, 12:52)  Плохо, что не видите. Вот и посмотрите на 1 цикл. На примере 4-х точечного фильтра. К-ты фильтра h0,h1,h2,h3. h0 в младшем адресе, h3 в старшем. AR4 указывает на h0. Буфер данных, тоже 4-х точечный, располагаемый по адресам A0-A3. Изначально буфер обнулен. В AR3 содержится адрес A0 до записи первого входного отсчета. Как только Вы его записали, AR3 станет равным A1. Вот и смотрите. Первое выходное значение будет h0*[A1]+h1*[A2]+h2*[A3]+h3*[A0]. Здесь под [A0],[A1],[A2],[A3] обозначено содержимое ячеек по адресам A0-A3. Т.к. по адресам A1-A3 находится 0, а в ячейке с адресом A0 находится x0, то в результате получается h3*x0. А техасовский пример Вы зря упомянули. Вы с ним не разобрались совершенно. Я даже не поленился его посмотреть. Там все абсолютно правильно. Посмотрите хотя бы картинку на странице 77. Там дано расположение к-тов по адресам. Они там расположены именно в инверсном порядке. В тексте же программы неудачно использован симметричный фильтр. У него начало и конец абсолютно одинаковы. Хмм, есть подозрение что вы правы. Не уделил должного внимания более глубокому изучению их примера (карты памяти расп. коеффициентов). Видимо действительно меня спас факт использования симметричного фильтра. Еще раз перепроверю и видимо нужно будет перевернуть порядок коеффициентов..
|
|
|
|
|
Jun 6 2007, 10:01
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(Саша Z @ Jun 6 2007, 08:33)  ... не понял что вы имеете ввиду во втором параграфе (вы не заметили % или я не заметил ?). В целом в самой рутине ошибки нет, думаю вы уже поняли, исключая тот факт о котором упомянул =BH=, сейчас себя перепроверяю - есть подозрение что он прав насчет расположения коэфф. в буфере, сейчас с этим разбираюсь. Моя рутина работает как надо (фильтр проверен по анализу результата в Матлабе на тестовом сигнале), но кажется меня спасло симметричность фильтра (был-бы он анти-симметричен - видимо не работал бы без инверсии расположения коэффициентов). 1) Не заметил я, отсюда весь сыр-бор загорелся(:-). 2) Не путайте нумерацию коэффициентов и содержимое этих самых коэффициентов. Скажем, никто не запрещает загрузить их задом-наперед. 3) Ошибок вроде нет, но программу фильтрации вам ещё шлифовать и шлифовать(:-). Например, вместо rptb fir_loop_end-1 можно использовать rptbd fir_loop_end-1, имеем уменьшение на 2 МС. Кстати, давно не работал с этим процом, компилятор принимает rptz a,_fir_ord-1 вместо rptz a,#_fir_ord-1? Вроде бы в команде должна стоять решетка (#). Цитата(Саша Z @ Jun 6 2007, 08:33)  ar0 не мучается. В него одноразово загружена 1 и все Одна команда, одно слово, ни вреда, ни пользы, хотя можно обойтись, если подумать. Давайте вместо "не мучить" поставлю "не использовать", пойдёт?
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jun 6 2007, 10:36
|
Знающий
   
Группа: Свой
Сообщений: 921
Регистрация: 6-04-07
Из: Israel
Пользователь №: 26 822

|
Цитата(=GM= @ Jun 6 2007, 14:01)  1) Не заметил я, отсюда весь сыр-бор загорелся(:-). 2) Не путайте нумерацию коэффициентов и содержимое этих самых коэффициентов. Скажем, никто не запрещает загрузить их задом-наперед. 3) Ошибок вроде нет, но программу фильтрации вам ещё шлифовать и шлифовать(:-). Например, вместо rptb fir_loop_end-1 можно использовать rptbd fir_loop_end-1, имеем уменьшение на 2 МС.
Кстати, давно не работал с этим процом, компилятор принимает rptz a,_fir_ord-1 вместо rptz a,#_fir_ord-1? Вроде бы в команде должна стоять решетка (#).
Одна команда, одно слово, ни вреда, ни пользы, хотя можно обойтись, если подумать. Давайте вместо "не мучить" поставлю "не использовать", пойдёт? Да, насчет оптимизации - тут я конечно-же еще "чайник", только начал вообще асемблер данного процессра изучать, да и то в рамках нужных мне вещей (для проэкта). На доскональное изучение (что требуется для оптимизаций) времени нет, нужно что-бы работало с более-менее (тем более реч не идет о реальном времени, по крайней мере в конкретной реализации). Наверняка есть инструкции позволяющие экономить цикл там, цикл сям и т.д., но пока это не моя преррогатива...  Насчет комамнды, у меня нужна косвенная адресация для _fir_ord (ибо данная константа определена во внешнем C файле и передается в asm код). Посему заменена на: Код ld #0, а rpt *(_fir_ord)
|
|
|
|
Сообщений в этой теме
Саша Z Нужна помощь разобраться с asm рутиной FIRа Jun 3 2007, 18:35 BratherLU 1 - В mvdd можно использовать только регистры ar... Jun 4 2007, 05:16 Саша Z Цитата(BratherLU @ Jun 4 2007, 09:16) 1 -... Jun 4 2007, 05:59 BratherLU В Conventions описано как праввильно делать вызов ... Jun 4 2007, 08:54 Саша Z Цитата(BratherLU @ Jun 4 2007, 12:54) В C... Jun 4 2007, 10:14 BratherLU mvdk *(_p_buff_length-1),brc сорри Вас запутал и... Jun 4 2007, 11:06 Саша Z Цитата(BratherLU @ Jun 4 2007, 15:06) mvd... Jun 4 2007, 11:27 BratherLU ld #0x00,a
rpt *(_fir_ord)
rptz действительно не ... Jun 4 2007, 11:58 Саша Z Цитата(BratherLU @ Jun 4 2007, 15:46) ld ... Jun 4 2007, 12:03 BratherLU Коэффициенты тоже должны быть выровнены по соответ... Jun 4 2007, 12:07 Саша Z Цитата(BratherLU @ Jun 4 2007, 16:07) Коэ... Jun 4 2007, 12:28 BratherLU Еще смотрите - что у вас в BK и в ar0 если все ок ... Jun 4 2007, 12:43 Саша Z Цитата(BratherLU @ Jun 4 2007, 16:43) Еще... Jun 4 2007, 13:07 BratherLU В Данной реализации длина линии задержки==число ко... Jun 4 2007, 14:13 Саша Z Цитата(BratherLU @ Jun 4 2007, 18:13) В Д... Jun 4 2007, 18:18  BratherLU Цитата(Саша Z @ Jun 4 2007, 22:18) ..., т... Jun 5 2007, 08:49   Саша Z Цитата(BratherLU @ Jun 5 2007, 12:49) Пос... Jun 5 2007, 11:48 BratherLU Еще раз в данной реализации -> длина линии заде... Jun 5 2007, 12:03 Саша Z Цитата(BratherLU @ Jun 5 2007, 16:03) Еще... Jun 5 2007, 12:25 BratherLU Давйте кусочек кода начиная с внешнего цикла (там ... Jun 5 2007, 12:45 Саша Z Цитата(BratherLU @ Jun 5 2007, 16:45) Дав... Jun 5 2007, 13:02     -=ВН=- Цитата(Саша Z @ Jun 6 2007, 10:57) ...
Кс... Jun 6 2007, 07:28      Саша Z Цитата(-=ВН=- @ Jun 6 2007, 11... Jun 6 2007, 08:04       -=ВН=- Цитата(Саша Z @ Jun 6 2007, 12:04) Да нет... Jun 6 2007, 08:52 Саша Z Цитата(BratherLU @ Jun 5 2007, 18:07) Да ... Jun 5 2007, 14:55
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|