FPGA: Xilinx Spartan-6 MCB DDR3, поднимаем контроллер памяти.

 

В статье пойдет речь о том как поднять встроенный контроллер памяти MCB в Spartan-6 для памяти DDR3.

Затем буден создан проект для тестирования памяти.

Исходные данные:

  • ПК с Windows 7 64, Xilinx ISE 14.7, ModelSim.
  • Плата с SPARTAN-6 (xc6slx16 ftg256) + DDR3 (MT41J64M16LA-187E:B).
  • Голова, руки, время и т.п.

  

 

ВНИМАНИЕ: Для экономии места производители (микросхем памяти да и не только) не пишут полного

наименования, а оставляют сокращенный код.

Расшифровку кода для DDR3 Micron можно посмотреть у них на сайте

https://www.micron.com/support/tools-and-utilities/fbga?fbga=d9hxt#pnlFBGA

 

 


Создание проекта в Xilinx CORE Generator.

 

Запускаем CORE Generator.

Создаем новый проект, в меню File->New Project. Сохраняем проект my_ddr3_mcb в отдельную

директорию C:\PRJ\my_ddr3_mcb.

 

 

В Part, в выпадающем меню, выбираем свой кристалл (spartan6, xc6lsx16, ftg256, -2).

 

 

В Generation выбираем язык Verilog, нажимаем ОК.

 

 

Выбираем в IP Catalog контроллер памяти MIG Virtex-6 and Spartan-6 3.92

Затем нажимаем Customize and Generate. В появившемся окне нажимаем Next.

 

 

 

Выбираем Create Design и задаем Compoinent Name = mig_39_2_ddr3 (или любое другое),

нажимаем Next.

 

 

В окне Pin Compatible FPGAs выбираем наш кристалл если есть или любой другой если нет,

в данном случаи был выбран xc6slx9-ftg256 (хотя наш кристалл xc6slx16).

Нажимаем Next.

 

 

Теперь выбираем контроллер к которому подключена память на плате.

Согласно схеме, память подключена к MCB (C3).

Выбираем тип памяти Memory Type -> DDR3 SDRAM.

Ставим галку в поле Extended MCB. Данное поле отвечаем за максимальную производительность

(скорость) работы контроллера памяти. Это означает что ядро FPGA должно питаться повышенным

напряжением питания для устойчивой работы на максимальной скорости, согласно даташиту.

Т.е. исходное значение (Standart performance) 1.2 вольта -> повышенное (Extended performance)

1.23 вольта. Выдержка из даташита представлена ниже.

Нажимаем Next.

 

 

Frequency - оставляем без изменений, это максимальная частота на которой возможна работа

контроллера в spartan6 и индексом -2.

В данной реализации частота будет другой (325 МГц), т.к. на плате нет возможности получить 333 МГц.

Выбираем в Memory Part микросхему памяти, в данном случаи MT41J64M16XX-187EE.

Если в списке нет нужной микросхемы то выбираем наиболее близкую к установленной

(в том числе и по разрядности шины данных) на нажимаем Create Custom Part.

Затем в появившемся меню задаем тайминги из даташита на новую микросхему памяти.

 

 

Выбираем RTT (nominal) - ODT = RZQ/2.

 

 

В следующем окне выбираем:

Разрядность пользовательских портов (32 разрядные порты),

снимаем галку со всех портов кроме Port0.

В проекте тестера памяти будет использоваться только один порт.

Задаем метод адресации памяти галка напротив BANK-ROW-COLUMN.

Нажимаем два раза Next.

 

 

Если контроллер должен проводить калибровку:

Выбираем Calibrated Input Termination. Задаем пин на который подключен резистор RZQ - M4

Задаем пин который не подключен ZIO - M5.

Выбираем тип тактового генератора System Clock - Single-Ended (т.к. на плате установлен

НЕ дифференциальный генератор).

 

 

Если не проводим калибровку контроллером (резистора RZQ не предусмотрен, нет на схеме):

Выдираем Un-calibrated Input Termination. Задаем сопротивление 25-50-75 Ом в зависимости от

реализации. При этом вывод M4 (или другой) должен оставаться не подключенным.

Выбираем тип тактового генератора System Clock - Single-Ended.

Нажимаем Next два раза.

 

 

 

Выбираем Accept и нажимаем Next два раза.

 

 

Нажимаем Generate.

 

 

 

Ожидаем окончания создание проекта.

 

 

 

Нажимаем Close. Закрываем CORE Generator.

 

Ядро готово ! Переходим к созданию проекта тестера памяти.


Тест памяти.

 

Алгоритм тестирования памяти следующий.

В ячейку памяти по заданному адресу записывается значение, затем считывается и сравнивается с тем

что было записано. Если есть различие, то сообщаем об ошибке и останавливаем проверку.

Тест проходит по всему диапазону адресов.

В память поочередно пишутся следующие паттерны 0xAAAAAAAA, 0x55555555, 0xFFFFFFFF, 0x00000000.

 Результат тестирования памяти выводится на светодиод и в консоль UART 115200 8N1.

Индикация светодиода:

  1. Подали питание на плату - НЕ ГОРИТ.
  2. Загрузили проект, идет тест - МИГАЕТ один раз в секунду.
  3. Тест закончился, ошибок нет - НЕ ГОРИТ.
  4. Тест закончился, есть ошибки - ГОРИТ постоянно.

 

Вывод в консоль:

  1. При старте теста выводится выводится - TEST:
  2. Тест закончился, ошибок нет выводится - PASS OK.
  3. Есть ошибки - Выводится строка с адресом где была найдена ошибка, в формате [АДРЕС, Записанное Значение, Прочитанное Значение]. Например: 0x0000000 0xAAAAAAAA 0xAAAAAABA и в конце строка ERROR.

 

 Примеры:

TEST: 
PASS OK
TEST: 
0x040BF360 0xAAAAAAAA 0xAAAAAABA
ERROR

 

 

Создание проекта для Xilinx ISE.

 

CORE Generator создает всю необходимую инфраструктуру, остается только запустить скрипт C:\PRJ\my_ddr3_mcb\mig_39_2_ddr3\example_design\par\create_ise.bat для создания

проекта для среды ISE.

Далее необходимо подправить проект под свою реализацию, т.к по умолчанию

создается проект который не учитывает всех возможных вариантов реализации.

 

Тактовый частоты.

 

Для данного Spartan-6 с индексом -2, максимальная частота работы памяти DDR3 может быть 333 МГц

и удвоенная 666 МГц для блока MCB.

ВНИМАНИЕ: По стандарту частота DDR3 не может быть ниже 303 МГц.

На использованной плате есть генератор 50 МГц, из которого при помощи PLL получаем все необходимые

частоты (кратные 50 МГц), т.е. наша частота будет 325 МГц для памяти и удвоенная 650 МГц для MCB.

650 МГц получается как 50 МГц * 13, и 325 МГц получается как 650 МГц  / 2.

Для установки частоты в файле infrastructure.v задаем множитель CLKFBOUT_MULT = 13,

что даст нам 650 МГц и 325 МГц.

 

Если применяется spartan-6 c другим индексом -3  например, то максимальная частота памяти может

увеличена до 400 МГц и 800 МГц для MCB. 400(800) МГц это максимальная частота на которой способен

работать MCB в Spartan-6 c DDR3. Для 400 МГц множитель CLKFBOUT_MULT = 16 (для 50 МГц).

 

В файле example_top.ucf выставляем работу от тактового сигнала 50 МГц(20нс) за место 3 нс.

NET "memc3_infrastructure_inst/sys_clk_ibufg" TNM_NET = "SYS_CLK3";
TIMESPEC "TS_SYS_CLK3" = PERIOD "SYS_CLK3"  20  ns HIGH 50 %;

 

Сброс контроллера MCB.

 

Контроллеру MCB перед работой обязательно нужно сделать RESET.

По умолчанию в проекте созданным при помощи CORE Generator, reset это внешний входной сигнал,

но в данной реализации будет создан модуль отвечающий за reset внутри проекта.

Принцип работы следующий.

После того как будет подан сброс, PLL находящаяся в infrastructure.v(module infrastructure) будет

сброшена и начнет перезапуск.

PLL после стабилизации выдаст сигнал наличия достоверного клока(pll_lock) и подаст ресет на

MCB(модуль memc_wrapper).

MCB выждет время необходимое для стабилизации тактового сигнала, затем запустит процесс

калибровки, т.е определение местоположения данных относительно тактового сигнала.

Затем MCB выставит сигнал готовности (calib_done=1).

После этого можно начинать обмен с контроллером памяти.

 

 Тестер памяти.

 

Добавляем в examle_top.v модуль управления светодиодом, тестер памяти и модули вывода в uart

консоль.

 

 

Моделирование работы MCB+DDR3.

 

Моделирование будет производится при помощи симулятора ModelSim(или QuestaSim). 

ВНИМАНИЕ: Симулятор устанавливается отдельно.

В директории C:\PRJ\my_ddr3_mcb\mig_39_2_ddr3\example_design\sim\functional\

создаем командный файл для быстрого запуска симуляции run_questasim.cmd со следующим

содержимым:

set XILINX=C:\Xilinx\14.7\ISE_DS\ISE
C:\questasim64_10.4\win64\vsim.exe -do sim.do

Первая строка прописывает переменную окружения XILINX необходимую для работы ModelSim.

Вторая строка производит запуск симулятора, где все команды для симулятора заданны в файле sim.do

 

ВНИМАНИЕ: Симулятор может потребовать наличия откомпилированных библиотек от XILINX.

Процесс компиляции библиотек описан в Компиляция библиотек Xilinx(ISE) для ModemSim(QuestaSim).

 

Затем необходимо подправить test bench

(C:\PRJ\my_ddr3_mcb\mig_39_2_ddr3\example_design\sim\functional\sim_tb_top.v)

Удаляются не используемые сигналы и добавляются новые (светодиод, выход uart консоли, убираем

ресет и т.д.). 

Задается источник и частота входного тактового сигнала.

Подключается микросхема памяти DDR3 к test bench, по умолчанию она не подключена.

// ========================================================================== //
// Memory model instances                                                     // 
// ========================================================================== //
ddr3_model_c3 DDR3_CHIP (
    .rst_n     (mcb3_dram_reset_n),
    .ck        (mcb3_dram_ck),
    .ck_n      (mcb3_dram_ck_n),
    .cke       (mcb3_dram_cke),
    .cs_n      (1'b0),
    .ras_n     (mcb3_dram_ras_n),
    .cas_n     (mcb3_dram_cas_n),
    .we_n      (mcb3_dram_we_n),
    .dm_tdqs   ( {mcb3_dram_udm, mcb3_dram_dm} ),
    .ba        (mcb3_dram_ba),
    .addr      (mcb3_dram_a),
    .dq        (mcb3_dram_dq),
    .dqs       ( {mcb3_dram_udqs ,mcb3_dram_dqs}),
    .dqs_n     ( {mcb3_dram_udqs_n ,mcb3_dram_dqs_n}),
    .tdqs_n    (),
    .odt       (mcb3_dram_odt)
);

 

Сама модель памяти находится тут же в файлах ddr3_model_c3.v и ddr3_model_parameters_c3.vh 

В ddr3_model_c3.v можно задать вариант таймингов (последнии цифры скорости в наименовании

микросхемы, хотя для 300-400 МГц это не критично). Также можно включить более подробный вывод

отладочной информации от самой микросхемы памяти в ddr3_model_parameters_c3.vh 

parameter DEBUG = 0;//1; // Turn on Debug messages

 

Теперь можно запускать симуляцию памяти.

Для этого достаточно запустить скрипт:

C:\PRJ\my_ddr3_mcb\mig_39_2_ddr3\example_design\sim\functional\run_questasim.cmd

 

 


 

Загрузка проекта в плату.

 

Во время работы тест выводит результат работы на светодиоды и консоль(COM port).

 

Подключаем плату к источнику питания, программатору, ПК.

На плате установлен конвертер интерфейса USB-to-COM CP2102.

При подключении платы к ПК появится COMxx - port.

На ПК запускаем программу терминал и производим подключение к COMxx порту платы,

с параметрами 115200 8N1.

 

Подаем питание на плату.

Запускаем скрипт для программирования:

prog_ram.cmd - для программирования без записи в конфигурационную flash.

prog_spi.cmd - для программирования конфигурационной flash памяти (на плате установлена

SPI Flash M25P80).

Скрипты расположены тут: xilinx_ddr3_mem_test/ise_14.7/par/prog

Описание работы скриптов находиться в статье FPGA: Xilinx Рекомендации советы.

 

 

Во время работы теста светодиод LED3 будет мигать.

В результате работы теста в консоль будет выведена строка TEST:

После того как тест завершит работу, в консоль будет выведена строка:

PASS OK - если ошибок нет (при этом светодиод LED3 погаснет),

ERROR - если были обнаружены ошибки (при этом светодиод LED3 будет светиться).

 

Пример успешного завершения теста памяти.

TEST: 
PASS OK

 

Пример завершения теста с ошибкой.

TEST: 
0x040BF360 0xAAAAAAAA 0xAAAAAABA
ERROR

 

 

Исходники проекта  GitHub: xilinx_ddr3_mem_test.