nabbla (nabbla1) wrote,
nabbla
nabbla1

Categories:

Макет ВИПС: дамп памяти

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


Первые 53 строки всё хорошо, а дальше как будто бы начинается запись "всего подряд", вместе с синхроимпульсами, и через некоторое время совсем всё останавливается. Но увы, мы не знаем, это причина или следствие "сбоя"?

Пожалуй, надо наконец получить дамп оперативной памяти, благо её у нас всего 512 слов, или 1024 байта :) Причём львиная доля занята всевозможными "надписями".


К сожалению, наш передатчик UART из 16-битного слова на шине берёт только младшие 8 бит, поэтому совсем "в лоб" передать слово за слово не удастся. Есть несколько решений...


Первая мысль у меня была: сделать "адаптер" между UART и QuatCore, который может работать в старом "байтовом" режиме, либо в 16-битном, на каждую команду со стороны QuatCore инициируя передачу ДВУХ байт.

Я чуть было не начал делать подобный модуль, только имеющий 1-битный режим - хотел таким способом передавать ч/б изображения, чтобы не ждать по 8 секунд появления каждого "экранного меню". Уже успел этот модуль поставить на "схему". Поначалу было так:
OrigSchematic.png

UART соединялся практически "напрямую", а теперь появился модуль QuatCoreBitByteUART:
OrigSchematic.png

И даже лишний бит был выделен в QuatCoreIOSelector, чтобы можно было выбирать между двумя режимами работы.

И логику работы худо-бедно продумал.

[Spoiler (click to open)]
В байтовом режиме (когда подаётся isBitMode=0) контролируется, занят ли наш регистр. Изначально он свободен - и мы ничего не делаем. Если поступает st=1, мы "защёлкиваем" младший байт из шины данных, и к следующему такту регистр становится занят. Формируется UART_st=1, и если в ответ не приходит UART_busy, то регистр снова считаем свободным - теперь он может "защёлкнуть" новое значение с шины данных. Если же продолжается UART_busy=1, и при этом снова пришёл st=1, то уже формируется busy=1 для QuatCore: "Горшочек, не вари!". В смысле, что и передатчик UART занят, и мы свой регистр заняли - и теперь ждём.

В битовом режиме (когда подаётся isBitMode=1) должен работать 3-битный счётчик (от 0 до 7). Изначально на нём ноль, что означает: все биты свободны. При поступлении st=1, защёлкивается один-единственный бит, со сдвигом регистра влево и прибавлением счётчика. Как только счётчик доходит до 7, это означает, что все 8 бит уже защёлкнуты - в этот момент выдаётся UART_st=1, и если UART_busy=0 (т.е передатчик был свободен и взял у нас этот байт) - счётчик возвращается в нулевую позицию. В противном случае - остаётся в 7-й позиции, и при очередном поступлении st=1 будет выдан busy=1.


В принципе, идея работоспособная, и можно было бы вообще универсальный модуль сделать - хочешь по 16 бит передаёшь, хочешь по 1 биту, ну или по умолчанию 8 бит.

Но на самом деле всё уже есть!
Мы же ввели "байтовый режим" памяти, когда адресные регистры X и SP имеют двумя битами больше, чем надо, и эти 2 бита выбирают "режим":
00 - обычный доступ по целым словам,
10 - вместо всего слова подаётся младший байт, а старший "зануляется",
11 - вместо всего слова подаётся старший байт на месте младшего, а старший байт шины данных "зануляется",
01 - "зарезервировано"


Когда у нас объём оперативной памяти 512 слов, регистры X и SP становятся шириной 11 бит.
Адреса от 0x000 до 0x1FF соответствуют обычному доступу по целым словам,
адреса 0x200 до 0x3FF пока "зарезервированы" (на самом деле будут доступны те же самые 0x000 до 0x1FF, этот бит просто будет проигнорирован), а вот
адреса 0x400 до 0x5FF будут соответствовать доступу к младшим байтам, и
адреса 0x600 до 0x7FF - доступу к старшим байтам памяти.

Получается, нам достаточно присвоить SP = 0x400 - и потом просто передать 1024 байта подряд, с помощью [SP++]. Дёшево и сердито! Нравится мне этот "байтовый режим", на удивление легко пошёл! Конечно, сейчас "накаркаю", но посмотрим.

Для начала, уберём передачу изображения, и сделаем взамен передачу дампа памяти. Со стороны макета ВИПС напишем так:

	;рано или поздно мы попадаем сюда...				
	;endless:	JMP	endless	
	DebugLoop:	SIO	UART
			ERL	0
			ERH	0	;заблаговременно, чтобы не было IO Hazard	
			NOP	IN
	;чуть позже будем определять, какой символ нам дали, а пока тупо отправим картинку
				
			;самое смешное: у нас в 16-битный регистр не влезет то число, до которого делать итерации!
			;либо применить FMA, либо тупо 2 вложенных цикла
			; j	29
; @@OuterLoop:	Acc	24575		;24576 * 30 = 1024 * 720 
; @@InnerLoop:	OUT	[ER++]
			; SUB	1
			; JGE	@@InnerLoop
			; jLOOP	@@OuterLoop
				
			;а теперь давайте дамп передадим
			SP	0x400	;кривовато, мы привязываемся к разрядности адреса, но для сельской местности сойдёт
			Acc	1023
	@@Loop:		OUT	[SP++]
			SUB	1
			JGE	@@Loop
			
			JMP	DebugLoop


Результат можно увидеть на картинке в начале поста. По крайней мере, похоже на правду. Строки отчётливо видны, а вот 16-битные значения здесь разбиты и разнесены в стороны.

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

А с упаковкой в слова получается вот так:


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

Слева - начальное содержание оперативной памяти, справа - наш "дамп".

Эх, какой-нибудь инструментарий всё-таки хотелось бы, но разок можно и ручками поковыряться, как в старые добрые времена. Получается так:



Сначала идут всевозможные строки: для инициализации Ethernet-контроллера (отключить всё лишнее и дать нам тактовую частоту 25 МГц), ЖК-экранчика, "приветственное" сообщения, всевозможные сообщения об ошибках и о результатах работы. И что радостно, они остались как были.

Далее идёт "динамическая память", в смысле что связанные списки. Список ActivePoints имеет указатель на "правую фиктивную точку" (сам являясь "левой фиктивной точкой"), а она указывает на Null/nil, короче никуда не указывает. Так и должно быть - по окончании работы список ActivePoints освобождается!

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

Первый параметр - это "радиус", и вот с ним что-то странное. Радиусы составляют чаще всего 9, но есть точки покрупнее: 0x71 = 113 пикселей. Кстати, очень похоже на правду :) Вот только выбивающиеся отсюда точки смущают.

Y-координата идёт по возрастанию, что похоже на правду. X скачет взад-вперёд.

Пожалуй, надо сейчас написать программу для визуализации результатов измерений.

Наконец, в самом низу "притаился" стек. И его значения даже осмысленны. Первое: 0x8B, вот оно где в коде:

88  CD2B                  X       SizeStr
89  80E0                  Acc     [Z+1]   ;размер точки
8A  F3BC                  CALL        CallThemAll             
8B  8801      @@moveOn:   ZAcc        RoundZero


Это как раз последний раз, когда мы вызывали процедуру из главной функции (CALL CallThemAll), и адрес возврата заносили "на один больше", как и положено.

Второе значение, A9, лежит как раз внутри CallThemAll:
    CallThemAll proc
A7  F3BD          CALL    print
A8  F3BF          CALL    BetterBin2Bcd
A9  0034          OUT 13
AA  0035          OUT 10
AB  B0FF          JMP [--SP]
    CallThemAll endp


Это также следующая строка за последним вызовом процедуры ОТСЮДА.

И наконец, 0x18 = 24 - это количество обнаруженных точек, мы хранили его в регистре i, но при вызове Bin2Dec сохраняли значение в стек, чтобы использовать регистр по своему усмотрению.


Такое ощущение, что оно почти работает! А то, что точек обнаруживается не 4 штуки, а 24 - думаю, что проблема не "аппаратная", а непосредственно в алгоритме. Он придумывался для маленьких точек, у которых яркость от центра спадает к краям. Тут же у нас равномерно засвеченные "блямбы". Думается, видеопроцессор в качестве точки с максимальной яркостью раз за разом указывает НАЧАЛО отрезка, а потом в противоположном конце нашего пятна как бы обнаруживается ЕЩЁ ОДНА точка, и однажды обнаруженные, они уже не могут сливаться. Впрочем, надо смотреть.
Tags: ПЛИС, программки, работа, странные девайсы
Subscribe

  • Я создал монстра!

    Вот нормальная счастливая пара разъёмов ОНЦ-БС-1-10/14-Р12-2-В и ОНЦ-БС-1-10/14-В1-2-В: У розетки кроме основного выступа, отмечающего "верх",…

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

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

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

    Вчера я чуть поторопился отсинтезировать проект,параметры не поменял: 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