nabbla (nabbla1) wrote,
nabbla
nabbla1

Categories:

Отладка обнаружения, день второй

(эта запись должна была увидеть свет в среду, но не склалось)

Конечно же, я надеялся, что как только я исправлю тот страшный баг - сразу же всё и заработает. Ага, ЩАЗЗЗ. Теперь "исчерпание заданий GPU" наступило ещё раньше:



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

Дамп памяти показывает: список "окончательно обнаруженных" пятен AllPoints пуст, а в списке ActivePoints, за исключением двух "фиктивных" пятен, присутствует ровно одно, с координатами (348; 197) и диаметром 3. Как-то так:


Злая мыша из прошлого года преследует меня!


По счастью, вовремя вспомнил ещё одну "проблему": я при анализе дампа памяти ввёл адреса списков AllPoints и ActivePoints, но теперь, когда в памяти перестала лежать переменная D1 (она превратилась в "непосредственное значение"), эти адреса сдвинулись на единичку, и столь неудачно:

ActivePoints:     0A0  0x00A2
AllPoints:        0A1  0x8000
APHeadDummyX:     0A2  0x8000
Heap:             0A3  0x00A5
APTailDummyX:     0A4  0x7FFF
Elem0Next:        0A5  0x00A9


что результат работы получался довольно разумный, пустой список AllPoints (на самом деле это был APHeadDummyX) и одно значение в списке ActivePoints.

Теперь, когда переправил адреса, получилось поинтересне. Вот содержание AllPoints:

(348; 197), радиус 3,
(352; 195), радиус 3


И целых 3 элемента лежит в ActivePoints:

(342; 199), радиус 3,
(347; 198), радиус 6,
(354; 197), радиус 3


Как говорится, есть две новости: хорошая и плохая.
Хорошая: все значения вполне адекватные, видно, что операции со списками выполняются правильно, и значения X,Y,D заносятся куда надо. Кроме того, в списке ActivePoints пятна отсортированы слева направо, так и должно быть, это сохраняющийся на всём протяжении ИНВАРИАНТ.

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

Для начала попытаюсь разобраться методом "пристального взгляда", в смысле пройти по шагам алгоритма "вручную", и понять, что там стряслось.

Вот интересующий нас кусок изображения:


Только вот, если я не ошибаюсь, у нас до сих пор Y-координата в алгоритме получается на единичку больше чем надо, грубо говоря нумерация начинается с единицы. Поэтому (352; 195) - это действительно первая обнаруженная точка! Видеопроцессор в линейке одинаковой яркости всегда возьмёт самую левую точку.

Тут же смотрим, что конкретно мы должны отправить на обработку. Тут важно понять, как именно произойдёт округление. В аккумуляторе разрядность высокая, грубо говоря есть "разряды после запятой", поэтому в нём 352 - 3/2 даст честно 350,5, но на шину данных уйдёт только 350. Таково будет наше первое задание на обработку, "до X=350". Включительно или нет - НЕ ПОМНЮ, сейчас как раз сообразим.
А второе задание получается прибавлением D1 к первому, то есть получится 353,5, и на шину данных пойдёт просто 353. Этот отрезок, от 350 до 353 - то, где мы ожидаем продолжения пятна. И наконец, последний отрезок будет до самого конца строки.

Пошла следующая строка изображения, Y=195 на рисунке, 196 в коде...
Давайте не будем гадать на кофейной гуще, а посмотрим лучше в код видеопроцессора, в какой момент он прекращает обработку отрезка.

Вот формируется сигнал start (один из вариантов):
wire start_normal = (~SyncOut[1])&(~SyncOut[0])&(BufOut[XregWidth-1:0] == X);

Да, здесь разумеется именно равенство, его гораздо проще реализовать, чем знак "больше".

Этот сигнал делает синхронный сброс нашим сумматорам, и он же защёлкивает ТЕКУЩЕЕ значение в выходной буфер видеопроцессора. Получается, что первый отрезок - это от [0; 349], а 350 в него уже не входит! Но при текущей реализации, пиксель 350 и в следующий отрезок не войдёт! К его окончанию у нас сумматоры только сбросятся, и лишь на следующем пикселе дадут хоть что-то осмысленное. Это можно будет подправить (вместо обнуления сделать занесение текущего пикселя). Но в целом, такое поведение даёт даже в чём-то более сбалансированные строки. Если бы 350 уже вошло в следующую строку, был бы заметный "перекос влево". Учтём это на будущее и продолжим наблюдения.

Получается, на первом отрезке, этом самом [0;349], мы вообще ничего не обнаруживаем.
Далее, на [351;352] мы обнаруживаем точку, аккурат на 351 (опять берётся самая левая). Мы берём текущий номер строки, 196, вычитаем половинку диаметра, получая 194,5 (аккумулятор у нас имеет дробные разряды), ещё вычитаем Y-координату центра пятна, 195, получаем -0,5. Прыжок JL срабатывает - и мы прыгаем в начало цикла по списку пятен, т.е ничего с этим отрезком делать не требуется. Да, мы так и задумывали. Кроме того, висит метка "за нами должок" по заданиям. Пока ещё ни одного не отправили!

Берём результаты по следующему отрезку, [354;1023]. Там обнаруживается точка аккурат по X=354. Начинается проверка на слияние.

Из 354 вычитаем 352, получаем 2. Вычитаем половинку диаметра, получаем 0,5. Вычитаем ещё половинку диаметра, получаем -1. Срабатывает JL @@LeftMerge - мы прыгаем туда.

Там мы берём X-координату пятна справа от себя, 32767 (это "правое фиктивное пятно"), вычитаем X-координату пятна справа от себя, 352, получая 32415. Затем вычитаем половинку диаметра правого пятна, это указатель Heap, он не может быть больше чем 511 (у нас сейчас 9-битная адресация оперативной памяти), так что будет не менее 32159. Вычитаем половинку диаметра левого пятна, 3, и получаем не менее 32157,5. Потом ещё вычитаем 3, получая 32154,5. Очевидно оно больше нуля, поэтому прыжок JL @@MergeBlobs не выполняется.

Вместо этого мы должны обновить параметры пятна, чтобы в него вошла эта новая точка. В аккумулятор заносится X-координата только что обнаруженной точки, 354. Вычитаем координату центра пятна, 352, получая 2. Прибавляем половинку диаметра, получая 3,5. В диаметр заносится то же значение, что было там и раньше, 3 это и мешает "расползанию" пятна.

Далее должна обновиться X-координата. В аккумулятор загружается текущее значение, 354. Из него вычитается половинка диаметра (уже внесённого в память, а потому округлённого до целого), получается 352,5. Оно обрезается до 352 - и сохраняется. Вот и вышло, что пятно совсем не сдвинулось с места!

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

"подправив" параметры пятна (а на деле оставив их теми же самыми), мы прыгаем в AcqNoCheck, где посылаются очередные задания на обработку. Получается всё то же самое: [0;349] и [351;352]. Оттуда "выпрыгиваем" в @@MidCycle, и там сразу же в @@FinalRange. Отправляем недостающие задания "до конца строки" и на "синхроимпульс" - и начинаем следующую строку.

Строка 196 на картинке, 197 "в коде" На первом отрезке, [0;349], обнаруживается точка X=348. Идёт сравнение с точкой "слева от себя": из 348 вычитается (-32768) - это координата "левой фиктивной точки", чтобы за неё никто "не зацепился", выходит 33116 (в аккумуляторе есть запас в один бит, но при запросе Acc происходит насыщение результата до 32767). Вычитаем D1/2=1,5, выходит 33114,5. Вычитаем половину диаметра "левого фиктивного пятна", это на самом деле указатель AllPoints, по-любому не превысит 512, поэтому выйдет не менее 32858,5. Переход JL @@LeftMerge очевидно не сработает, это правильно.

Затем проверим близость к пятну справа от себя. Загружаем в аккумулятор координату её центра, 352. Вычитаем текущую координату, 348, получаем 4. Вычитаем две половинки диаметров, получаем 1. JL @@RightMerge также не срабатывает - и мы получаем НОВОЕ ПЯТНО, с координатами (348;197) и радиусом 3. Да, пока всё соответствует результатам дампа памяти.

Сразу же высылаем задания для обработки, отрезки [0;345] и [347;348], и переходим к отрезку [351;352].

На нём мы находим точку, X=351 (очень неожиданно :)) и начинаем проверять Y-координаты. Загружаем в аккумулятор номер текущей строки, 197. Вычитаем половинку диаметра, получаем 195,5. Вычитаем координату центра пятна, 195, получаем 0,5. Переход JL @@ActPointsStart не срабатывает. Далее вычитаем D1=3, получая -2,5. Переход "JL @@RemoveBlob" срабатывает, А ЗРЯ. Мы тут явно перепутали JL и JGE. Отрицательное значение как раз должно было показать: мы в непосредственной близости от пятна, и тут нужно его расширять, а не удалять! Ошибок уже целый воз, но всё-таки проследим дальше, возникновение прерывания до сих пор не объяснено!

Регистр Y "заблаговременно" указывал на только что добавленное пятно (348;197), и мы успешно "перецепили" идущее за ним "старое" пятно (352;195) в список AllPoints. По окончании перецепки мы присвоили X = Y, т.е мы снова сидим на пятне (348;197), и прыгаем по @@ResetPending, это на одну строчку выше нашего цикла по всем пятнам из списка, там присваивается C=0. Этим мы говорим, что никакого "долга" по передаче заданий у нас нет.

И теперь мы принимаемся за отрезок [354;1023], причём слева от нас сидит пятно (348;197), поскольку от самого первого мы уже избавились. Там мы находим точку X=354, она явно лежит далеко от X=348, и ещё дальше от "правой фиктивной", так что она добавляется в список, и сразу отсылаются задания на обработку [350;351] и [353;354].

Этот отрезок был последним, так что переходим на @@FinalRange и там отправляем ещё 2 задания, [356;1023] и HSync.
К следующей строке у нас уже набирается 6 заданий: [0;345],[347;348],[350;351], [353;354], [356;1023] и HSync. Во входном буфере GPU пока что объявлено 8 элементов, так что пока вроде всё нормально. Ну, не считая всех выявленных ошибок.
В это же самое время, в списке ActivePoints у нас 2 точки: (348;197) и (354;197).

Строка 197 на картинке, 198 "в коде". На первом отрезке, [0;345], мы находим точку X=345. Она явно СИЛЬНО правее "левой фиктивной точки". Проверим слияние с (348;197): в аккумулятор загружается 348, вычитается 345 (выходит 3), и ещё дважды вычитается 1,5, что даёт ровно нолик. JL @@RightMerge не срабатывает, поэтому добавляется ЕЩЁ ОДНА ТОЧКА, (345;198). Что интересно, её в финальных списках не видно, неужели всё-таки смогла куда-то сдвинуться? Любопытно... Сразу же высылаются задания на обработку, [0;342] и [344;345].

Далее идёт отрезок [347;348]. В нём мы находим X=347, проверяем Y-координату: начинаем со 198, вычитаем 1,5, получается 196,5, вычитаем 197, получается -0,5, поэтому срабатывает переход JL @@ActPointsStart, точка (348;197) остаётся на том же месте.

Теперь идёт отрезок [350;351], на котором мы находим X=350. Сравниваем с точкой левее себя: загружаем в акк. 350, вычитаем 348, получая 2. Вычитаем дважды половинку диаметра и получаем -1, срабатывает переход JL @@LeftMerge.

Там мы определяем, не пора ли объединить два пятна. Для этого в аккумулятор загружаем X-координату центра правого пятна, 354. Вычитаем X-координату левого, 348, получается 6. Вычитаем дважды по половинке диаметра, получаем 3. И наконец, вычитаем D1, получая 0. Но переход JL @@MergeBlobs не срабатывает, значит мы должны расширить пятно слева от себя...

Загружаем текущую координату, 350. Вычитаем центр левого пятна, 348, получая 2. Прибавляем половинку диаметра, 1,5, и получаем 3,5, которые при занесении в память "отрежется" до 3, то есть опять не склалось, диаметр остался неизменным! Далее, загружаем 350, вычитаем половинку диаметра, это даёт 348,5, которое отрезается до 348 - координата центра тоже никуда не уехала... И это пока что согласуется с финальным списком, там стоит именно точка (348;197).

Отправляем задание на обработку, до точки 346. Только вот незадача, в прошлый раз задание тоже шло до 346, и это очень грустно! Поскольку видеопроцессор проверяет строго равенство, ему ничего не останется, как прождать до СЛЕДУЮЩЕЙ СТРОКИ, где снова появится 346! Начинает проясняться, что у нас за "сбой" вышел. Всё логично...

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

Теперь идёт отрезок [353;354], "под" пятном (354;197). В нём обнаруживаем точку X=353. Начинаем сравнивать Y-координаты: загружаем в акк. текущий номер строки 198, вычитаем 1,5 и коорд. центра пятна 197, получаем -0,5 - и не трогаем пока это пятно, оно остаётся в ActivePoints. Метка "за нами должок" включена, но, как ни странно, ещё ни разу не была применена!

И, наконец, отрезок [356;1023]. Тут мы находим точку X=356. Проверяем на слияние: 356-354-D/2-D1/2 = -1, то есть прыгаем в @@LeftMerge. Там убеждаемся, что объединять пятно с "правым фиктивным" нам не хочется, поэтому в очередной раз уточняем координаты, и опять бесполезно: 356+D1/2-354 даст после отсечения дробной части всё ту же двойку, и X-координата останется на месте. Выдадим такие же задания на обработку, как и в прошлый раз, и дело с концом. И, наконец, перейдём на @@FinalRange, где добавим задания до конца строки и HSync.

Итого, по завершении строки 198, у нас одно пятно в AllPoints: (352;195), три пятна в ActivePoints: (345;198), (348;197), (354;197), и выданы задания на обработку: [0;342], [344;345], и ещё один ошибочный 345], который сгрызёт нам строку, а за ним ещё [347;348], [350;351], [353;354], [356;1023] и HSync. Их ровно 8, так что последний HSync отправим аккурат когда отработает HSync в начале новой строки, и потом мы будем честно ждать поступления первого результата по этой строке. То есть, по буферам у нас пока всё укладывается...

И теперь самое интересное, строка 198, которая "в коде" значится под номером 199. Первым поступает отрезок [0;342]. В нём мы находим X=342. Ближайшее пятно справа: 345. Вычитаем одно из другого, выходит 3, вычитаем дважды половинки диаметров, выходит 0. Этого недостаточно, чтобы перейти на @@RightMerge, поэтому добавляем новую точку, (342;199). И даём задания на обработку, уже пофиг, какие :)

Далее, обрабатывается отрезок [344;345]. Там проверяем Y-координаты, всё хорошо, пятно (345;198) ещё совсем близко, делаем пометку "за нами должок" - и двигаем дальше.

Затем идёт ещё один отрезок до 345, который должен был быть "между пятнами (345;198) и (348;197)". Вот тут начинается веселье: работа по нему начинается с X=347 (там, где закончился прошлый отрезок), и уже в этот момент найдена точка с максимальной яркостью в 255, поэтому именно такая координата, 347, и остаётся в регистре! Тем временем, мы застреваем на целую строку: она успевает дойти до конца, пройти строчный синхроимпульс, очищающий очередь результатов GPU, но она и так пустая (мы всё оттуда сняли и ожидали следующего результата, который "почему-то" затянулся). И вот, наконец, оно доходит до 345 - и мы получаем результат, X=347 (!).

При сравнении с пятном слева от себя, 345, мы прыгаем в @@LeftMerge. А там в кои-то веки находим разность между правым и левым пятном, 348-345 = 3, вычитаем половинку диаметра левого пятна и половинку диаметра правого, получая 0. Потом ещё вычитаем D1=3, и наконец-то решаем ПРОИЗВЕСТИ СЛИЯНИЕ.

Там мы складываем диаметры и получаем 6, и находим среднее арифметическое от 345 и 348, с округлением "до ближайшего целого", то есть с прибавлением 0,5 по ходу дела. Получается 347 - именно такой становится X-координата центра "нового" пятна.

В итоге, вместо пятен (345;198) и (348;197), получаем одно, (347;198) и диаметром 6. Итого, список ActivePoints пришёл ровно к тому состоянию, которое мы увидели в дампе памяти. А вот в AllPoints не хватает элемента (348;197). Странно, откуда он теперь сможет появиться?


Давайте-ка ещё одну вещь посмотрим: как поживает наш Heap? Все его элементы изначально были инициализированы нулями (не считая связей между собой), и было их ровно 32 штуки. Сейчас 2 отданы в AllPoints и 3 в ActivePoints, так что должно остаться 27. И глянем, "в каком они состоянии".

Действительно, осталось 27 штук, то есть утечек памяти у нас нет! Но самый "свежий" элемент содержит в себе некий мусор: D=-602, X=301, Y=0. Что это такое - пока не соображу.

Но вернёмся к нашим баранам. После того, как два пятна были слиты в одно, мы перешли в @@EndOfCycle, но ЗНАЧЕНИЯ РЕГИСТРОВ НЕПРАВИЛЬНЫЕ! X в этом месте указывает на Heap, Y указывает на текущее пятно (уширенное), Z на уже удалённое.

Там мы получаем очередные результаты, по отрезку [347;348]. У меня нет уверенности, что здесь GPU выдаст правильный результат, поскольку обычно мы проходим строчный синхроимпульс, посылая "ACQ HSync", где HSync = 0x4106, где четвёрка - это флажки, соответствующие "ловле строчного синхроимпульса", а вот 0x106 = 262 - это количество пикселей между строчным импульсом и началом полезной области строки. По приходу импульса выставляется регистр FrontPorch=1 (возможно, название неправильное, я по-прежнему путаю front porch и back porch), но только если мы действительно ждали синхроимпульса. Так вот, следующее задание при включённом FrontPorch сбрасывает регистр X, поэтому дальше всё отсчитывается относительно начала "видимой" (полезной) строки, а не от начала синхроимпульса. Но в нашем случае мы не ждали строчного синхроимпульса, но он "припёрлися", и эти 262 пикселя никак не отсчитывались, так что сейчас мы ПРОМАХИВАЕМСЯ МИМО ПЯТНА!

Сначала, как водится, проверяем Y-координату. Вот только регистр X смотрит совсем не туда, вот что он воспринимает за пятно:

Heap:             0A3  0x00A5  - ссылка на следующее пятно (правее себя)
APTailDummyX:     0A4  0x7FFF  - диаметр пятна (32767)
Elem0Next:        0A5  0x8000  - X-координата (-32768)
Elem0D:           0A6  0x0003  - Y-координата (3)


В итоге, мы берём текущую строку изображения (199), вычитаем "Y-координату центра пятна" (3), получая 196. Вычитаем половинку диаметра, а это, простите, 16383,5, и получается заведомо отрицательное значение, так что мы выпрыгиваем в @@ActPointsStart.

Там мы прочитываем ещё один отрезок, [350;351], и в этот раз НИЧЕГО НЕ НАХОДИМ (поскольку смещены на 262 пикселя). Так что в кои-то веки мы должны угодить в TaskPending, где обнаружить: мы должны передать задание по предыдущей точки, и выпрыгнуть в @@MidCycle.

В @@MidCycle мы "продвигаемся вперёд по списку активных точек", только на самом деле мы двигаемся по Heap! И этот список ОЧЕНЬ ДЛИННЫЙ, 27 элементов, так что здесь мы застряли надолго :)

Но первым элементом, совершенно ВНЕЗАПНО, оказывается удалённое нами пятно (348;197) !!! И теперь мы прочитываем из GPU результат очередного задания, [353;354], и снова там ничего нет. В этот раз проверка Y-координаты проходит "ожидаемо" - из текущей координаты, 199, вычитаем 197, получая 2. Вычитаем половинку диаметра, 1,5, и получаем 0,5, поэтому закончить с этим отрезком не спешим.

А вот продлить его вниз из-за уже обнаруженной ошибки (JL вместо JGE) мы тоже не можем, вместо этого переносим эту точку в список AllPoints. Забавно, какими кружными путями она шла, чтобы очутиться в конце концов в этом списке!

Списки AllPoints и ActivePoints, которые мы увидели в дампе памяти, уже объяснены. Осталось совсем немного - "увидеть", как список заданий оказался исчерпан (что и вызвало прерывание) и что за мусор оказался в элементе Heap, пятно (301;0) с диаметром -602

После переноса пятна в AllPoints, мы вернулись в начало цикла по всем пятнам на строке, попутно сбросив флажок "TaskPending" (он лежит в регистре C, если там -32768, значит он поставлен, иначе сброшен).

У нас снова X=Heap, и воспринимает свои окрестности как странное "пятно" (-32768;3) с диаметром 32767. А "справа от нас" лежит пятно (0;0) с диаметром 0, тоже неплохо :)

В этот раз мы получаем результаты работы по заданию [356;1023], что на самом деле соответствует отрезку примерно [94;761], в который входит всё наше пятно. Как водится, найдена будет крайняя левая точка, координата которой должна была быть примерно 342, только здесь она отобразится как 604.

Сравнение с левым пятном не даст слияния (слишком уж она далеко, аж в 32768 пикселя влево, и даже столь же гигантский диаметр не поможет, т.к берём лишь половину от него), а вот с правым пятном слияние определённо произойдёт: мы возьмём X-координату этого пятна, 0, вычтем из него нашу, 604, получим -604, потом ещё вычтем 1,5, и ещё половинку диаметра этого пятна (0), получив -605,5. Ответ очевидно меньше нуля - и мы перейдём в @@RightMerge (ВПЕРВЫЕ ЗА ВСЁ ЭТО ВРЕМЯ).

Там снова прибавим половинку диаметров, получая -604 - это и запихнём как "обновлённый" диаметр пятна. А затем поделим пополам, прибавим текущую X-координату - и запишем как "обновлённую" X-координату, 302.

Очень похоже на правду, только было не 604, а 602, что логично - пятно ещё на 2 пикселя расширилось к этой строке.

После этого мы пытаемся получить очередной отрезок с GPU, но там на очереди задание HSync, так что мы сначала дожидаемся синхроимпульса, а потом начинаем долго и упорно ждать, когда же он доползёт до первого задания. Зря мы не посмотрели, что же мы там отправляли. Придётся посмотреть: у нас новая точка добавлялась, (342;199). Значит задания одно [0;339] и второе [341;342]. А уже за ними идёт что-то более упоротое, поскольку мы задания передавали, когда X=Heap, т.е по совершенно упоротому "пятну" (-32768;3) с диаметром 32767.

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

Думаю, на пока хватит.


В общем, ошибок выше крыши:
- неправильно обновляются параметры пятен, из-за чего они не могут расти и двигаться в сторону "поглощаемых точек",
- тупо перепутано условие для переноса пятна из списка ActivePoints в AllPoints, вместо JGE стояло JL,
- после слияния двух пятен остаются неверные значения регистров, из-за чего мы из списка ActivePoints "перескакиваем" в список Heap, где нас и ждёт погибель...

Но и радостного много:
- утечек памяти нет
- покрытие кода ProcessFrame.asm уже составило 91%, буквально один "закуток" (расширение пятна "вниз") мы ещё не посмотрели. Так что шибко много ошибок остаться не должно.
- процессор работает правильно - строго по программе. И наши с ним представления "что значит работать правильно" - полностью совпадают :)

Сейчас исправим ошибки, снова всё откомпилим, отсинтезируем и прошьём - и попробуем ещё разок!
Tags: ПЛИС, программки, работа, странные девайсы
Subscribe

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

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

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

    Вчера я чуть поторопился отсинтезировать проект,параметры не поменял: RomWidth = 8 вместо 7, RamWidth = 9 вместо 8, и ещё EnableByteAccess=1, чтобы…

  • Балансируем конвейер QuatCore

    В пятницу у нас всё замечательно сработало на симуляции, первые 16 миллисекунд полёт нормальный. А вот прошить весь проект на ПЛИС и попробовать "в…

  • Ковыряемся с сантехникой

    Наконец-то закрыл сколько-нибудь пристойно трубы, подводящие к смесителю, в квартире в Москве: А в воскресенье побывал на даче, там очередная…

  • Мартовское велосипедное

    Продолжаю кататься на работу и с работы на велосипеде, а также в РКК Энергию и на дачу. Хотя на две недели случился перерыв, очередная поломка,…

  • Обнаружение на новом GPU - первые 16 мс

    Закончилась симуляция. UFLO и OFLO ни разу не возникли, что не может не радовать. За это время мы дошли до строки 0x10F = 271. Поглядим дамп памяти:…

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 0 comments