nabbla (nabbla1) wrote,
nabbla
nabbla1

Categories:

Алгоритм обнаружения на симуляции (2)

Продолжаем разбираться, в чём же проблема. Пока что мы успели пройти строки изображения, не содержащие пятно (там всё нормально), наткнулись на первую строку, содержащую "верхушку" пятна, добавили новое пятно (61;11) и диаметром 3. Чуть-чуть у нас "сбит прицел" - это должно было быть (60;13), но это не страшно.

Также мы выдали задания на обработку отрезков [0;59], [60;62] и [63;127], ну и на HSync разумеется, куда же без него - и замерли в ожидании результатов по первому из них. Даже на "покоцанном" кадре 128х128 процессор пока успевает обработать строку до прихода следующей - и то радость.

Проматываем к тому моменту, когда результаты появляются:


Ровно "в этот самый момент" идёт выдача строки, как видно по графе "X" и "Pixels". Т.е как только мы дошли до пикселя 59 - тут же и "кинулись в бой".

Максимальная яркость: 255, достигается при X=0x03A=58. Сейчас начнётся веселье...


Первым делом убеждаемся, что яркая точка превышает порог. Загружаем порог 1, вычитаем яркость, пришедшую с GPU, 0 (там применена инверсия), результат выходит неотрицательным, из-за чего переход JL не выполняется.

Далее проверяется, не нужно ли расширить пятно слева от нас за счёт новой яркой точки. Загружается X-координата левого пятна, -32768 (0x8000, это фиктивное пятно), вычитается из него текущая координата, 0x03A = 58, добавляется половинка D1 (3) и половинка диаметра левого пятна, 0x8000. Регистру Z присваивается адрес пятна справа от нас, 0xA0. Сейчас память должна быть организована следующим образом:

ActivePoints:     09B  0x00A0
AllPoints:        09C  0x8000
APHeadDummyX:     09D  0x8000
Heap:             09E  0x00A4
APTailDummyX:     09F  0x7FFF
Elem0Next:        0A0  0x009D
Elem0D:           0A1  0x0003
Elem0X:           0A2  0x003D
Elem0Y:           0A3  0x000B
Elem1:            0A4  0x00A8
Elem1[1]:         0A5  ????
Elem1[2]:         0A6  ????
Elem1[3]:         0A7  ????


Переход на @@LeftMerge не выполняется, оно и ясно.

Далее, проверяем, не нужно ли обнаруженную точку объединить с пятном справа от нас. В аккумулятор заносится X-координата его центра, 0x3D = 61. Следующий слайд:



Вычитаем текущую X-координату, 0x3A = 58, получая 3. Затем вычитаем (D1+1)/2, то есть двоечку, получая 1. Наконец, вычитаем диаметр правого пятна, делёный пополам, получая -0,5.

Переход JL @@RightMerge срабатывает, и мы попадаем вот сюда:

64  82E0  @@RightMerge:   ADD         [Z+1]   ;в аккумуляторе лежало x-X-D/2-D1/2. Теперь прибавили D, получили x-X+D/2-D1/2
65  8E1D                  DIV2A       D1p2    ;прибавили D1/2, получили x-X+D/2 - новый диаметр пятна
66  E080                  [Z+1]       Acc     ;ага, записали.
67  8C80                  DIV2        Acc
68  82F0                  ADD         [SP+1]
69  8311                  SUB         1
6A  EA80                  [Z+2j+k]    Acc
6B  B013                  JMP         TaskPending


К значению в аккумуляторе, -0,5, прибавляем диаметр пятна слева от нас, 3, что должно дать 2,5.

Затем прибавляем (D+2)/2 = 2,5, что должно даёт 5. Это становится наш новый диаметр пятна, заносится в соответствующее место.

Затем мы делим его на 2, что должно дать 2,5. Прибавляем только что найденную координату, 0x3A=58, что должно дать 60,5. Затем вычитаем единичку, что должно дать 59,5. С выхода аккумулятора идёт значение 0x3B = 59 - и это становится нашим новым центром пятна.

Выглядит неплохо: пятно расширяется, при этом смещается влево. Если раньше по горизонтали в это пятно входил отрезок [60;62], то теперь получится отрезок [57;62], т.е ранее входивший диапазон никуда не делся, зато добавился новый, в который входит только обнаруженная точка 58.

Следующий слайд:


Прыгаем в "процедуру" TaskPending, но поскольку мы рассматривали самый первый отрезок на строке, мы из неё очень быстро выскакиваем, прямиком в @@MidCycle:

71  CDC8  @@MidCycle:     X           [X+k]
72  DDCD                  Y           X
73  84C8                  ABS         [X+k]
74  BA0F                  JO          @@FinalRange
75  F288  @@EndOfCycle:   [SP+2j+1]   GPUL            ;яркость
76  F08A                  [SP+1]      GPUH            ;пока не забыли - сразу второе слово запрашиваем (коорд точки), чтобы не сбить весь FIFO 
77  8A1E                  C           Nil         ;по умолчанию ставим метку "за нами должок!"                
78  80C2                  Acc         [X+2j+1]
79  8EC0                  DIV2A       [X+1]
7A  83FA                  SUB         [SP+2j+k]
7B  BC1F                  JGE         @@ActPointsStart
7C  8320                  SUB         nD1
7D  B821                  JL          @@RemoveBlob


Присваиваем X = 0x0A0 (то самое "пятно справа", которое мы только что подрихтовали). Затем Y=0x09B (старое значение X, "левое фиктивное пятно"). Проверяем, является ли это пятно "правым фиктивным", а именно смотрим его указатель Next. Если там значение -32768 - значит это "правое фиктивное".

Нет, в указателе Next лежит 0x09D, абсолютное значение от него не вызывает переполнения, поэтому прыжок по JO @@FinalRange НЕ ПРОИСХОДИТ. Мы начинаем обрабатывать отрезок [60;62]. Заметим, что строка изображения в этот момент уже окончилась, пришёл синхроимпульс - и теперь мы идёт back porch длиной 262 такта. Время ещё есть...

Получаем максимальную яркость на этом отрезке, 0 (инвертированное значение). X-координата 0x3C = 60, логично. В регистр C мы должны были записать значение -32768, то бишь 0x8000.

Но за каким-то хреном туда отправилось значение 0x8600, или -31232.

Хм, что-то наш компилятор намутил:
34304 FFFF C Nil


Хотя объявлена эта константа была так:
Nil			EQU	-32768


Похоже, тут очередной "прикол" с расширением знака. У меня все значения в компиляторе хранятся как 32-битные целые, причём младшие 16 бит - само значение, а в верхних битах сидит некоторое количество "флажков", типа того, это у нас адрес в данных или в коде, и вообще это адрес или литерал, и ещё 2 бита - это указатель на 16 бит, или на 8 бит, причём "верхние" или "нижние".

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

Поставим AND где надо, чтобы лишние биты обрубать.

32768 FFFF ACQ VSync/C Nil                                                               


Да, кажется, сработало.

В этом и был весь сыр-бор? Весьма вероятно: из-за неправильной установки этого значения у нас вообще никогда не заказываются отрезки на обработку при вызове TaskPending, и это явно не сулит нам ничего хорошего...

Попробовал снова запустить "в железе" программу, пропущенную через исправленный компилятор. Получилось как-то совсем грустно:


Всего 4 строки. Впрочем, там в самом-самом углу чрезмерно яркие пиксели, у меня вся эта конструкция на подоконнике, и как раз с угла проникает свет из окошка, а я как раз поставил малую яркость светодиодов, 3 (3,8% от максимума).


Ладно, пока постелил туда свой чёрный свитер, сейчас яркость поднимем на побольше - и попробуем снова. Так оно выглядит через старый добрый ImageTransfer:


А если применить порог 254, то выйдет так:


Попробуем ещё разочек...


Да, мы снова добрались до первого пятна, а потом "пошли вразнос" - видно, как там сбилась синхронизация. Ну и остановилась работа по прерыванию "Исчерпание заданий GPU".


Пора начинать сначала! Но одной ошибкой стало меньше - уже радость. Но сначала придётся бумажками позаниматься.
Tags: ПЛИС, программки, работа, странные девайсы
Subscribe

  • Ремонт лыжных мостиков

    Вернулся с сегодняшнего субботника. Очень продуктивно: отремонтировали все ТРИ мостика! Правда, для этого надо было разделиться, благо народу…

  • Гетто-байк

    В субботу во время Великой Октябрьской резни бензопилой умудрился петуха сломать в велосипеде. По счастью, уже на следующий день удалось купить…

  • А всё-таки есть польза от ковариаций

    Вчера опробовал "сценарий", когда варьируем дальность от 1 метра до 11 метров. Получилось, что грамотное усреднение - это взять с огромными весами…

  • Так есть ли толк в ковариационной матрице?

    Задался этим вопросом применительно к своему прибору чуть более 2 недель назад. Рыл носом землю с попеременным успехом ( раз, два, три, четыре),…

  • Big Data, чтоб их ... (4)

    Наконец-то стряхнул пыль с компьютерной модели сближения, добавил в неё код, чтобы мы могли определить интересующие нас точки, и выписать…

  • Потёмкинская деревня - 2

    В ноябре 2020 года нужно было сделать скриншот несуществующей программы рабочего места под несуществующий прибор, чтобы добавить его в документацию.…

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 0 comments