nabbla (nabbla1) wrote,
nabbla
nabbla1

Categories:

QuatCore начинает фурычить (часть 4)

Часть 1, часть 2, часть 3

После некоторой доработки напильником нам удалось корректно исполнить первые 33 инструкций. Прошли целиком внутренний цикл и увидели, что выходим из него корректно. Наконец-то увидели АЛУ в работе.


Теперь интрига: сможет ли оно возвести в квадрат и поделить на два ОТРИЦАТЕЛЬНОЕ число?


ДА. У нас было число -939, точнее говоря, -939/32768. Его возведение в квадрат и деление на два дало 13/32768, и это правильный ответ.

Далее командой ADD [SP] мы прибавляем сумму квадратов всех предыдущих разностей, там у нас семёрка.

Командой [SP] Acc загоняем результат, 0x14 = 20 на стек.

Командой kLOOP -5 завершаем внутренний цикл, ведь k уже равен нулю.

Затем, iLOOP -7 - уменьшаем i на единичку, до 1, и теперь считаем квадрат расстояния от точки 1 до точки 3.

k 1 - приготовились к внутреннему циклу (k от 1 до 0).

Acc [X+2i+k] - загружаем Y-компоненту 1-й точки, эффективный адрес X+2i+k = 0x18+0x2+0x1 = 0x1B, там лежит значение 0xFFE2, или -30 в дополнительном коде.

SUB [X+2j+k] - вычитаем Y-компоненту 3-й точки, эффективный адрес X+2j+k = 0x18+0x6+0x1 = 0x1F, там лежит значение 0xFC1B, или -997 в дополнительном коде.

Пора несколько отдалиться от отдельных команд. У нас 4 точки:
F0 (53; -7),
F1 (480; -30),
F2 (-539; -302),
F3 (400; -997).

По окончании первой итерации по циклу j (где j=3), мы должны получить сумму квадратов

(53-400)2+(-7-(-997))2+(480-400)2+(-30-(-997))2+(-539-400)2+(-302-(-997))2 = 104 (да, у нас везде неявно деление на 32768, уже привыкать стал)

Половина от этого - 52. Именно это значение мы должны получить по [SP], и это же значение должно лежать в Acc.

Давайте промотаем до этого счастливого момента:


Да, по команде [SP] Acc у нас заносится значение 0x33 = 51. Близко! К сожалению, суммировались у нас 16-битные значения, поэтому точность немножко потеряли, но здесь нам нужно лишь найти самую отдалённую точку, для этого сверхточные вычисления и не нужны.

Из цикла по k (kLOOP -5) успешно вышли, из цикла по i (iLOOP -7) - тоже. Далее из нашей суммы квадратов, 51, вычитаем максимальное значение сумм квадратов, которое мы храним в [SP+1] и инициализировали нулём. Понятно, что 51-0 = 51 - число положительное.

Команда JL 4 (прыгнуть на 4 команды вперёд, если "меньше") поэтому не выполнила условный переход, что бывает, когда мы обнаружили НОВЫЙ максимум. В аккумуляторе его уже нет, к сожалению (может, стоит попытаться вкрутить команду CMP - то же, что SUB, но без занесения в аккумулятор), а передать значение из [SP] в [SP+1] мы тоже сейчас не можем, т.к решили упростить модуль QuatCoreMem - поставить там лишь один формирователь эффективного адреса и всё сопутствующее.

Поэтому пришлось воспользоваться промежуточным хранилищем - регистром C. C [SP] - занесли нашу сумму квадратов длин. [SP+1] C - положили на стек, теперь это наш максимум.
Y j - запомнили, точка с каким номером дала нам максимальное значение. В данном случае - третья.

И наконец, мы подошли к концу цикла по j. jLOOP -15 - уменьшили j на единичку и прыгнули почти в самое начало.

i 3 - повторно инициализировали цикл по i (от 3 до 0).
[SP] 0 - обнулили "текущую сумму квадратов".

Дальше началось долгое и мучительное вычисление суммы квадратов длин от второй точки до всех остальных:

((53-(-539))+(-7-(-302))2+(480-(-539))2+(-30-(-302))2+(400-(-539))2+(-997-(-302))2)/2 = 44,47 = 0x2C.

Посмотрим, что получается:


Опять немножко ошиблись, вместо 0x2C вышло 0x2B. Ничего страшного, всяко чувствуем разницу с 0x33, а это у нас почти наихудший случай, когда максимальное отдаление, поэтому все точки рядышком сидят, в центре экрана.

Снова из текущего значения вычитаем ранее найденный максимум (0x33), и в этот раз результат выходит отрицательный, поэтому команда JL 4 действительно осуществляет условный переход к команде jLOOP -15. Таким образом, мы пропускаем команды, которыми перезаписываем максимум и номер точки, в которой он найден.


Мы уже тихонько потеряли счёт числу выполненных команд, пока у меня в модели стоит генератор тактовой частоты 4 МГц, и мы провели моделирование на первые 130 микросекунд, т.е более 500 тактов. И пока всё хорошо.

Осталось докрутиться в 3 циклах, убедиться, что мы выходим из внешнего цикла, и что в регистре Y мы действительно найдём индекс наиболее отдалённой точки, после чего мы переставим её на нулевую позицию и успешно вернёмся из процедуры.

Продолжение следует...
Tags: ПЛИС, математика, программки, работа, странные девайсы
Subscribe

  • Нахождение двух самых отдалённых точек

    Пока компьютер долго и упорно мучал симуляцию, я пытался написать на ассемблере алгоритм захвата на ближней дистанции. А сейчас на этом коде можно…

  • Слишком общительный счётчик

    Вчера я чуть поторопился отсинтезировать проект,параметры не поменял: RomWidth = 8 вместо 7, RamWidth = 9 вместо 8, и ещё EnableByteAccess=1, чтобы…

  • Балансируем конвейер QuatCore

    В пятницу у нас всё замечательно сработало на симуляции, первые 16 миллисекунд полёт нормальный. А вот прошить весь проект на ПЛИС и попробовать "в…

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 0 comments