dm_mur писал(а): * | 2020-апр-23 14:46 |
Я сначала было подумал, что если к примеру ADR = 1, то адресация идет к первому байту 32-разрядного слова (если с нуля считать), ADR = 2 - то ко второму, ADR = 3, к третьему, ADR = 4 - к нулевому байту следующего 32-битного слова, тогда есть корреляция с вашим объяснением. То есть по сути получается, что шина адреса если с нулевого бита считать, соответствует восьмибитной шине данных. Не? Но зачем тогда сигналы выбора байта BE??
Так оно и будет, но имеет значение к данным какой размерности обращаться. Затем и BEx нужны.
За дальнейшее поручиться не могу, это нужно бы перепроверить, но понимаю так:
int16_t x = *((int16_t *)1); // читаем по адресу 1 16-битное слово 0xhilo.
// имеем:
// A = 0x0000_0001 -- шина адреса
// D = 0x00hi_lo00 -- шина данных
// BE0=BE3=0, BE1=BE2=1
// x = 0x0000hilo, т.е. по пути от внешней шины до внутренней произойдёт сдвиг на 1 байт.
int32_t x = *((int32_t *)2); // читаем по адресу 2 32-битное слово 0xb3b2b1b0.
// имеем:
// A = 0x0000_0002 -- шина адреса
// D = 0xb1b0_b3b2 -- шина данных
// BE0=BE1=BE2=BE3=1
// x = 0xb3b2b1b0, т.е. по пути от внешней шины до внутренней произойдёт циклический сдвиг на 2 байта.
int32_t x = *((int32_t *)3); // читаем по адресу 3 32-битное слово 0xb3b2b1b0.
// имеем:
// A = 0x0000_0003 -- шина адреса
// D = 0xb0b3_b2b1 -- шина данных
// BE0=BE1=BE2=BE3=1
// x = 0xb3b2b1b0, т.е. по пути от внешней шины до внутренней произойдёт циклический сдвиг на 3 байта.
// остальное кратно ширине шины
ОТСЮДА ВАЖНЫЙ ВЫВОД: чтобы читать слова по не выровненным адресам необходимо учитывать адрес, по которому происходит чтение и наоборот: чтобы не запариваться над учётом адреса (отбросить один или два адресных бита) нужно читать только выровненные адреса, а их всего то, кроме тривиальных:
32 битные слова кратно только 0х4, 16 битные - кратно только 0х2 - для 32 разрядной памяти;
16 битные - кратно только 0х2 - для 16 разрядной памяти.
если же хочется читать как угодно и что угодно с точностью до байта, тогда для каждого читаемого байта нужно вычислять адрес с учётом адреса чтения и ширины шины (например с помощью ПЛИС и байтовых ОЗУ).
RAM[j].ADDR = (MCU.ADDR + N-1 - j ) >> LOG2(N)
RAM[j].BE = MCU.BE[j]
RAM[j].D = MCU.D[j]
где j - это номер байта в шине, начиная с нуля, и соответствующая м/с ОЗУ за него отвечающая (её индекс в массиве);
N = ширина шины данных, байт.
Мультиплексор байт данных уже встроен в КШ МК.