nabbla (nabbla1) wrote,
nabbla
nabbla1

Categories:

QuatCore: ещё два прерывания

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

Возможны две "исключительные ситуации". Первая: QuatCore не успел вовремя "озадачить" видеопроцессор - и тот не знает, что ему делать с УЖЕ ПОСТУПАЮЩИМ сигналом. Остановить его нельзя, и даже если я всё-таки заполучу в свои загребущие лапы отечественную фотоприёмную матрицу 1205ХВ014, её остановить тоже будет нельзя. Мы могли бы, конечно, остановить подачу тактовой частоты, но в документации про такое ничего не пишется - могут полезть очень неприятные вещи. У нас эта ситуация названа Underflow, или UFLO, то бишь "исчерпание".

Вторая ситуация: QuatCore не успевает обработать результаты работы видеопроцессора - и те накапливаются в выходном буфере, пока не заполнят его до предела. В итоге новым данным поступать некуда - и они пропадают. Опять же, мы не можем приказать фотоприёмной матрице (или аналоговой камере) "горшочек, не вари!". У нас эта ситуация названа Overflow, или OFLO, то бишь "переполнение".

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

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

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

Начнём традиционно с "железа".


Оставим вход NMI (Non-Maskable Interrupt), только теперь разные прерывания надо будет объединять по "ИЛИ". Но чтобы узнать, какое именно прерывание случилось, сделаем шифратор, который сигнал по "нулевому" входу преобразит в код "00", по "первому" - в "01", по "второму" - в "10".

Всё это запихаем в один модуль, причём не будем пытаться сделать его слишком уж "общим" (параметризованным). Я хочу, чтобы QuatCore подстраивался под конкретную задачу, и эти прерывания - это одна из наиболее специфических вещей. Конкретный код куда проще для понимания, так что имена дам понятные, а не просто NMI0, NMI1, NMI2:

module QuatCoreCVinterruptEncoder (input OFLO, input UFLO, input WDT, output StallEn, output NMI, output [1:0] intN);

assign NMI = OFLO | UFLO | WDT;

assign StallEn = ~NMI;

assign intN = WDT? 2'b00:
                OFLO? 2'b01:
                        2'b10;

endmodule


Как водится, чем мельче модуль - тем мудрёнее его имя! Здесь оно означает: "шифратор прерываний для технического зрения (Computer Vision, CV) на основе QuatCore".

И впихивается оно как-то так, между видеопроцессором и QuatCore:


Но, как видно, "номер прерывания" (intN) пока привести некуда, нет подходящего входа у QuatCore. Пора его добавить, сначала в QuatCore, затем уровнем ниже, в QuatCorePC (program counter), и, наконец, в QuatCoreCallTable.

Вот в QuatCore можно ввести параметризацию на количество бит, требующихся для "номера прерывания". Сейчас нам хватает 2 бит, но аппетит приходит во время еды, может ещё что-нибудь захотеться.

Так теперь выглядит QuatCorePC:


В кои-то веки удалил ненужный параметр RelAddrWidth (сколько бит занимает "относительный адрес" - нет их у нас больше!), вместо него всунул nmiWidth. Не самое удачное название, но пока так.

Уровнем выше, в QuatCore, ничего интересного, просто ещё один проводок:


Ну и параметр nmiWidth объявили и здесь, чтобы не приходилось каждый раз лезть "в потроха".

Наконец, теперь и на уровне QuatCore+GPU+периферия также появился нужный вход, так что можно завершить схему...


При этом ушло два вывода на "самом верхнем уровне", тех самых Underflow и Overflow, которые я первоначально планировал вывести через регистры-защёлки на какие-нибудь светодиодики :) Как результат, все выводы на схеме "поехали" - ковырялся возвращал их на место. Но это и хорошо: штука потихоньку приобретает законченный вид, избавляясь от "отладочных" выводов.

Синтезируется оно успешно, даже каким-то чудом получилось на 1 ЛЭ меньше, чем в прошлый раз, Fitter "живёт своей жизнью".

Далее, допишем программу. Не буду сейчас приводить её всю (она есть в предыдущем посте), только кусок, посвящённый обработке прерываний:

;Обработка немаскируемых прерываний (а других пока и нет :))
	.data
		CommonError	dw	0x101,'Ошибка: ',0
		NoVideoSignal	db	'нет сигнала',0
		UnderflowInt	db	'исчерпание  ','заданий GPU',0
		OverflowInt	db	'переполнение','результатов GPU',0
	.code
	GPU_WDT:	Y	NoVideoSignal
			JMP	IntHandler
	GPU_UFLO:	Y	UnderflowInt
			JMP	IntHandler
	GPU_OFLO:	Y	OverflowInt
	IntHandler:	SIO	LCD
			X	CommonError
			CALL	print
			X	Y
			CALL	print
	@@endless:	JMP	@@endless


Жадность традиционно зашкаливает: первая посылка, поступающая на ЖК-экранчик, хранится по 16-битным словам, чтобы можно было вместе с обычными символами иметь команду "очистка экрана". А уже сообщения, специфичные для каждой ошибки хранятся по байтам.

В будущем может захотеться ещё и получить "дамп памяти" - уже картинка, приведшая к ошибки - уже интересно. Но не всё сразу.


"Железо" почти готово. В последний момент сообразил, что OFLO и UFLO включаются "надолго", не на один такт, поэтому надо будет добавить формирование одиночного импульса, а вот "сторожевого пса" можно будет слегка упростить. Но даже тогда я ожидаю, что UFLO "зажжётся" СРАЗУ ЖЕ, потому как при включении на видеопроцессоре нет никаких заданий. Нужен и здесь дополнительный регистр, чтобы "ловить" именно прорехи во время обработки кадра. Как только кадр закончился, а новый мы не заказали - можно и отдохнуть с чистой совестью.

Программа готова.

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

Recent Posts from This Journal

  • Лестница для самых жадных

    В эти выходные побывал на даче, после 3-недельной "самоизоляции". Забавно, как будто зима началась! Особенно грязные галоши остались на улице, в…

  • Возвращаемся к макету

    Очень давно макетом видеоизмерителя параметров сближения не занимался: сначала "громко думал" по поводу измерения его положения на аппарате, а потом…

  • Минутка живописи

    В процессе разгребания содержимого квартиры (после нескольких ремонтов) дошёл, наконец, и до картин. В кои-то веки их повесил. Куда их вешать -…

  • Костыль ноутбуку и кабели Франкенштейна (это не я!)

    Продолжаю разгребать хлам, накопившийся за много лет, раз уж всё равно на карантине сижу. Довольно продуктивный день: починил ноутбук (грубо, но…

  • Атомный файлсервер, убитые петухи и харакири андроида

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

  • Ещё про яркий светильник и ИБП

    Всё-таки применил лежащее дома барахло наиболее простым образом: А ещё наконец-то замерял температуру теплоотвода яркого светильника на кухне,…

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 6 comments