nabbla (nabbla1) wrote,
nabbla
nabbla1

Categories:

Тестирование "случая Берегового"

Отсинтезировался проект легко и непринуждённо, в 521 ЛЭ из доступных 9984 (5%, но это только ядро, без периферии и видеопроцессора), предельная частота 30,21 МГц, уже радость (мы собираемся пока на 25 МГц работать).

Приведём дамп памяти с прошлого запуска, т.е когда были найдены и помещены в соответствующие позиции "центральные точки":
DumpAfterCenterPoints.png

Ну и запустим симуляцию, глянем, что там происходит...


Ушли те времена, когда я ручками в эту картинку рисовал расшифровку команд, чтобы хотя бы самому понять, что происходит. Сейчас я почти что "вижу", что происходит и без этого, хотя листинг перед глазами всё равно нужен...


Вот и он:
CheckUpsideDown proc
33  A711              ijk     0x0026  ;{Inv,k,i,j}
34  FC03              [SP]    0
35  8900              NOP     0 ;AUTOMATICALLY INSERTED BY TRANSLATOR TO PREVENT HAZARD
36  80C4  @@i_loop:   Acc     [X+i]       ;Fy0 на первой итерации, Fx0 на второй
37  83E6              SUB     [Z+2j+i]    ;вычесть Fy7 на первой итерации, Fx7 на второй
38  8ADC              C       [Y+i^j] ;i^j = 7 на первой итерации, 6 на второй. Должным выбором Y можно это устроить...
39  9080              MUL     Acc     ;(Fy0-Fy7) * Vx на первой итерации,  (Fx0-Fx7) * Vy на второй
3A  83FC              SUB     [SP]        ;вычитаем 0 на первой итерации, получая (Fy0-Fy7) * Vx.  Вычитаем (Fy0-Fy7) * Vx на второй, получая (Fy0-Fy7) * (-Vx) + (Fx0-Fx7) * Vy
3B  FC80              [SP]    Acc
3C  A812              iLOOP   @@i_loop
3D  BC09              JGE     @@skip
3E  A002              i       6
3F  FCB8              [SP]    Call(SwapPoints)    ;поменяли 6 и 7
40  A713              ijk     0x0042  ;i=2, j=2, k=0, Inv=0, последнее вообще необязательно
41  FCB8  @@reverse:  [SP]    Call(SwapPoints)
42  A500              j++     0
43  A814              iLOOP   @@reverse
44  A715  @@skip:     ijk     0x0025  ;Inv=0, k=0, i=1, j=5
45  FCB8              [SP]    Call(SwapPoints)
46  A716              ijk     0x0086  ;Inv=0, k=0, i=4, j=6
47  FCB8              [SP]    Call(SwapPoints)
CheckUpsideDown endp
48  B017  endless:    JMP endless


Инициализируем регистры i,j,k, а также [SP] нулём. "Выполняем" NOP, который любезно вставил компилятор. И приступаем к делу. Загружаем Fy0 = 0xF480 = -2944. Вычитаем Fy7 = 0xD340 = -11456, результат должен получиться 8512 = 0x2140. Да, его и видим после того, как загрузим в регистр C значение 0x1240 = 4672. Это ни что иное, как Vy=(Fy7-Fy6)/2. Это-то и странно! Мы же специально взяли нумерацию i^j, чтобы X и Y поменялись местами!

Ах да, при j=6, "исключающее ИЛИ" с i, принимающим 0 или 1, работает ровно также, как самое обычное сложение! Чтобы оно пошло "задом наперёд", значение j должно быть нечётным!

Это легко устроить:
		ijk	0x0027	;{Inv,k,i,j} = {0,0,1,7}
		[SP]	0
@@i_loop:	Acc	[X+i]		;Fy0 на первой итерации, Fx0 на второй
		SUB	[X+2j+i]	;вычесть Fy7 на первой итерации, Fx7 на второй
		C	[Y+i^j]	;i^j = 6 на первой итерации, 7 на второй. Должным выбором Y можно это устроить...
		MUL	Acc		;(Fy0-Fy7) * Vx на первой итерации,  (Fx0-Fx7) * Vy на второй
		SUB	[SP]		;вычитаем 0 на первой итерации, получая (Fy0-Fy7) * Vx.  Вычитаем (Fy0-Fy7) * Vx на второй, получая (Fy0-Fy7) * (-Vx) + (Fx0-Fx7) * Vy
		[SP]	Acc
		iLOOP	@@i_loop


Сделали j=7, но при доступе к Fy7 / Fx7 вместо регистра Z поставили регистр X. Остальное оставили "как есть".


Да, в этот раз взяли нужное значение, Vx = (Fx7-Fx6)/2 = 27520 = 0x6B80. Умножаем (Fy0-Fy7) на Vx и получаем 7149 = 0x1BED. Хорошо.

Идём на вторую итерацию, где в аккумулятор закладываем Fx0 = 0x38C0 = 14528. Вычитаем Fx7 = 0x72C0 = 29376, получая -14848. В регистр C закладываем Vy = 0x1240 = 4672. Следующий слайд:

(сейчас выбрал представление DataBus в десятичной форме со знаком)

Да, видим результат вычитания, -14848. Начинаем умножение, а сразу за ним вычитаем [SP], куда было занесено значение с прошлой итерации, 7149=0x1BED.

Результат: -14848 * 4672 - 7149 = -9266. (здесь умножение имеется в виду в формате Q1.15, т.е по кр. мере одно число воспринимается как имеющее диапазон -1..+1, т.е вместо 4672 мы подставляем 4672/32768, и получим ответ)

Всё верно. И переход JGE не срабатывает.


Что ж, первую часть (определение величины проекции и принятие решения) проверили, работает, все данные какие надо "подгружает". Завтра ещё быстренько "добьём" все перестановки - и золотой ключик у нас в кармане.
Tags: ПЛИС, программки, работа, странные девайсы
Subscribe

  • Тестируем atan1 на QuatCore

    Пора уже перебираться на "железо" потихоньку. Решил начать с самого первого алгоритма, поскольку он уже был написан на ассемблере. В программу внёс…

  • Формулы приведения, что б их... (и atan на ТРЁХ умножениях)

    Формулу арктангенса на 4 умножениях ещё немножко оптимизировал с помощью алгоритма Ремеза: Ошибка уменьшилась с 4,9 до 4,65 угловой секунды, и…

  • Алгоритм Ремеза в экселе

    Вот и до него руки дошли, причина станет ясна в следующем посте. Изучать чужие библиотеки было лениво (в том же BOOSTе сам чёрт ногу сломит), писать…

  • atan на ЧЕТЫРЁХ умножениях

    Мишка такой человек — ему обязательно надо, чтоб от всего была польза. Когда у него бывают лишние деньги, он идёт в магазин и покупает какую-нибудь…

  • Ай да Пафнутий Львович!

    Решил ещё немного поковыряться со своим арктангенсом. Хотел применить алгоритм Ремеза, но начал с узлов Чебышёва. И для начала со своего "линейного…

  • atan(y/x) на двух умножениях!

    Чего-то никак меня не отпустит эта тема, всё кажется, что есть очень простой и эффективный метод, надо только его найти! Сейчас вот такое…

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 0 comments