nabbla (nabbla1) wrote,
nabbla
nabbla1

Categories:

QuatCore+GPU, строка 9

Продолжаем смотреть на симуляцию обработки видео в реальном времени с помощью связки QuatCore и "GPU" - довольно простого обработчика видео, немногим более сотни ЛЭ. Львиную долю логики у нас сжирают буферы FIFO на вход и выход, их оба пришлось увеличить до 5 "ячеек", иначе мы "сбиваемся с ритма".

Сейчас мы здесь:

Самую сложную строку мы уже обработали, и заказали такие же 5 отрезков на следующую строку, но нас ждёт разочарование: она вообще будет ПУСТАЯ. И совсем скоро выполнится код по перемещению точек из списка активных ActivePoints в список "отработанных", который мы в своей неземной мудрости обозвали AllPoints...


Напомним: входной буфер GPU из 5 ячеек "забит под завязку": первой командой, выполняющейся в этот самый момент, является HSync (ожидание строчного синхроимпульса и пропуск нужного числа тактов, так называемый Back porch) и затем 4 отрезка. Пятый ("до конца строки") уже не влез, поэтому QuatCore остановился в самом конце цикла по строкам, в ожидании, когда сможет отдать это пятое задание, "стиснутое" на шине DataBus, и заняться наконец своими делами...


Только когда началась полезная область новой строки (задание HSync отработано), мы смогли положить задание ACQ WholeRow (последний, пятый отрезок) и снова застряли на ACQ HSync. Его мы смогли отправить, когда видеопроцессор уже обработал первый отрезок, ACQ 0x0B.

После этого мы проверили, что "закругляться" ещё рано, строки обработаны не все. Прибавили единичку, перепрыгнули в начало цикла по строкам, занесли новую Y-координату 9 на её место, [SP+2]. И пока мы делали это нехитрое дело, видеопроцессор обработал ещё 3 отрезка! Но ничего страшного не случилось: у нас и выходной буфер на 5 позиций, сейчас заняты 4.

Смотрим дальше:


Здесь мы получаем информацию от GPU о первом отрезке: яркость 0xFFF (то есть нулевая), координата 0. Вычитаем эту яркость из порога, убеждаемся, что ловить нечего - и переходим в @@MidCycle.

Там уже знакомые все значения: в регистре X лежало 0x10 - адрес левой фиктивной точки, заносим его в Y на всякий случай (вдруг следующую точку будем удалять), а X "итерируем" по списку, он теперь указывает на 0x15, адрес первой нашей точки (левой верхней). Затем в аккумулятор отправляем указатель с этой точки дальше по списку, 0x1A. Это не Null, значит наша текущая точка это ещё не правая фиктивная, значит, нужно уточнить её координаты. Условный переход на @@FinalRange не выполняется, вместо этого в аккумулятор загружаем яркость текущей точки (указанную в списке), 0x39A.

Смотрим дальше:


Запрашиваем у GPU данные по второму отрезку (под нашей яркой точкой): яркость 0xFFF (нулевая), координата нулевая. Сравниваем яркости и "незаметно" прыгаем на @@NotSoBright.

Там мы загружаем в аккумулятор текущий номер строки, 9. Вычитаем Y-координату нашей яркой точки, 7, а потом вычитаем диаметр, 6, делёный на два. Получается -1 - число отрицательное, что означает: мы ещё не столь далеко от центра пятна, и на следующей строке ещё на всякий случай поищем. Поэтому прыгаем на @@QueueAnyway, а оттуда сразу вызываем процедуру AcqQueue. Пока ещё помню, что можно было чуть поиграться с прыжками и вызовами, и сэкономить несколько тактов, избежав лишних "сбросов конвейера", но переделывать лениво...

Смотрим дальше:


Успешно пропукаем цикл, в котором мы обновляем параметры точки в списке, переходим сразу к "озадачиванию" GPU. Кстати, он уже закончил обработку строки, получил синхроимпульс и теперь отсчитывает 238 тактов. То есть, в нём ровно 1 задание, и ещё 4 позиции буфера пустуют. Мы опять даём ему 2 новых задания: ACQ 0x0B и ACQ 0x11. Поскольку буфер пустует, они заносятся за один такт (задержку в данном случае дают команды по SrcAddr, [X+1] и [--SP], им нужен лишний такт на выборку из памяти). Ну и возвращаемся из процедуры, и тут же прыгаем в начало цикла по списку активных точек.

Смотрим дальше:


Меня пугает, что больше не приходится сверяться с листингом, чтобы видеть, что здесь происходит. Ох, пора в отпуск...

Здесь мы запрашиваем у GPU данные по короткому отрезку в 1 пиксель. Ответ всё тот же: яркость 0xFFF (нулевая), координата 0. Сверяемся с порогом, переходим на @@MidCycle, там в регистр Y запоминаем адрес текущей точки в списке, 0x15, в X заносим адрес следующей точки, 0x1A, а в аккумулятор - точки "через одну", 0x12. Это не Null, значит, нужно уточнить координату ещё одной точки, которая у нас правее на картинке.

Смотрим дальше:


Запрашиваем у GPU параметры отрезка под "правой точкой". Как оказывается, яркость всё-таки не нулевая, а 0xFA1, что после инверсии даёт 0x5E = 94, что для 12-битного АЦП (0..4095) вообще "ниже плинтуса". Но всё-таки, какое-то разнообразие. Потому и координата в кои-то веки осмысленная: 0x15.

Ожидаемо прыгаем на @@NotSoBright, где повторяем ту же проверку по Y-координате. Приходим к тому же ответу: ещё одну строку мы всё-таки запросим. Тут не сколько "надежда" увидеть что-то яркое, сколько опасение, что если мы не "отнесём" нечто светлое в этом месте к текущей точке, то как будто бы обнаружим ещё одну точку, и запутаемся в них.

Поэтому мы снова попадаем в процедуру AcqQueue:


По "прямолинейному ходу" PC сразу видно: цикл мы опять пропустили, то есть параметры точки в списке не обновляем, сразу "озадачиваем" GPU, теми же двумя отрезками, до 0x12 (коротенький, в 1 пиксель) и до 0x18. Входной буфер GPU заполнили целиком, а до окончания задания HSync осталось ещё около 100 тактов.

Возвращаемся в начало цикла по списку ярких точек:


Здесь мы запрашиваем у GPU результаты по последнему отрезку. Они столь же незамысловаты: яркость 0xFFF (нулевая) и координата 0. Всё, теперь нам не страшно завершение задания HSync - мы САМИ ОПУСТОШИЛИ ВЫХОДНОЙ БУФЕР, и сколько-нибудь заблаговременно :) Поскольку яркой точки мы на отрезке не нашли, перепрыгиваем в @@MidCycle, где заносим в Y адрес текущей точки из списка: 0x1A, в X заносим адрес следующей, 0x12, а в аккумулятор следующей за ней, 0x8000, то есть NULL. Поэтому прыгаем в @@FinalRange:


И как и в прошлый раз, "застряли" на передаче последних двух заданий по строке, WholeRow и HSync.

Обработку строки 9 успешно завершили!

Увы, ни одной "новой" строки кода мы так и не исполнили, шли уже проторенными дорожками.

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

  • О вытягивании себя из болота по методу Мюнхгаузена

    Всё готовлюсь к встрече с представителями РКК Энергия, нужно убедить их в моём способе определения положения ВидеоИзмерителя Параметров Сближения на…

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

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

  • Гетто-байк

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

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 0 comments