Я испытывал модуль SPI, и для начала решил подключить по нему не SD, с которой я ещё ни разу не имел дела, а что-то более знакомое - АЦП ADC124S051, который у меня замечательно опрашивался и выдавал данные по UART "в человеческом виде", без всяких процессоров, на чистом верилоге :) Надеялся, что и сейчас с пол-пинка он заработает - не тут-то было. Несколько проблем с модулем SPI нашёл на симуляции, после чего вроде всё правильно, но "в железе" не работает, хоть ты тресни!
Даже осциллограф расчехлил, тыкался по всем проводам, и увидел совершенно нормальный информационный обмен. А вся подлянка ждала меня в строке
[SP++] Y
В стек записывалось что угодно, только не регистр Y, и потом всё катилось под откос...
Многострадальный модуль QuatCoreMem никак не сдастся. Мы его уже правили раз, и ещё раз, и ещё раз, но здесь у нас волшебное число: 4, так что ещё разок точно придётся.
Вот как он у нас выглядит:

Последняя доработка позволяет легко и непринуждённо поставить любой из базовых регистров в качестве DestAddr, т.е записать в них любой другой базовый регистр, или значение из памяти.
Обратное, увы, неверно, поскольку у нас стоит всего ОДИН мультиплексор базового адреса. Выход с него идёт как напрямую в мультиплексор SquareMux (выбор, нужен ли нам адрес или значение из памяти, лежащее по этому адресу), так и в формирователь эффективного адреса. Когда мы пытаемся записать в память базовый регистр, нам нужно и то, и другое, причём РАЗНЫЕ регистры.
Сейчас выходит, что в строке
[SP++] Y
первый операнд (DestAddr) берёт верх, и мультиплексор базового адреса выбирает SP. SquareMux выбирает адрес, а не значение, вот только адрес не тот. Нам нужен Y, а вместо него получается SP. Именно адрес стека внезапно заносится в стек, и затем вполне корректно извлекается назад в регистр Y, затирая её исходное значение.
Мы можем пойти "в обход" программно: написать
[SP++] C C Y ... ... Y C C [--SP]
(если регистр C не используется. Если используется - ещё немножко телодвижений понадобится)
А можно и аппаратно: для этого нужно поставить два одинаковых мультиплексора. Один такой занимает при 8-битной адресации 16 ЛЭ. Модуль памяти QuatCoreMem "в сборе" - пока что 127 ЛЭ.
Попробуем доработать эту хреновину:

Декодирующая логика второму мультиплексору не нужна, он просто берёт 2 бита из SrcAddr. Теперь модуль занимает 143 ЛЭ, ровно на 16 больше. Теперь мы сможем заносить любой регистр в стек, да и вообще по любому адресу в памяти, без ограничений. Переносы "память-память" по-прежнему недоступны, поскольку формирователь эффективного адреса всё равно один. Но к этому мы уже привычные...
Кажется, заработало. По крайней мере, один канал отображается.
