nabbla (nabbla1) wrote,
nabbla
nabbla1

Categories:

Связанные списки в QuatCore

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

Начал было его записывать на ассемблере - разъярился, как приходится долго и муторно заносить в регистры большие константы, выходящие за диапазон -64..+63. Поковырял процессор и компилятор к нему - теперь можно любые константы использовать - и то хлеб.

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

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

Даже не так: у нас по сути два списка, в одном хранятся "активные точки", то есть такие, которые ещё могут появиться на следующей строке, а по мере сканирования они должны перемещаться в "окончательный список найденных точек", и здесь работа со связанными списками тоже очень кстати: не нужно перетаскивать всю запись длиной в 4 слова (8 байт), достаточно указатели переставить!

Именно реализация в виде связанных списков позволяет осуществить вставку, удаление, "перецепку" за O(1) операций, что при нашей работе "в реальном времени" очень важно. И cache miss нам не страшен, потому что у нас НЕТ КЭША! Точнее говоря, мы умудряемся пока ВСЮ НАШУ ПРОГРАММУ УМЕСТИТЬ В L1-КЭШЕ, БЕЗ НУЖДЫ ВО ВНЕШНЕЙ ПАМЯТИ!

Есть только одна мааленькая проблема: у нас нет alloc/free или new/delete, вообще нет никакого "менеджера памяти" или рантайм-библиотеки, есть только "голое железо". Значит, продолжим изобретать велосипед, сделаем свой собственный Heap allocator, простой до безобразия...


Наверное, Heap allocator - слишком громкое имя для данной хреновины. Здесь нет нужды выделять блоки памяти произвольного размера, мне сейчас нужны исключительно блоки по 5 слов (10 байт):
- Next (1 слово) - указатель на следующий элемент (или отрицательное значение, если этот элемент последний),
- X, Y (по 1 слову) - координаты яркой точки на фотоприёмной матрице,
- Lum (Luminance, 1 слово) - яркость этой точки,
- P (Path, 1 слово) - некое число, характеризующее размер точки. Точнее, это длина "пути", который мы прошли от первого обнаружения этой точки до её центра. Так мы сможем селектировать точки по размеру - и откровенные блики выкинем, и можем даже по размеру точек прикинуть, на каком примерно расстоянии мы находимся.

Сколько именно таких точек нам понадобится - точно сказать пока не могу, но могу дать оценку снизу. Если нас вдруг включат на дальности порядка 15 метров, то мы увидим наиболее "кишащую точками" картинку:


Тут "разрешатся" отдельные уголковые отражатели, и точек получится 23. Могут ещё и блики какие затесаться, так что желательно, чтобы точек было ещё больше, для ровного счёта 32 штуки, а там глянем, сколько нам памяти "не жалко".

Всё, что надо сделать - это инициализировать соответствующие области памяти так, чтобы там уже образовался связанный список по имени Heap или, как у Кнута: Avail (от слова Available - "доступные ячейки"). Не будем заниматься "производством средств производства", а сделаем это почти что "ручками" в сегменте данных:

	;область для списков точек, для начала она вся объединена в список Heap
	Heap		dw	Elem0
	Elem0:
	Elem0Next	dw	Elem1
	Elem0X		dw	?
	Elem0Y		dw	?
	Elem0L		dw	?
	Elem0P		dw	?
	Elem1		dw	Elem2,?,?,?,?
	Elem2		dw	Elem3,?,?,?,?
	Elem3		dw	Elem4,?,?,?,?
	Elem4		dw	Elem5,?,?,?,?
	Elem5		dw	Elem6,?,?,?,?
	Elem6		dw	Elem7,?,?,?,?
	Elem7		dw	Elem8,?,?,?,?
	Elem8		dw	Elem9,?,?,?,?
	Elem9		dw	ElemA,?,?,?,?
	ElemA		dw	ElemB,?,?,?,?
	ElemB		dw	ElemC,?,?,?,?
	ElemC		dw	ElemD,?,?,?,?
	ElemD		dw	ElemE,?,?,?,?
	ElemE		dw	ElemF,?,?,?,?
	ElemF		dw	Elem10,?,?,?,?
	Elem10		dw	Elem11,?,?,?,?
	Elem11		dw	Elem12,?,?,?,?
	Elem12		dw	Elem13,?,?,?,?
	Elem13		dw	Elem14,?,?,?,?
	Elem14		dw	Elem15,?,?,?,?
	Elem15		dw	Elem16,?,?,?,?
	Elem16		dw	Elem17,?,?,?,?
	Elem17		dw	Elem18,?,?,?,?
	Elem18		dw	Elem19,?,?,?,?
	Elem19		dw	Elem1A,?,?,?,?
	Elem1A		dw	Elem1B,?,?,?,?
	Elem1B		dw	Elem1C,?,?,?,?
	Elem1C		dw	Elem1D,?,?,?,?
	Elem1D		dw	Elem1E,?,?,?,?
	Elem1E		dw	Elem1F,?,?,?,?
	Elem1F		dw	-32768,?,?,?,?


Снова проявляется специфика ПЛИС: на файле конфигурации экономить нет никакого смысла, он заведомо влезет в конфигурационную ПЗУ!. Одно дело программы для ПК, где желательно побольше памяти оставить неинициализированной или заполненной нулями, поскольку все прочие данные так или иначе надо хранить в .exe-файле, и подобные штуки никто в здравом уме делать не будет, лучше инициализировать область уже "на лету". А тут хочешь-не хочешь, место для инициализации всех блоков памяти уже выделено, так почему бы и не сделать такое вот "форматирование"?!

И заводим ещё два указателя, ActivePoints (список точек, которые мы ожидаем увидеть на очередной строке) и AllPoints ("окончательно обнаруженные" точки):

	ActivePoints	dw	-32768
	AllPoints	dw	-32768


Возможно, стоит ещё и константу ввести, Null, а может быть Nil (ты слышал как паскали называют наш нулл? Нил! Поубывал бы!):
	Nil		EQU	-32768
	ActivePoints	dw	Nil
	AllPoints	dw	Nil


Почти всегда он равнялся нулю, но у нас здесь - любому отрицательному числу. Какбы 65536 слов (128 кбайт) памяти нам всё равно не надо, 64 кбайт хватит на всех (вообще, я надеюсь в 1 кбайт уместиться), а поскольку у нас до сих пор нет флага нуля, только флаг знака, так оно сподручнее.

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



Можно было бы связать данные "задом наперёд":

Elem1F  dw Nil,?,?,?,?
Elem1E  dw Elem1F,?,?,?,?
Elem1D  dw Elem1E,?,?,?,?
...

но тогда и указатель Heap отправится далеко вперёд, а нам всё-таки хочется, чтобы его адрес был предельно коротким, ну и вообще "на ровном месте" изворачиваться только из-за туповатого компилятора - это не наш путь!

Чуть-чуть доработав его, мы можем наконец-то посмотреть листинг оперативной памяти ("сегмента данных"):


Не, пока не можем. Забыли новые команды добавить, ACQ (Acquire - запустить видеопроцессор в "режиме захвата"), TRK (Track - запустить видеопроцессор в "режиме сопровождения") и GPU (Получить данные с видеопроцессора). Пока что весь диапазон 00..1F (т.е 000x_xxxx) занимала команда OUT, а диапазон 20..3F (т.е 001x_xxxx): команда SIO (Select I/O). Чуть подвинем их:

00..0F (т.е 0000_xxxx) теперь будет занимать OUT,
10..1F (т.е 0001_xxxx): SIO,
20..2F (т.е 0010_xxxx): ACQ,
30..3F (т.е 0011_xxxx): TRK.

В общем, строки в файле конфигурации
  object TQuatCoreCommand
    Key = 'OUT'
    Code = 0
    Mask = 224
    DataMask = 1023
    Description = 'Sends value to chosen output'
    Place = [cpDest]
    Resources = []
    DataType = dtNumeric
  end
  object TQuatCoreCommand
    Key = 'SIO'
    Code = 32
    Mask = 224
    DataMask = 15
    Description = 'Selects I/O device'
    Place = [cpDest]
    Resources = []
    DataType = dtNumeric
  end


заменяем на

  object TQuatCoreCommand
    Key = 'OUT'
    Code = 0
    Mask = 240
    DataMask = 1023
    Description = 'Sends value to chosen output'
    Place = [cpDest]
    Resources = []
    DataType = dtNumeric
  end
  object TQuatCoreCommand
    Key = 'SIO'
    Code = 16
    Mask = 240
    DataMask = 15
    Description = 'Selects I/O device'
    Place = [cpDest]
    Resources = []
    DataType = dtNumeric
  end
  object TQuatCoreCommand
    Key = 'ACQ'
    Code = 32
    Mask = 240
    DataMask = 50175
    Description = 'ACQuire mode of GPU (find most bright point and its X-coord on a row)'
    Place = [cpDest]
    Resources = []
    DataType = dtNumeric
  end
  object TQuatCoreCommand
    Key = 'TRK'
    Code = 48
    Mask = 240
    DataMask = 50175
    Description = 'TRacKing mode of GPU (find sum of pixels and weighted sum of pixels, for sub-pixel evaluation)'
    Place = [cpDest]
    Resources = []
    DataType = dtNumeric
  end


Ну теперь-то заработает? Нет:


Верно, про чтение данных из видеопроцессора забыли. Пора АЛУ немножко "пограбить": на его выходы Acc (аккумулятор "с насыщением"), UAC (Unsigned Acc, аккумулятор "как есть") и C (регистр C) приходится аж 16 адресов, 80..8F (1000_xxxx). Раньше и вовсе было 32, но потом 16 штук "откусили" и передали на IN (чтение из устройств ввода-вывода, как-то UART и SPI) и чтение из статической памяти. Давайте что ль ещё 8 "откусим" на видеопроцессор... И опять чуть правим конфиг, заменяя эти строки:

  object TQuatCoreCommand
    Key = 'Acc'
    Code = 128
    Mask = 242
    Description = 'Value of accumulator, saturated to 16 bits'
    Place = [cpSrc]
    Resources = [crAcc]
    DataType = dtNumeric
  end
  object TQuatCoreCommand
    Key = 'UAC'
    Code = 130
    Mask = 243
    Description = 'Unsigned ACcumulator. Raw value, so to say.'
    Place = [cpSrc]
    Resources = [crAcc]
    DataType = dtNumeric
  end
  object TQuatCoreCommand
    Key = 'C'
    Code = 131
    Mask = 243
    Description = 'Value of "C" register'
    Place = [cpSrc]
    Resources = [crC]
    DataType = dtNumeric
  end


на эти:

  object TQuatCoreCommand
    Key = 'Acc'
    Code = 128
    Mask = 250
    Description = 'Value of accumulator, saturated to 16 bits'
    Place = [cpSrc]
    Resources = [crAcc]
    DataType = dtNumeric
  end
  object TQuatCoreCommand
    Key = 'UAC'
    Code = 130
    Mask = 251
    Description = 'Unsigned ACcumulator. Raw value, so to say.'
    Place = [cpSrc]
    Resources = [crAcc]
    DataType = dtNumeric
  end
  object TQuatCoreCommand
    Key = 'C'
    Code = 131
    Mask = 251
    Description = 'Value of "C" register'
    Place = [cpSrc]
    Resources = [crC]
    DataType = dtNumeric
  end
  object TQuatCoreCommand
    Key = 'GPU'
    Code = 136
    Mask = 248
    Description = 'Read data from Graphic Processor (which reads image from sensor)'
    Place = [cpSrc]
    Resources = []
    DataType = dtNumeric
  end


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

SrcAddr


Адрес +0 +1 +2 +3 +4 +5 +6 +7
00 IMM0 IMM1 IMM2 IMM3 IMM4 IMM5 IMM6 IMM7
08 IMM8 IMM9 IMM10 IMM11 IMM12 IMM13 IMM14 IMM15
10 IMM16 IMM17 IMM18 IMM19 IMM20 IMM21 IMM22 IMM23
18 IMM24 IMM25 IMM26 IMM27 IMM28 IMM29 IMM30 IMM31
20 IMM32 IMM33 IMM34 IMM35 IMM36 IMM37 IMM38 IMM39
28 IMM40 IMM41 IMM42 IMM43 IMM44 IMM45 IMM46 IMM47
30 IMM48 IMM49 IMM50 IMM51 IMM52 IMM53 IMM54 IMM55
38 IMM56 IMM57 IMM58 IMM59 IMM60 IMM61 IMM62 IMM63
40 IMM-64 IMM-63 IMM-62 IMM-61 IMM-60 IMM-59 IMM-58 IMM-57
48 IMM-56 IMM-55 IMM-54 IMM-53 IMM-52 IMM-51 IMM-50 IMM-49
50 IMM-48 IMM-47 IMM-46 IMM-45 IMM-44 IMM-43 IMM-42 IMM-41
58 IMM-40 IMM-39 IMM-38 IMM-37 IMM-36 IMM-35 IMM-34 IMM-33
60 IMM-32 IMM-31 IMM-30 IMM-29 IMM-28 IMM-27 IMM-26 IMM-25
68 IMM-24 IMM-23 IMM-22 IMM-21 IMM-20 IMM-19 IMM-18 IMM-17
70 IMM-16 IMM-15 IMM-14 IMM-13 IMM-12 IMM-11 IMM-10 IMM-9
78 IMM-8 IMM-7 IMM-6 IMM-5 IMM-4 IMM-3 IMM-2 IMM-1
80 Acc Acc UAC C Acc Acc UAC C
88 GPU GPU GPU GPU GPU GPU GPU GPU
90 IN IN IN IN IN IN IN IN
98 [ER++] [ER++] [ER++] [ER++] [ER++] [ER++] [ER++] [ER++]
A0 i j k Inv ijk ijk ijk ijk
A8 i j k Inv ijk ijk ijk ijk
B0 CALL0 CALL1 CALL2 CALL3 CALL4 CALL5 CALL6 CALL7
B8 CALL8 CALL9 CALLA CALLB CALLC CALLD CALLE CALLF
C0 [X+1] [X+2i+1] [X+2j+1] [X+4j+1] [X+i] [X+3i] [X+2j+i] [X+4j+i]
C8 [X+k] [X+2i+k] [X+2j+k] [X+4j+k] [X+i^j] X [X+2j+i^j] [X+4j+i^j]
D0 [Y+1] [Y+2i+1] [Y+2j+1] [Y+Treug[j]+1] [Y+i] [Y+3i] [Y+2j+i] [Y+Treug[j]+i]
D8 [Y+k] [Y+2i+k] [Y+2j+k] [Y+Treug[j]+k] [Y+i^j] Y [Y+2j+i^j] [Y+Treug[j]+i^j]
E0 [Z+1] [Z+2i+1] [Z+2j+1] [Z+4j+1] [Z+i] [Z+3i] [Z+2j+i] [Z+4j+i]
E8 [Z+k] [Z+2i+k] [Z+2j+k] [Z+4j+k] [Z+i^j] Z [Z+2j+i^j] [Z+4j+i^j]
F0 [SP+1] [SP+2i+1] [SP+2j+1] [SP++] [SP+i] [SP+3i] [SP+2j+i] [i-1+SP++]
F8 [SP+k] [SP+2i+k] [SP+2j+k] [--SP+k] [SP] SP [SP+2j] [--SP]

DestAddr


Адрес +0 +1 +2 +3 +4 +5 +6 +7
00 OUT OUT OUT OUT OUT OUT OUT OUT
08 OUT OUT OUT OUT OUT OUT OUT OUT
10 SIO SIO SIO SIO SIO SIO SIO SIO
18 SIO SIO SIO SIO SIO SIO SIO SIO
20 ACQ ACQ ACQ ACQ ACQ ACQ ACQ ACQ
28 ACQ ACQ ACQ ACQ ACQ ACQ ACQ ACQ
30 TRK TRK TRK TRK TRK TRK TRK TRK
38 TRK TRK TRK TRK TRK TRK TRK TRK
40 ERL ERL ERL ERL ERL ERL ERL ERL
48 ERL ERL ERL ERL ERL ERL ERL ERL
50 ERH ERH ERH ERH ERH ERH ERH ERH
58 ERH ERH ERH ERH ERH ERH ERH ERH
60 [ER++] [ER++] [ER++] [ER++] [ER++] [ER++] [ER++] [ER++]
68 [ER++] [ER++] [ER++] [ER++] [ER++] [ER++] [ER++] [ER++]
70 [ER++] [ER++] [ER++] [ER++] [ER++] [ER++] [ER++] [ER++]
78 [ER++] [ER++] [ER++] [ER++] [ER++] [ER++] [ER++] [ER++]
80 Acc PM ADD SUB ABS ABSPM ABSA ABSS
88 ZACC NOP C C DIV2 CDIV2PM DIV2A DIV2S
90 MUL FMPM FMA FMS MULSU SUFMPM SUFMA SUFMS
98 MULU UFMPM UFMA UFMS SQRD2 SQRPMD2 SQRAD2 SQRSD2
A0 i j k Inv i++ j++ k++ ijk
A8 iLOOP jLOOP kLOOP Jik iLoopUp jLoopUp kLoopUp JNik
B0 JMP JMP JMP JMP JMP JMP JMP JMP
B8 JL JL JO JO JGE JGE JNO JNO
C0 [X+1] [X+2i+1] [X+2j+1] [X+4j+1] [X+i] [X+3i] [X+2j+i] [X+4j+i]
C8 [X+k] [X+2i+k] [X+2j+k] [X+4j+k] [X+i^j] X [X+2j+i^j] [X+4j+i^j]
D0 [Y+1] [Y+2i+1] [Y+2j+1] [Y+Treug[j]+1] [Y+i] [Y+3i] [Y+2j+i] [Y+Treug[j]+i]
D8 [Y+k] [Y+2i+k] [Y+2j+k] [Y+Treug[j]+k] [Y+i^j] Y [Y+2j+i^j] [Y+Treug[j]+i^j]
E0 [Z+1] [Z+2i+1] [Z+2j+1] [Z+4j+1] [Z+i] [Z+3i] [Z+2j+i] [Z+4j+i]
E8 [Z+k] [Z+2i+k] [Z+2j+k] [Z+4j+k] [Z+i^j] Z [Z+2j+i^j] [Z+4j+i^j]
F0 [SP+1] [SP+2i+1] [SP+2j+1] [SP++] [SP+i] [SP+3i] [SP+2j+i] [i-1+SP++]
F8 [SP+k] [SP+2i+k] [SP+2j+k] [--SP+k] [SP] SP [SP+2j] [--SP]


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

И наконец-то посмотрим листинг памяти:
EthDisable:      00    2
EthDisable[1]:   01    3
EthDisable[2]:   02    34
EthDisable[3]:   03    84
EthDisable[4]:   04    0
EthDisable[5]:   05    1
EthDisable[6]:   06    3
EthDisable[7]:   07    34
EthDisable[8]:   08    102
EthDisable[9]:   09    0
EthDisable[10]:  0A   24
EthDisable[11]:  0B   2
EthDisable[12]:  0C   34
EthDisable[13]:  0D   111
EthDisable[14]:  0E   2
R1:              0F   3
ActivePoints:    10   32768
AllPoints:       11   32768
Heap:            12   19
Elem0Next:       13   24
Elem0X:          14   ????
Elem0Y:          15   ????
Elem0L:          16   ????
Elem0P:          17   ????
Elem1:           18   29


Ну, почти... В своей вселенской мудрости, я адреса ячеек ввёл в hex, а вот значения - в десятичном виде. Вообще, тут есть, где поиграться: у меня есть директивы dw (Define Word) и Int16, и пока что первая означала, что данные ожидаются беззнаковыми, вторая - что "со знаком". Оно никак не влияет на результат, "зашиваемый" в ПЛИС, но позволяло более корректно представить память в этом самом листинге, и ещё на эмуляторе.

Давайте, что ли, dw будет отображать значения в hex:

EthDisable:      00    0x0002
EthDisable[1]:   01    0x0003
EthDisable[2]:   02    0x0022
EthDisable[3]:   03    0x0054
EthDisable[4]:   04    0x0000
EthDisable[5]:   05    0x0001
EthDisable[6]:   06    0x0003
EthDisable[7]:   07    0x0022
EthDisable[8]:   08    0x0066
EthDisable[9]:   09    0x0000
EthDisable[10]:  0A   0x0018
EthDisable[11]:  0B   0x0002
EthDisable[12]:  0C   0x0022
EthDisable[13]:  0D   0x006F
EthDisable[14]:  0E   0x0002
R1:              0F   0x0003
ActivePoints:    10   0x8000
AllPoints:       11   0x8000
Heap:            12   0x0013
Elem0Next:       13   0x0018
Elem0X:          14   ????
Elem0Y:          15   ????
Elem0L:          16   ????
Elem0P:          17   ????
Elem1:           18   0x001D
Elem1[1]:        19   ????
Elem1[2]:        1A   ????
Elem1[3]:        1B   ????
Elem1[4]:        1C   ????
Elem2:           1D   0x0022
Elem2[1]:        1E   ????
Elem2[2]:        1F   ????
Elem2[3]:        20   ????
Elem2[4]:        21   ????
Elem3:           22   0x0027
Elem3[1]:        23   ????
Elem3[2]:        24   ????
Elem3[3]:        25   ????
Elem3[4]:        26   ????
Elem4:           27   0x002C
Elem4[1]:        28   ????
Elem4[2]:        29   ????
Elem4[3]:        2A   ????
Elem4[4]:        2B   ????
Elem5:           2C   0x0031
Elem5[1]:        2D   ????
Elem5[2]:        2E   ????
Elem5[3]:        2F   ????
Elem5[4]:        30   ????
Elem6:           31   0x0036
Elem6[1]:        32   ????
Elem6[2]:        33   ????
Elem6[3]:        34   ????
Elem6[4]:        35   ????
Elem7:           36   0x003B
Elem7[1]:        37   ????
Elem7[2]:        38   ????
Elem7[3]:        39   ????
Elem7[4]:        3A   ????
Elem8:           3B   0x0040
Elem8[1]:        3C   ????
Elem8[2]:        3D   ????
Elem8[3]:        3E   ????
Elem8[4]:        3F   ????
Elem9:           40   0x0045
Elem9[1]:        41   ????
Elem9[2]:        42   ????
Elem9[3]:        43   ????
Elem9[4]:        44   ????
ElemA:           45   0x004A
ElemA[1]:        46   ????
ElemA[2]:        47   ????
ElemA[3]:        48   ????
ElemA[4]:        49   ????
ElemB:           4A   0x004F
ElemB[1]:        4B   ????
ElemB[2]:        4C   ????
ElemB[3]:        4D   ????
ElemB[4]:        4E   ????
ElemC:           4F   0x0054
ElemC[1]:        50   ????
ElemC[2]:        51   ????
ElemC[3]:        52   ????
ElemC[4]:        53   ????
ElemD:           54   0x0059
ElemD[1]:        55   ????
ElemD[2]:        56   ????
ElemD[3]:        57   ????
ElemD[4]:        58   ????
ElemE:           59   0x005E
ElemE[1]:        5A   ????
ElemE[2]:        5B   ????
ElemE[3]:        5C   ????
ElemE[4]:        5D   ????
ElemF:           5E   0x0063
ElemF[1]:        5F   ????
ElemF[2]:        60   ????
ElemF[3]:        61   ????
ElemF[4]:        62   ????
Elem10:          63   0x0068
Elem10[1]:       64  ????
Elem10[2]:       65  ????
Elem10[3]:       66  ????
Elem10[4]:       67  ????
Elem11:          68  0x006D
Elem11[1]:       69  ????
Elem11[2]:       6A  ????
Elem11[3]:       6B  ????
Elem11[4]:       6C  ????
Elem12:          6D  0x0072
Elem12[1]:       6E  ????
Elem12[2]:       6F  ????
Elem12[3]:       70  ????
Elem12[4]:       71  ????
Elem13:          72  0x0077
Elem13[1]:       73  ????
Elem13[2]:       74  ????
Elem13[3]:       75  ????
Elem13[4]:       76  ????
Elem14:          77  0x007C
Elem14[1]:       78  ????
Elem14[2]:       79  ????
Elem14[3]:       7A  ????
Elem14[4]:       7B  ????
Elem15:          7C  0x0081
Elem15[1]:       7D  ????
Elem15[2]:       7E  ????
Elem15[3]:       7F  ????
Elem15[4]:       80  ????
Elem16:          81  0x0086
Elem16[1]:       82  ????
Elem16[2]:       83  ????
Elem16[3]:       84  ????
Elem16[4]:       85  ????
Elem17:          86  0x008B
Elem17[1]:       87  ????
Elem17[2]:       88  ????
Elem17[3]:       89  ????
Elem17[4]:       8A  ????
Elem18:          8B  0x0090
Elem18[1]:       8C  ????
Elem18[2]:       8D  ????
Elem18[3]:       8E  ????
Elem18[4]:       8F  ????
Elem19:          90  0x0095
Elem19[1]:       91  ????
Elem19[2]:       92  ????
Elem19[3]:       93  ????
Elem19[4]:       94  ????
Elem1A:          95  0x009A
Elem1A[1]:       96  ????
Elem1A[2]:       97  ????
Elem1A[3]:       98  ????
Elem1A[4]:       99  ????
Elem1B:          9A  0x009F
Elem1B[1]:       9B  ????
Elem1B[2]:       9C  ????
Elem1B[3]:       9D  ????
Elem1B[4]:       9E  ????
Elem1C:          9F  0x00A4
Elem1C[1]:       A0  ????
Elem1C[2]:       A1  ????
Elem1C[3]:       A2  ????
Elem1C[4]:       A3  ????
Elem1D:          A4  0x00A9
Elem1D[1]:       A5  ????
Elem1D[2]:       A6  ????
Elem1D[3]:       A7  ????
Elem1D[4]:       A8  ????
Elem1E:          A9  0x00AE
Elem1E[1]:       AA  ????
Elem1E[2]:       AB  ????
Elem1E[3]:       AC  ????
Elem1E[4]:       AD  ????
Elem1F:          AE  0x8000
Elem1F[1]:       AF  ????
Elem1F[2]:       B0  ????
Elem1F[3]:       B1  ????
Elem1F[4]:       B2  ????
Stack:           B3  ????
Stack[1]:        B4  ????
                 B5  ????
                 B6  ????
                 B7  ????
                 B8  ????
                 B9  ????
                 BA  ????
                 BB  ????
                 BC  ????
                 BD  ????
                 BE  ????
                 BF  ????
                 C0  ????
                 C1  ????
                 C2  ????
                 C3  ????
                 C4  ????
                 C5  ????
                 C6  ????
                 C7  ????
                 C8  ????
                 C9  ????
                 CA  ????
                 CB  ????
                 CC  ????
                 CD  ????
                 CE  ????
                 CF  ????
                 D0  ????
                 D1  ????
                 D2  ????
                 D3  ????
                 D4  ????
                 D5  ????
                 D6  ????
                 D7  ????
                 D8  ????
                 D9  ????
                 DA  ????
                 DB  ????
                 DC  ????
                 DD  ????
                 DE  ????
                 DF  ????
                 E0  ????
                 E1  ????
                 E2  ????
                 E3  ????
                 E4  ????
                 E5  ????
                 E6  ????
                 E7  ????
                 E8  ????
                 E9  ????
                 EA  ????
                 EB  ????
                 EC  ????
                 ED  ????
                 EE  ????
                 EF  ????
                 F0  ????
                 F1  ????
                 F2  ????
                 F3  ????
                 F4  ????
                 F5  ????
                 F6  ????
                 F7  ????
                 F8  ????
                 F9  ????
                 FA  ????
                 FB  ????
                 FC  ????
                 FD  ????
                 FE  ????
                 FF  ????


ШИКАРНО!
Теперь можно отчётливо видеть, что между отдельными записями списка действительно установлены связи, уже при инициализации памяти.

Боюсь, что вот-вот козёл Фрэнк сочтёт пост слишком длинным, так что пора закругляться.


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

Poll #2103165 Связанные списки

Насколько они актуальны?

По-прежнему актуальны
2(100.0%)
Годятся только в учебных целях, студентов помучать!
0(0.0%)
Вообще не нужны
0(0.0%)
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