De0-Nano SRAM шилд

Покупая отладочную плату De0-Nano, я как то сразу про себя подумал, а SRAM то и не хватает.
Ну а разве радиолюбителю проблема добавить платку, решил я, пару недель назад…

Далее под катом подробности того что из этого получилось.

Введение
И так для создания шилда я выбрал асинхронную SRAM 256K*16 типа CY7C1041DV33.Выбор продиктован очень просто — была в продаже.
Что бы ни томить читателя, сразу похвастаюсь, МС удалось завести на максимальной для нее частоте 100МГц (на чтение).
Железо
До сего момента, я никогда не разводил схемы с частотой работы больше 20МГц (а если точнее, то это мега какая ни будь на такой частоте работала, а уж периферия…), по этому сперва начал изучать всякие мануалы по разводке высокоскоростных схем, например AN4010. Дело в том, что я надеялся увидеть общие рекомендации, а там формулы, формулы.
Ясно, что считать каждую дорожку мне никак, не хотелось, но и с другой стороны, проконтролировать результаты трудов мне тоже нечем, поэтому пришлось делать, полагаясь на интуицию и общие правила:
  1. Дорожки покороче.
  2. Никаких прямых углов.
  3. Конденсаторы поближе к чипу.
  4. Ну и мой личный предел по техпроцессу ЛУТа — 0.4/0.3 для стабильности результата.
Вторым важным моментом, было само размещение шилда. Дело в том, что SRAM надо 39 пинов. А на плате De0-Nano, есть три разъема, два по 40 пинов (по 34 IO пина) и 1 на 26 пинов (13 IO пинов). Можно взять чип sram с 8 битной шиной, и тогда его можно подключить на 1 порт, но в таком случае мы теряем в скорости.
Сначала, я хотел подключить шилд непосредственно к одному из разъемов, а недостающие выводы подключить шлейфом к другому. Но такой вариант мне не понравился, и я решил разместить шилд непосредвенно под основной платой. Таким образом основная честь портов SRAM подключена к разъему GPIO 1, шлейфом IDC через гребенку типа PLD 40R, а оставшихся 5 штук через разъем типа PBD непосредственно к разъему GPIO2.
Вот такая получилась печатка:

Схему не привожу так как, она проста как угол дома. Каждый пин подключен через резистор 33 Ом, плюс возле питания 2 конденсатора по 0,1 uF, 1 резистор 0 Ом 1206 и две перемычки ( провод должен быть изолирован). Соответствие пинов SRAM и выводов ПЛИС можно найти в настройках квартуса (вложение).
Кстати про резисторы, установлены они здесь для исключения «звона» линии. По правилам они тоже рассчитываются, но я ставил те, что были. Опять же, как они влияют на линию, я не знаю. Но на старших платах от Terasica, на выходных разъемах резисторы есть (82 Ом), а на этой нет. Так что, хоть какая то защита от короткого, если что.
Лутим, травим, запаиваем.


Еще раз все прозваниваем и можно переходить к софту.
Софт

NIOS 2-50Мгц

Так как SRAM планировалось использовать с встроенным процессором, то для испытания работы полученной платы я решил использовать предлагаемый альтерой процессор NIOS 2.
Честно, говоря Quartus 2, довольно сложный пакет программ, на изучение которого необходимо затратить не мало времени. Я же пытаюсь все время взять его нахрапом, что порой выливается в долгие часы борьбы с неизвестными глюками. Благо, в сети есть не мало quick start по нему, и все же и они не все учитывают. Поэтому далее я буду не много останавливаться, на таких «подводных камнях», себе на память, плюс еще кому сгодится.
Дабы не мучатся созданием системы с нуля, я выбрал готовый проект поставляемый с Altera University Program (далее UP)– De0-Nano Basic Computer. Плюс такого решения, готовый рабочий проект. Все IP поставляемые с UP открыты для изучения, так что можно посмотреть все изнутри.
А самое главное, подключение sram к проекту в Qsys выглядит как: university program->memory->sram/ssram->de1(или de2 без разницы.
Далее необходимо подключить шины, и назначить диапазон адресов, у меня получилось 0х04080000-0х040FFFFF. После генерируем проект, а также делаем необходимые исправления в основном проекте квартуса. После чего компилируем уже основной проект.
Обычно, после такого изменения компиляция заканчивается с критическим варнингом – мол отсутствует назначение выводов для n выводов схемы, так что надо открыть Pin Planner и назначить выводы для SRAM.
Если собралось без критических ошибок, то можно переходить к написанию программ. Для этого у квартуса есть Nios 2 Software Tool на базе eclipse.
И тут снова удача, в стандартных примерах есть программа Memory Test Small, которая при беглом осмотре выполняет следующие действия для указанного диапазона памяти:
  1. Тестирует шину данных.
  2. Тестирует шину адреса.
  3. Тестирует работу всех ячеек памяти в указанном диапазоне.
Ура, подумал я, ничего писать не надо, и быстренько собрал проект.
Наступил момент истины, я подключил плату к питанию — дыма нет, запрограммировал ПЛИС- все ОК. Загружаем проект для отладки – не грузится. Проблема вот в чем:

В проекте используется функция System ID, в которую можно записать уникальный номер, который Eclipse будет проверять при отладке и если он не совпадает…
Вообщем, галочки которые надо установит, отметил красным (они мне стоили пару часов времени). Также если в поле Connections в графах Cable будет пусто. Надо нажать кнопочку Refresh Connection. И так грузим.
Также не забываем после каждого изменения в основном проекте в квартусе регенирировать bsp файлы в эклипсе: «name»_bsp->right click->nios2-> generate BSP.

И вот система нас приветствует:

<---->   Nios II Memory Test.   <---->
This software example tests the memory in your system to assure it
is working properly.  This test is destructive to the contents of
the memory it tests. Assure the memory being tested does not contain
the executable or data sections of this code or the exception address
of the system.


Дальше надо ввести наш диапазон памяти и начать тест. Опять засада, тест стопорится с фразой:

-Data bus test failed at bit 0x1024

Я так и не понял, почему он падает на 1024 бите, и тут же совершил грубую ошибку посчитав, что это программа кривая.
Дальше я пытался много часов заставить работать схему через Altera Monitoring Program, попутно борясь с незнакомым ассемблером, необходимостью писать свою программу теста и ошибками в ней, так как ее пришлось писать фактически в блокноте.
Итог странный, вроде раз пишется, раз нет, то все нормально, то одни ошибки. На вкладке memory watch, то все как надо то билеберда. Так продолжалось бы долго, пока я не нашел в той де программе пункт Memory Fill, позволяющий записать в память свои данные.
Я решил записать в sram 0X11. Но что за фигня, уже через деcяток байт в памяти оказывается вот такое:
15111511 15111511 15111511 15111511


Так как у нас шестнадцатиразрядная шина, то получается что в 10 бит вместо 0 пишется 1, причем постоянно. Берем микроскоп в руки, а-а-а нога IO10 практически парит над площадкой. Еще раз пропаиваю выводы. Повторяю тест – все ОК.
И тут я вспомнил про 0x1024 вот оно что, мне же программа сразу указывала на неисправный вывод.
Запускаю снова Eclipse, и вправду теперь тест шины данных проходит, но вылетает на тесте шины адреса. Но, я то уже знаю, как с этим бороться, паяльник в руки…
И в конце дня я таки получил заветное:
Testing RAM from 0x4080000 to 0x40FFFFF
 -Data bus test passed
 -Address bus test passed
 -Byte and half-word access test passed
 -Testing each bit in memory device. . .  passed
Memory at 0x4080000 Okay

Я не придумал ничего лучше как дописать такую обвертку к функции тестирования.
for (y=0; y<10000; y++)
{

}
if(!ret_code2)
printf(" Pocket test OK\n");
printf("%d failed tests\n", ret_code2);
//И приблизительно через сорок минут увидел в консоли:
Pocket test OK
0 failed test.

Возможно, этого и мало, но для homemade считаю достаточно.
Почему же на плате оказалось столько непропаев? Все очень просто, если еще раз посмотреть на фото платы с ЛУТ можно увидеть виасы под чипом. И хотя я их запаял очень аккуратно, их высоты все равно хватило что бы перекосить чип на плате. Дело в том что такой ход с виасами под чипом прокатывает для меги в tqpf, а эта sram в TSOP II, который плотно прижимается пузом к плате да и ноги у него коротенькие не сильно паяльником прижмешь.
Одним словом виа под чипом в самодельных платах зло.

NIOS 2 — 100Мгц

Из даташита на sram известно, что Trc (read cycle) у нее 10ns, а значит, она может работать при тактовой частоте 100МГц. И тут уже все просто, переделываем проект под частоту 100МГц, собираем, прошиваем и … НИФИГА.
Точнее не то что sram не работает, такое впечатление что процессор заменили на ГСЧ. Ибо глючит он безбожно.
Долгое изучения аналогичных проектов вывело меня на замечательную инструкцию:
emb4fun
И так сразу перехожу к тому, что надо изменить проекте:
Процессор выбрать типа f (fast) – возможно это и не влияет, но все же.
И поменять настройки SDRAM в которой собственно работает процессор.
1. Для нормального функционирования SDRAM ей нужен отдельный клок опережающий основной на 3ns, но это для 50 МГц, а для 100 МГц соответственно в 2 раза меньше. И что бы не мучатся с высчитванием наносекунд, лучше сразу поменять их на градусы (примерно-60 град) вот так:

2. Также надо поменять также тайминги SDRAM:

На что они влияют, я особо не вникал, но с ними процессор завелся нормально.
Но вот память sram все равно так и не заработала на 100Мгц (да и на 75 и 60 МГц тоже), я даже проект с нуля собрал, но все без толку.

Еще один день ушел на обдумывание причин такого поведения.Пришлось все таки вернуться в самое начало, то есть к даташиту и таймингам.
Так как это асинхронное sram, то на цикл записи уходит один такт, на запись 2 такта. Или если рассмотреть код модуля sram, можно очень упрощенно представить цикл чтения в таком виде ( для простоты считаем что сигналы oe, we, уже в нужном состоянии).

Как видно из рисунка, после появления команды read от процессора по тактовому сигналу 1, захватываются данные adress (на диаграмме сразу показан выход модуля) и поступают на вход sram. По второму тактовому сигналу, входные триггеры запоминают состояние шины данных, а на выходе valid1 появляется 1, говоря процессору о том, что данные можно забирать. Разница в один такт между read и valid1 достигается вводом промежуточного триггера.
Но это в идеале, а в реале уже с диаграммы видно, что значения адреса появляется спустя некоторое время после фронта клока, а потом эму надо побежать по не самой лучшей плате до sram, а она в свою очередь тоже не сразу данные отдает, есть даже параметр такой Taa (adress to data valid) который в худшем случае гарантируется в 10ns…
Приехали, с такими успехами, хорошо что оно на 50 МГц заработала. Что же делать в таком случае?

Вечерело, и единственной идеей пришедшей в голову стало ввести между read и valid1 еще один триггер (получаем сигнал valid2), выделяя на цикл чтения все те же 20ns. Естественно после такой модификации, все заработало на отлично.
И таким образом запись получилась на 100МГц, чтение около 30.
Можно ли еще увеличить скорость чтения? Можно, и даже нужно, но на этот вечер у меня идеи закончились ;-).
  • +11
  • 22 ноября 2013, 22:42
  • Signaller
  • 1
Файлы в топике: sram_100.zip

Комментарии (23)

RSS свернуть / развернуть
Это отличная статья!
Поздравляю с успехом!
0
Спасибо, несколько раз порывался написать на пол пути, но все думал нет давай еще так попробую. На очереди еще пару идей для ПЛИС, надеюсь пойдут полегче.
0
Хм, а на такой частоте выравнивание длин линий еще не требуется?
+1
  • avatar
  • Vga
  • 23 ноября 2013, 02:00
Нет, не требуется. Длины не выравниваются на высокочастотных SDRAM(до 166 мгц). Хотя можно встретить дизайны, на которых эти линии выровнены — видимо делают по принципу, кашу маслом не испортишь. Выравнивать нужно на DDR\DDR2, там без этого, вообще, работать правильно не будет.
-1
На нескольких источниках читал что 100 МГц как раз граничная частота, начиная с которой нужно выравнивать длину дорожек, волновое сопротивление и т.д., у самого опыта работы с высокочастотными шинами очень мало, только с RF сигналами и то не много, но могу посоветовать исходя из того, что имею:
1) питание, должно быть организовано в разы лучше чем сама шина — нагрузка на каждом элементе шины (емкость) при резких фронтах и спадах (высокие частоты) целиком и полностью ложиться на питание, грубо говоря 2 ножки питания держат 16 ног шины (сужу о питании по 2-м кондерам на плате), кондеры это хорошо, но вопрос в том какие и сколько:
а) чем выше частота, тем меньше советуют типоразмер кондера (0402 лучше 0603, 0603 лучше 0805) (обосновывают внутренней составляющей индуктивности)
б) чем выше частота -> лучше ставить ниже номинал кондера, будет лучше отдавать заряд
в) лучше поставить разные номиналы кондеров, допустим 0,1 мкФ + 1000 пФ
Дорожки питания лучше подвести пожирнее, никаких нулевых резисторов-перемычек на пути, лучше кусочек провода припаять
2) все дорожки шины должны быть максимально близкими по своим параметрам (если есть переходы, то на всех, одинаковые)
3) расстояние между дорожками, особенно длинными, не меньше двух ширин дорожек
4) есть еще требования касательно полигонов земли/питания, проходящими под дорожкой, но к сожалению статью найти не могу, а без картинок не объяснить (касательно вырезах в полигонах, границ полигонов), если найду, добавлю ссылку
Вообще тема рекомендаций по разводке высокочастотных плат мало освещена в статьях(статей конечно не мало, но все о разном, связать в кучу самому сложно, поскольку очень много палок о двух концах, сделаешь лучше для одного, проиграешь в другом, и как найти компромисс — вопрос тяжелый), было бы неплохо сделать единый источник рекомендаций (есть конечно книги, но чтобы полностью понять их материал, нудно подкреплять опытом, а начинать с чего то нужно...)
+3
Совершенно согласен. Вот только посчитать дорожки без спец софта задача крайне сложная, думаю если эту же схему подсунуть какому нибудь монстру разводки (altium, eagle), то он развел бы ее получше.
никаких нулевых резисторов-перемычек на пути, лучше кусочек провода припаять
А вот это интересный момент, почему резистор-перемычка хуже куска провода?
0
Потому что его сопротивление — несколько десятых ома.
0
А-а, теперь ясно. Я вообще перемычки подсознательно не люблю, но без них дома плату увы не разведешь. Впредь буду стараться на высоких частотах в сигнальных линиях их не использовать.
0
в свое время заметили что 0805 нулевики перегарают при токах чуть более ампер (хотя, казалось бы с чего бы нулевому то). больше в такие цепи не ставим.
0
частота не самый важный фактор. важный фактор модуляция. если фазовая составляющая несет какую то информацию, то граничная частота на которой нужно выравнивание падает в разы.
0
частота не самый важный фактор. важный фактор модуляция
Я писал применительно к конкретному случаю, описанному автором. Насчет модуляции могу согласиться с оговоркой, что это тоже зависит от конкретного случая, а случаи эти либо из аналоговой части, либо из интерфейсов, где модуляция является частью протокола передачи данных. Я уже писал, что у меня не так много опыта работы с разводкой цифровой ВЧ части, и если, по вашему мнению, я не прав, просветите меня пожалуйста в этом вопросе, буду рад подчеркнуть для себя что то новое =)
0
соглашусь. тоже малость оговорился. в ddr модуляции нет в явном виде, но частота передачи данных выше частоты клока в два раза, поэтому там та же беда что и с модуляцией. тактирование вроде и с той же частотой, а требования выше.
0
А вот интересно чем не устроила встроенная в эту плату 16 Meg x 16 bit SDRAM (143 MHz)?
0
  • avatar
  • wowa
  • 23 ноября 2013, 14:32
за автора сказать не могу, но думаю из-за разницы между SDRAM и SRAM, вот статья по разнице между ними(английский):
www.differencebetween.net/object/difference-between-sram-and-sdram/
в кратце: SDRAM — динамическая память, нужно периодически обновлять записанное, SRAM — статическая память, записал — храниться, пока не сбросил питание (действует на оба вида, они оба энергозависимы)
0
Я это знаю :) Только вот та что стоит на досточке работает быстрее чем то что сделал автор. А так же памяти уже давно перешагнули проблемы с регенерацией. В встроеной микросхеме есть авторегенерация. Плюс у ней есть много интересных режимов работы которые ещё более ускоряют работу с ней неговоря о том что она полностью синхронная по отношению к интерфейсу.Так что вопрос к автору остался :) Я так же слышел что существуют SRAM чипы которые по питанию совпадают с SDRAM — тоесть их можно просто заменить одну за другую. Далее разводка по ногам всёравно делается програмно.
0
Причина проста. Одна память хорошо, а две лучше:-). А точнее на самой плис под алгоритм памяти хватает, но без процессора. А с процессором уже маловато, вот я и подумал, что пусть проц работает с sdram + кеш. А под буфер взять sram, да и работать с ней, как с отдельным блоком, попроще.
+1
Первая мысль, которая возникла при взгляде на чертеж платки: «неужели это будет НОРМАЛЬНО работать?..».
Потом просмотр статьи по диагонали успокоил.
А когда, я читал комменты и до меня дошло, что платка еще и в Sprint`е трассирована, то я искренне порадовался, что есть еще такие трудолюбивые люди и что автора оно вообще хоть как-то заработало.
:)
0
Хе, сам в шоке. Пора переходить на продвинутые пакеты pcb design, но они столь монструозны, что для 1 платки раз в пол года, мучиться не хочется.Хотя диптрейс поставил, может осилю.
0
сейчас тоже пытаюсь. основная проблема паттерны непривычные. с интерфейсом разобрался вроде. а вот библиотеку пока до ума не довел и как то непривычно, что под 0805 ничего не провести
0
Это получается если микроконтроллеру не хватает SRAM то можно вот такую внешнюю микруху подключить? А че так много ног надо для подключения?
0
А где вы тут мк увидели? У автора softcore ядро в FPGA.

Ну а ног много, потому как чип ведь 256Кх16, 18+16=34 ноги нужны только для шин адреса и данных, потом еще всякой мелочи вроде земли, питания, стробы…
+1
Ну ниже уже ответили, а вообще попадались проекты и для авр. Но ног все равно надо много :-(
0
хм, у Сабунина есть неплохой видеоурок по выравниванию длин в Альтиуме тыц
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.