nabbla (nabbla1) wrote,
nabbla
nabbla1

Categories:

Отладка QuatCore+GPU - вторая попытка

Первый раз, когда запустили в четверг, обнаружили, что запускается процессор нормально, начинает закидывать задания в видеообработчик, а тот наглухо застревает на самом первом, на обнаружении кадрового синхроимпульса. На следующий день, поковырявшись с модулем управления видеообработчиком, нашли, в чём было дело - приоритет управляющих сигналов был неправильным, ena имела приоритет над VSync/HSync, а надо было наоборот. Пора двигаться дальше.

Запустили симуляцию схемы "в сборе" - теперь кадровый синхроимпульс мы успешно словили:


К следующему такту, как видно по сигналу Sum, сумматоры были сброшены, и поступил запрос во входной буфер FIFO. Он, получив запросы одновременно и на запись, и на чтение, тут же снял SrcStallReq (запрос на приостановку процессора), так что он выполняет команду kLOOP @@topRows (прыгаем в начало цикла, 10 строк ещё не отсчитали), один такт совсем пропускаем (в конвейере остались незадействованные команды), на другом загружаем значение 0x40F0 (очередное задание для GPU), и снова застреваем на том же самом месте.

Пока всё верно. Далее начинается длительная пауза - мы хотим встретить строчный синхроимпульс, а затем ещё выждать 0xF0 = 240 тактов перед тем, как взяться за следующую команду.


Отсчитали 0xF0 на этой строке - и ничего не произошло.

Я было решил, что это глюк, но всё верно: когда к нам поступила эта команда 0x40F0, строчный синхроимпульс был уже позади, поэтому мы ждём следующего. Его пока не было - и мы никак не отреагировали. Всё верно.

Ждём дальше. Вот он синхроимпульс:


Внутренний регистр видеообработчика XReg сбросился в ноль - это правильно. А больше ничего пока не произошло, и это тоже верно. Вот теперь отсчитываем 240 тактов (0xF0):


Да, по достижении 0xF0 видеопроцессор достаёт из буфера следующую "команду", соответственно освобождается QuatCore и снова проходит по циклу, и снова застревает на посылке следующей команды 0x40F0. Пока что была выполнена одна команда VSync и одна команда HSync, в буфере лежит ещё 4 команды HSync, а всего их должно быть 10 штук.

На T=965 мкс у нас завершается ещё одна команда, и QuatCore заносит в буфер ещё одну такую же. Ему осталось сделать это ещё 4 раза.
На T=979,05 мкс происходит то же самое, осталось 3 итерации цикла в QuatCore.
Затем, T=993,01 мкс, и остаётся 2 итерации цикла в QuatCore.
Примерно на T=1,007 мс завершается ещё одна такая же команда, и остаётся 1 итерация цикла QuatCore.

Наконец, на T=1,021 мс начинается самое интересное:


Команда kLOOP уже не приводит к прыжку (у нас наконец-то k=0), поэтому она не мешает подгрузить данные для следующей команды, [Z+k]. Это мы заносим куда-нибудь "поближе" расчётный диаметр наших пятен, D1. Это получилось число 3 - именно его мы и положили, хотя меня сейчас гложат сомнения, не должна ли там быть шестёрка? Ну ладно, потом сообразим...

Заносим эту тройку в регистр C, тем временем обрабатываем "непосредственное значение" 0x0A, которое превращается в 0x0028 = 40. Именно так мы задали ImgHeight, а поскольку это число отправляется в память, то все 16 бит у нас были заданы правильно, QuatCoreImmTable в этот раз не "жадничал".

На следующем такте это значение 0x0028 поступает в [SP+2j] = [SP], т.е в "первую локальную переменную". Надеемся, что попадёт оно куда надо, не стали выводить шину адреса оперативной памяти, потому как в последнее время туда "не лезли", и скорее всего ничего не сломали. А тем временем обрабатывается "непосредственное значение" 0x37. Оно преобразуется в 0xCDB6, а вообще это адрес для JMP. И тут происходит конфуз. Компилятор честно нас предупредил: ширина адресной шины кода 7 бит. И действительно, если откусить от 0xCDB6 младшие 7 бит, получим 0x36, и это действительно метка @@FinalRange:

2E  80C2              @@NotSoBright:  Acc     [X+2j+1]    ;Y-координата ранее обнар. точки. Сейчас 
2F  83FE                          SUB     [SP+2j] ;текущий номер строки, чем меньше - тем НИЖЕ, идём от 719 (или от 1024) до нуля. При этом вычитании всегда получаем положительное значение
30  8FC0                          DIV2S       [X+1]       ;ну и размер точки, в кои-то веки уполовиненный
31  B84F                          JL      @@QueueAnyway   ;не так уж эта точка далеко, попробуем всё равно 
32  CD45                          X       AllPoints
33  F3B6                          CALL        ListOp
34  CDDD                          X       Y       ;теперь [X] ссылается уже не на обработанную и удалённую точку, а на следующую, так что всё верно
35  B069                          JMP     @@ActPointsStart    ;ура...                 
36  207C              @@FinalRange:   ACQ     WholeRow
37  2006                          ACQ     HSync
38  80F2                          Acc     [SP+2j+1]
39  8340                          SUB     1
3A  BC38                          JGE     @@newRow
        ProcessFrame endp


Но увы, я выставил ширину адресной шины кода (RomWidth) 8 бит. Сделал это из-за того, что ширина числа для относительных прыжков также должна была быть 7, а мой новый счётчик инструкций, ставший счётчиком, на такое не был рассчитан, верилог не любит, когда ему дают шины нулевой ширины, то бишь состоящие из нуля проводов - начинает материться как сапожник.

И всё у меня нормально работало, пока не реализовал особенно экономичный QuatCoreImmTable, который вовсю пользуется возможностью оставить произвольные значения в неиспользуемых битах...

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


Первые 8 строк кода исполнялись абсолютно корректно, на 9й строке прыгнули не туда. Надо дорабатывать счётчик инструкций, чтобы допускал RomWidth == RelAddrWidth. Как вариант, можно было бы попробовать отказаться от относительных прыжков, потому как здесь от них особого выигрыша не проглядывается...
Tags: ПЛИС, программки, работа, странные девайсы
Subscribe

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

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

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

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