QuatCore

Conduit - что за хрень?

В Quartus'е, если соединять модули на "принципиальной схеме" (Block Diagram), есть 3 типа соединителей:

- провод (wire) - обозначен тонкой линией. Соединяет "один бит";
- шина (bus) - обозначен жирной линией. Соединяет массив бит;
- жгут (conduit) - обозначен сдвоенной тонкой линией. Может содержать в себе провода и шины.

Так вот, эти жгуты я ещё ни разу не применял. По описанию, можно его закидывать в модуль, и одноимённые провода и шины должны соединиться автоматически.

Кажется, может пригодиться для QuatCore, чтобы не соединять раз за разом SrcAddr[7:0], DestAddr[7:0], DataBus[15:0], SrcDiscard,SrcStall, DestStall. Но пока лениво.

Кто-нибудь пользовался этим? Оно того стоит?
QuatCore

Видеообработчик: нахождение "второй" суммы

Вот этой суммы:

До сих пор не знаю, как её правильно обозвать.

Ничего сложного, соответствующий блок уже был готов:


Collapse )

Самое простое сделали, пора делать "обвязку" для подключения к QuatCore. Почему-то вся эта логика (когда нужно разрозненные модули объединить в цельную систему) до сих пор меня очень пугает, вводит в ступор на длительное время. Потом, вдоволь насмотревшись "в одну точку", начинаю делать - и рано или поздно что-то получается.
QuatCore

Максимум и сумма - "в одном флаконе"

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

Может показаться, что это принципиально разные задачи, но как ни странно, их можно возложить на один модуль.

Collapse )

Дальше на очереди: "вторая" сумма (яркостный центр: способ получше) и "обвязка" для QuatCore...
QuatCore

Тестовая картинка для видеопроцессора

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



Так наша "мишень" должна выглядеть с расстояния 300 метров. Практически пустой кадр 1024х1024, а вся информативная часть умещается в 32х32 (именно такая эта картинка, я её увеличил до 64х64 методом nearest neighbour, просто чтобы лучше было видно).

Кажется, что именно работа с большой дальности для видеопроцессора наиболее "нервная" - счёт идёт на пиксели, и нужно успевать отправить измеренные результаты в QuatCore, а тем временем уже сбрасывать сумматоры и приниматься за следующий фрагмент!

Попытаемся понять, что же там должно твориться...

Collapse )

Poll #2102244 Данные с видеообработчика

Как передавать данные на процессор QuatCore?

Обычным способом, через шину данных, но ввести буфер на 2-3 отрезка
2(66.7%)
Прямой доступ к памяти (DMA)
1(33.3%)
Видеообработчик должен "поумнеть" и не дёргать QuatCore по пустякам
0(0.0%)
slow loris

Дополнение про велосипед

Ко вчерашнему.

Тогда, как посчитал, что проехал 590 км - решил в кои-то веки цепь поменять, пока она совсем звёздочки "под себя" не заточила. Потому как есть такая рекомендация: купить новую кассету (задние звёздочки) и три новых цепи, и затем их попеременно заменять, и ехать "пока едется", а когда начнёт проскакивать со страшной силой - выкинуть всё это нафиг - и опять купить новую кассету и три новых цепи.

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


(осторожно, ненормативная лексика)

Collapse )
ook

Велопробегом по короновирусу - продолжение

Прошло ровно три недели, как я стал ездить на работу исключительно на велосипеде, и туда, и обратно. За это время ещё и три раза (по разу каждую неделю) ездил в РКК Энергию. Туда - на велике, потом садился на электричку и доезжал от Подлипок-Дачных до Яузы, а оттуда на работу уже на велосипеде.

И за это время дважды съездил на выходные на дачу, на велосипеде с работы до станции Ростокино, там на электричке-экспрессе до Сергиев Посада, и оттуда уже своим ходом на дачу. Назад - примерно также, только не на экспрессе (их утром нет), и до Яузы, а оттуда уже до работы.



Collapse )
QuatCore

Яркостный центр: способ получше!

В продолжение этого

Что-то перемудрил: поставил туда аж целый перемножитель, занимающий 250 ЛЭ, а уже под вечер сообразил: без умножения на каждом такте можно обойтись!

Collapse )
QuatCore

Нахождение яркостного центра пятна

Пора, наконец-то, взяться вплотную за видеообработчик!

Возможно, для начала нужно будет немножко сигнал "подрихтовать" - устранить "битые пиксели", если таковые появятся. В этом больших проблем не вижу, по крайней мере, при наших довольно щадящих требованиях по радиационной стойкости. Думаю, поставлю критерий "если яркость пикселя существенно выше или существенно ниже, чем среднее от его соседей, признаём его битым и заменяем на это среднее". Поскольку у любого объектива есть функция рассеяния точки (ФРТ), т.е даже точечный объект никогда не займёт СТРОГО ОДИН ПИКСЕЛЬ, а на самом деле расползётся в площадку, у нас это 3х3 (чтобы субпиксельную точность получить), то оно вполне себе сработает.

А пока о самом сложном, на мой взгляд. Видеообработчику посылаются предполагаемые координаты ярких точек (наших мишеней), некие (x0, y0). И затем, когда он начинает получать текущий кадр строка за строкой, пиксель за пикселем, он должен для всех точек на расстоянии менее R от (x0, y0) найти выражения:


(сумма яркостей всех пикселей),


(сумма яркостей пикселей, помноженных на их горизонтальное смещение от предполагаемого центра)

и

(теперь умножаем на вертикальное смещение от предполагаемого центра)

И затем, уже на QuatCore можно будет получить:

и


это смещение яркостного центра от предполагаемой позиции, измеренное С СУБПИКСЕЛЬНОЙ ТОЧНОСТЬЮ.

Можно было бы посчитать яркостный центр напрямую, заменив x0, y0 на ноль, но тогда промежуточные значения могут получаться ОЧЕНЬ БОЛЬШИМИ. Зная, что пятна имеют хоть сколько-нибудь ограниченный размер, используя "мои" формулы с x0 и y0, можно несколько облегчить себе жизнь.

Поразмышляем, как это реализовать "в железе"...

Collapse )

Итого, на выполнение "непосредственно вычислений" по нахождению яркостного центра, у нас уходит 34 ЛЭ на первую сумму и 250 ЛЭ на вторую, всего 284 ЛЭ.

Но к этим вычислителям теперь нужна обвязка: они каким-то образом должны передать результаты своей работы в QuatCore, а он, в свою очередь, должен управлять неким блоком, который будет в нужные моменты времени обнулять эти суммы и также пинать QuatCore, когда на выходе формируется результат...
QuatCore

Подключаем статическую память к "ускоренному" QuatCore

Надеюсь, что эта статическая память будет чисто в "отладочных целях": записать туда видеокадр целиком и потихоньку переправить на компьютер по UART, чтобы потом можно было проверить, правильно ли сработал видеообработчик. Видеообработчику эта память не нужна, он должен "на лету" работать!

На 4 МГц мы её уже подключали, теперь только нужно модифицировать интерфейс для "ускоренного" QuatCore с его конвейерными заморочками...

Collapse )



Работает! Это очень радостно, поскольку там могли быть проблемы с таймингами, всё очень "впритык". Возможно, разогрейся эта статическая память градусов до 60, и получи пониженное напряжение, 3 вольта вместо штатных 3,3 вольт - и уже начнёт "глючить", в смысле что не успевать вовремя сформировать выходные значения, либо запишет значения по неверным адресам, поскольку новый адрес не успел "распространиться".

Но как уже говорилось: мне эта память чисто в отладочных целях, и её работа "в крайних режимах" мне особо не нужна. Работает при комнатной температуре на 3,3 вольтах - я счастлив :)

Следующий этап: сделать своеобразный "DMA", так что в эту статическую память будет записываться оцифрованная картинка (вообще минуя ПЛИС), а потом уже QuatCore займётся её пересылкой на компьютер.
QuatCore

Hello, world теперь на 25 МГц

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

Ещё у меня дурацкая мысля возникла, что на ПЛИС, для этого "софтового" процессора не очень-то нужен вход reset, ведь он всё равно сбрасывает не всё. Если мы уже успели "затереть" что-нибудь в своей оперативной памяти, то reset это на место не вернёт, тут уж лучше всю ПЛИС сбросить, тогда она отконфигурируется по-новой, в том числе инициализирует содержимое блоков внутренней памяти. По счастью, достаточно лишь "заземлить" вход reset - и при синтезе всё ненужное уберётся.

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

Collapse )



Фурычит. И на 25 МГц мы наконец можем поставить частоту UART в 921600 бод, это деление частоты в 27 раз, получается с точностью 0,5%, это допустимо. С 4 МГц оно делиться правильно не хотело, разве что "дробный" делитель сделать, но всё равно же каждый бит тогда будет "дёргаться" из стороны в сторону, какой-то будет занимать 4 такта, какие-то 5 тактов, джиттер, так сказать.