§ Виды памяти
Существует огромное количество разных видов памяти, которые подразделяются на категории, отделы, классы и так далее. Например, есть память SRAM (Synchronous Random Access Memory — память произвольного доступа, синхронная), она очень дорогая и выполнена обычно, на транзисторах. Транзисторная память находится в кешах, регистрах, в разного рода защелках. Это очень быстрая память, ее объем исчисляется от байт до мегабайт, а не гигабайтами, но работает такая память на скорости самого ядра процессора.А есть более дешевая память, DRAM (Dynamic RAM), и выполнена она с использованием микроконденсаторов, которые располагаются специальным образом рядом с управляющим транзистором. Такая память менее надежна и ей требуется постоянное обновление приблизительно раз в 20 мс (миллисекунд, то есть 0.02 секунду), или, так сказать, 50 раз в секунду, но можно и чаще, и чем чаще, тем, на самом деле, лучше. Почему ей нужно обновление, понятно потому, что конденсаторы не могут долго удерживать заряд и разряжаются не только по истечении времени из-за саморазряда, но и при каждом считывании данных с них, поскольку для того, чтобы данные прочитать, приходится "слить" с конденсатора значительную часть заряда, который нужно тут же восстановить.
Поскольку у меня есть SDRAM, а не DRAM (они отличаются временем доступа к данным), то я буду рассказывать именно о том, как работает SDRAM (Synchronous DRAM). Такая память отличается от DRAM тем, что она дает гарантированный ответ через опеределенные промежутки времени и заранее заданное фиксированное количество тактов, в отличии от DRAM, которая может профурычиваться столько, сколько ей потребуется.
§ Порты памяти
Далеко не секрет, что управлять SDRAM памятью очень сложно. Для того, чтобы получить доступ к определенному слову в памяти, сначала надо выбрать банк, строку памяти, а потом уже выбрать столбец, то есть, память устроена в виде трехмерной сетки, на узлах которой находятся требуемые данные.Теперь перечислю порты памяти SDRAM.
1output clk, // Генератор тактовой частоты 2output cke, // Chip Enabled (если здесь 1) 3output csn, // Chip Select (если здесь 0) 4output [ x:0] bank, // Текущий банк памяти 5output [ x:0] address, // Адрес строки или столбца 6inout [15:0] dq, // Данные (вход и выход) 7output cas, // Column Address Select, если 0, выбран столбец 8output ras, // Row Address Select, если 0, выбрана строка 9output we, // Write Enabled, если 0, то запись на следующем такте 10output ldqm, // Нижняя маска для записи или чтения 11output udqm // Верхняя маскаЗдесь много чего непонятного, но если разобраться, то все придет на свои места. С генератором тактовой частоты все ясно, он подает такты на чип памяти, который работает например, частотой 100 мгц. Провод CKE, если 1, активирует память, то есть, просто включает ее в работу. CSN, если 0, разрешает работать с памятью, он ее как бы, активирует, но мягко, не сбрасывает, а временно приостанавливает прием и передачу данных в память и из нее.
У памяти обычно 4 банка, которые могут располагаться, например, в разных "отсеках" физически, и потому, чтобы что-то прочитать, надо обязательно выбрать банк памяти для этого.
Шина
address
указывает либо на строку (если RAS=0), либо на столбец (если CAS=0), поэтому сначала делается выбор строки, потом столбца. Одновременно и сразу невозможно никак указать на нужный адрес, на выборку тратится время.С
we
тут все ясно, если WE=0, то DQ считается за вход и оттуда записывается в память, причем, записывается в некотором порядке. В случае если ldqm=0 и udqm=0, то тогда данные с DQ записываются в младший и старший байт 16 битного слова. Если например, ldqm=0 а udqm=1, то тогда записывается только в младший, а в старший записи не производится, там значение не меняется. Это удобно для проведения операции с байтами. При чтении, ldqm и udqm (или, в общем, DQM), работает аналогично. Здесь активный уровень равен 0.§ Коды команд
Для того, чтобы работать с памятью, ей необходимо отсылать команды. Всего команд 8 и они представлены в таблице ниже. Там где R — это RAS, C — CAS, W — WE, соотвественно.R C W Код Описане 0 0 0 | LOADMODE | Загрузка регистра режима 0 0 1 | REFRESH | Обновление очередной строки 0 1 0 | PRECHARGE | Перезарядка 0 1 1 | ACTIVATE | Активация строки 1 0 0 | WRITE | Запись в память 1 0 1 | READ | Чтение из памяти 1 1 0 | BURSTTERM | Остановка пакетного режима 1 1 1 | NOP | Ничего не делатьНекоторые команды тут понятны сразу, некоторые придется разобрать.
- Команда
LOADMODE
загружает во внутренний статусный регистр настройки для памяти. Что именно туда загружается и как, можно проверить в даташите. Кстати, в даташите все очень понятно и хорошо описано, так что то что я тут пишу, бессмысленно и не нужно. - Команда
REFRESH
перезаряжает очередную строку автоматически. Можно сделать перезарядку иначе, открыв строку, и закрыв ее сразу же, но эта команда позволяет сделать все без дополнительной логики со стороны контроллера и это удобно. -
ACTIVATE
включает строку. После этой команды требуется некоторое время подождать, примерно 2 такта, прежде чем информация со строки будет загружена в промежуточный буфер в памяти и будет готово к работе. - Команды
WRITE
иREAD
пишут в память и читают оттуда соответственно - Инструкция
BURSTTERM
необходима для того, чтобы досрочно остановить пакетную запись или чтение в память. Особенно важно это при записи, иначе, если этого не сделать, то туда будет записан всякий мусор. - Соответственно, инструкция
NOP
не делает ничего. Это самая ленивая инструкция из всех.