Shaos wrote:Shaos wrote:Триада - это три трита, каждый из которых представлен двумя битами - младшим битом минуса и старшим битом плюса. Триады у нас перевёрнуты из-за особенностей схемы "3niti alpha simu1", т.е. в старших битах находится младший трит, а в младших - старший:
bit 0 - установлен в "1", если старший трит триады отрицателен
bit 1 - установлен в "1", если старший трит триады положителен
bit 2 - установлен в "1", если средней трит триады отрицателен
bit 3 - установлен в "1", если средней трит триады положителен
bit 4 - установлен в "1", если младшей трит триады отрицателен
bit 5 - установлен в "1", если младшей трит триады положителен
bit 6 - должен быть нулевым
bit 7 - должен быть нулевым
Если таким байтом адресоваться к 27-триадному блоку данных, то в двоичной памяти оно расположится так:
Code: Select all
0x00 (00000000) OOO = 0
0x01 (00000001) NOO = -9
0x02 (00000010) POO = +9
0x03 (00000011)
0x04 (00000100) ONO = -3
0x05 (00000101) NNO = -12
0x06 (00000110) PNO = +6
0x07 (00000111)
0x08 (00001000) OPO = +3
0x09 (00001001) NPO = -6
0x0A (00001010) PPO = +12
0x0B (00001011)
0x0C (00001100)
0x0D (00001101)
0x0E (00001110)
0x0F (00001111)
0x10 (00010000) OON = -1
0x11 (00010001) NON = -10
0x12 (00010010) PON = +8
0x13 (00010011)
0x14 (00010100) ONN = -4
0x15 (00010101) NNN = -13
0x16 (00010110) PPN = +5
0x17 (00010111)
0x18 (00011000) OPN = +2
0x19 (00011001) NPN = -7
0x1A (00011010) PPN = +11
0x1B (00011011)
0x1C (00011100)
0x1D (00011101)
0x1E (00011110)
0x1F (00011111)
0x20 (00100000) OOP = +1
0x21 (00100001) NOP = -8
0x22 (00100010) POP = +10
0x23 (00100011)
0x24 (00100100) ONP = -2
0x25 (00100101) NNP = -11
0x26 (00100110) PNP = +7
0x27 (00100111)
0x28 (00101000) OPP = +4
0x29 (00101001) NPP = -5
0x2A (00101010) PPP = +13
0x2B (00101011)
0x2C (00101100)
0x2D (00101101)
0x2E (00101110)
0x2F (00101111)
Как можно видеть, не используются любые ячейки, в адресе которых встречаются две пары единиц у любой из триад (запрещённая комбинация в binary coded ternary).
В первой версии эмулятора для платы "3niti alpha simu1" предлагается держать 27-триад кода в EEPROM (как бы троичный ROM) с вышеуказанными адресами и 27-триад данных в регистровой памяти (как бы троичный RAM) с вышеуказанными адресами, к которым прибавлено число 0x40, т.е. диапазон переменных 0x40...0x6F (нулевой банк файла региcтров в пике).
В терминах длинных адресов "3niti alpha", этот 27-триадный ROM будет отображаться на область OOOOOOxxx, а 27-триадный RAM - на область OPNNNNxxx (начиная с адреса +1093). В текущей прошивке, над которой я сейчас работаю, внешняя память пока использоваться небудет (её можно будет добавить позже - у схемы есть возможность обновления прошивки через бутлоадер).
P.S. Глядя на этот маппинг троичных адресов на двоичные у меня возникла идея - что если прямо так и хранить во внешней памяти? Можно читать по 48 байт (тогда потеряно будет 44% памяти), убрав последние 5 байт получим 43 байта (37% потерь) или даже брать блоками по 11 байт три раза, где будет всего 2 однобайтных дырки (18% потерь). Проблема лишь в том, что придётся адресоваться к памяти через умножение - надо будет умножать на 48 (00110000), 43 (00101011) или 11 (00001011) - хотя точнее надо бы сказать 33 (00100001), т.к. 3 раза по 11. Формула уможения на 48: (x<<5)+(x<<4). Формула умножения на 43: (x<<5)+(x<<3)+(x<<2)+x. Формула умножения на 11: (x<<3)+(x<<1)+x или (x<<3)+(x<<2)-x (т.е. 12*x-x). Формула умножения на 33: (x<<5)+x. Хотя блоками по 27 тоже умножать надо, причём на некрасивое число 00011011...
P.P.S. Прикинул, что при 3x11-байтовом представлении 27-триадной страницы теоретически будет читаться-писаться по 300 страниц в секунду при 100кГц или 1200 страниц при 400кГц. Но т.к. при записи будет до 10 мс задержка на запись очередной порции (до 32 байт длиной) - то это уменьшит скорость записи до 30 страниц в секунду при 100кГц или 120 страниц при 400 кГц. Напомню, что первоначально оговоренный размер блоков RAM и ROM у
3niti alpha составляет (1093*2+1)/27=81 страница, которые можно прочитать меньше чем за треть секунды и записать за 2.7 или за 1.35 секунды в зависимости от тактовой частоты ПЗУ. Байты "потерянные" при такой оптимизации можно использовать для хранения адреса страницы (для проверки корректности места чтения) и её контрольной суммы (для проверки целостности данных).
P.P.P.S. Внимательно прочитал даташит на I2C память - страничная запись подразумевает запись в 32-байтовые области с фиксированными адресами - т.е. придётся таки писать ровно по 32 байта...