Настраиваем и запускаем Nios II в Intel Quartus Prime 18.0

В статье будет рассмотрен весь процесс от создания проекта с синтезируемым процессором Nios II до запуска прошивки на нём в ПЛИС, а также описаны возможные проблемы, возникающие в процессе, и способ их решения. Получившийся проект доступен для свободного скачивания (под Cyclone 10 LP) и любой может повторить все описанные ниже действия как самостоятельно с нуля, так и подсмотрев в проекте.

Здесь не будет рассмотрен процесс создания файла прошивки для конфигурационной памяти (для автономного запуска проекта), т. к. статья и так вышла довольно объемной и логично будет эту часть отделить.

Статья будет полезна новичкам, осваивающим ПЛИСы, и если вас заинтересовало, добро пожаловать под кат:

B65-0

Создание проекта

Итак, создаём новый проект с нуля, выбираем 10CL025YU256I7G, стоящую на Intel Cyclone 10 LP FPGA Evaluation Kit (или любую другую, которая на вашей плате, это не принципиально):

B65-1

Настройки EDA я не трогаю и можно всё оставить по умолчанию, т. к. никакой симуляции нам тут не потребуется (пока что):

B65-2

Сохраняем проект куда душе угодно и приступаем к его наполнению.

Простой тест работоспособности на Verilog

Итак, нам понадобится добавить в проект 3 файла. Первый — C10LP_TOP.v :

module C10LP_TOP
(
// Тактирование
input SYS_CLK50M,

// Пользовательское управление
input [3:0] USER_PB,
output [3:0] USER_LED
);

wire reset;

assign USER_LED = USER_PB;

debouncer db
(
.in(USER_PB[0]),
.clock(SYS_CLK50M),
.out(reset)
);

endmodule

Это будет ТОП-файл, который сейчас выполняет просто отображение нажатия кнопок на светодиодах.

Можно заметить, что в ТОП-файле выше используется фильтр для одной из кнопок — логично, что он будет в файле debouncer.v:

module debouncer
(
input wire in,
input wire clock,
output reg out
);

reg [7:0] shiftreg;

initial begin
shiftreg=8'hFF;
out=1'b0;
end

always @ (posedge clock)
begin
shiftreg[7:0] <= {shiftreg[6:0], in};
if (shiftreg[7:0] == 8'b00000000)
begin
out <= 1'b1;
end
else if (shiftreg[7:0] == 8'b11111111)
begin
out <= 1'b0;
end
else
begin
out <= out;
end
end

endmodule

Это нам понадобится для формирования четкого сигнала сброса для процессора, без дребезга.

И последний файл — C10LP_TOP.sdc:

#**************************************************************
# Time Information
#**************************************************************

set_time_format -unit ns -decimal_places 3

#**************************************************************
# Create Clocks
#**************************************************************

create_clock -name clock_50M -period "50 MHz" [get_ports {SYS_CLK50M}]

Этот файл необходим для Timing Analizer, для которого мы здесь описываем, какой сигнал у нас тактирующий и какую частоту он имеет. По факту в статье Timing Analizer не будет рассмотрен, потому что проект крайне простой, но в дальнейшем это пригодится. Да, этот файл должен называться аналогично ТОП-файлу, иначе не будет автоматом подхвачен при компиляции и анализе!

Примечание: В окошке создания новых файлов он находится в самом низу:

B65-3

Итак, добавили 3 файла, теперь можно сделать черновую компиляцию — вызываем только анализ и синтез:

B65-4

Да, перед этим не забываем назначить ТОП-файл:

B65-5

Примечание: Если проект новый, то стоит зайти в настройки:

B65-6

И указать использование всех доступных ядер процессора для компиляции — это положительно повлияет на время компиляции проекта:

B65-7

После успешного анализа, если нет ошибок, заходим в Pin Planer и видим все пины ввода-вывода:

B65-8

Назначаем их в соответствии со схемой на отладочную плату:

B65-9

Теперь компилируем проект полностью и заливаем прошивку в плату. Результат должен быть вот такой:

B65-10

Всё работает, можно закрывать Quartus…

Дальше мы уже пойдем по модулям собирать наш процессор.

Осваиваем Platform Designer

Запускаем Platform Designer (или в старых версиях Quartus это был Qsys):

B65-11

Перед нами предстаёт почти пустое окно с единственным IP — источником тактового сигнала и сброса:

B65-12

Двойной клик на нём, в свойствах устанавливаем частоту источника (осциллятора, если сигнал будет взят напрямую или PLL), с которого будет всё затактировано:

B65-21

В моём случае это 50 МГц, на плате установлен осциллятор 50 МГц и я просто возьму с него тактирующий сигнал напрямую, для теста этого будет достаточно более чем.

Начинаем добавлять IP, первое, что добавим, собственно, ядро процессора — Nios II Processor:

B65-13

Выбираем Economy вариант, т. к. он бесплатный и не требует лицензии. Правда, фарша у него кот наплакал, но ничего не поделать без лицензии.

В настройках из важных моментов — расположение векторов памяти:

B65-14

Векторы должны указывать на реальные блоки RAM памяти, нужно не забыть сменить их в выпадающих списках.

Также в настройках не стоит отключать JTAG Debug, иначе банально залить прошивку не сможете:

B65-15

Следующее IP, которое будем добавлять, — On-Chip Memory (RAM or ROM):

B65-16

Здесь все можно оставить по умолчанию (выбрана RAM), сменив только размер RAM на 32768 (32 Кб) — с большим запасом хватит на тестирование процессора.

Далее добавляем PIO (Parallel I/O) IP:

B65-17

Выставляем количество выводов = 4, т. к. у нас всего пользовательских светодиодов 4 шт., и устанавливаем их выходами.

Далее уже парочка не обязательных, но крайне рекомендуемых к добавлению IP, первое — это JTAG UART:

B65-18

Это IP поможет просматривать любые сообщения из printf в консоли Eclipce без дополнительных USB-UART.

Второе рекомендуемое IP — System ID Peripheral:

B65-19

Это IP позволяет задать уникальный идентификатор (ID) для процессора в нашем проекте, чтобы случайным образом не прошить не то, что надо, в другую плату. Это поначалу кажется избыточным, но лучше к такому привыкать сразу — позволяет избежать возможных проблем в будущем. Здесь выставляем ID = 0x12345678 (или любой другой, который хочется).

Итак, мы добавили все необходимые IP модули, и окно сообщений теперь пестрит красным — кучи ошибок:

B65-20

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

B65-22

Примечание: Также для PIO модуля я задал экспортное имя «GPIO» в колонке Export, чтобы при генерации ТОП-файла процессора было более осмысленное обозначение этих выводов.

Вот, уже лучше, но не всё. Прочитав сообщения ошибок, можно видеть, что большинство из них — это ошибки адресов добавленной периферии, они накладываются. Исправить это можно автоматически, вызвав пункт в меню:

B65-23

Или вручную, расставив Base адреса:

B65-24

Почти всё! Нажимаем Generate HDL…:

B65-25

Появляется окно с настройками генерации, я убрал создание графического символа, т. к. я его не использую (на удивление почти во всех мануалах подключают процессор именно через графический символ — зачем, для меня загадка) и поменял имя папки, куда будет сгенерирован процессор, на «nios2»:

B65-26

Перед генерацией первый раз спрашивается, куда сохранить настройки Platform Designer:

B65-27

После чего будет «первый проход»:

B65-28

И потом генерация, но она завершилась с предупреждением:

B65-29

Смотрим, что за предупреждение:

B65-30

Мда, забыл подключить выход прерывания JTAG UART — исправляем:

B65-31

Генерируем:

B65-32

Всё успешно! После закрытия окна будет выведена напоминалка, что вам необходимо вручную добавить сгенерированный файл nios2\synthesis\nios2.qip в проект:

B65-33

Добавляем синтезированный Nios II в проект

Ну что же, половина пути уже пройдена! :) Добавляем сгенерированный файл nios2.qip в проект так же, как обычный исходник на Verilog:

B65-34

Но он раскрываемый, если посмотреть, что он за собой притягивает, то видно все синтезированные IP, что мы добавили:

B65-35

Здесь нас интересует только файл nios2.v — он является ТОП-файлом процессора. Открываем его:

B65-36

И здесь мы видим в оглавлении модуля сигналы, которые необходимо подключить в своём проекте (тактирование, сброс и шина PIO).

Открываем ТОП-файл проекта, создаём экземпляр процессора и подключаем к нему, собственно, тактирование (осциллятор на 50 МГц, частоту которого я и указывал в IP из Platform Designer, а также в C10LP_TOP.sdc файле), сигнал сброса от кнопки (для которого и используется подавитель дребезга из файла debouncer.v) и шина пользовательских светодиодов (кнопки не используются, были добавлены для теста вначале). Выглядит ТОП-файл проекта теперь вот так:

B65-37

Компилируем. Всё успешно:

B65-38

Занимает проект вполне немного — 7% логических элементов, а вот памяти… 45% — это уже ощутимо. А всё из-за того, что Cyclone 10 LP — бюджетная серия и тут в принципе памяти довольно мало, по сравнению с тем же MAX 10.

Руки чешутся наверное уже. :) Прошиваем:

B65-39

Просто горят. Не густо, но так должно быть, ведь у нас прошивки-то у процессора еще никакой нет…

Осваиваем Nios II Software Build Tools for Eclipse

Ну а теперь окунаемся в использование IDE для богов (нет) — Eclipce. А то, что она то подвисает, то залипает по непонятным причинам или на вполне ровном месте — это мелочи… стартуем:

B65-40

Eclipse спросит, где расположить workspace (настройки IDE и т. д.), можно, к примеру, сделать папку рядом с Quartus’ом и поставить галку, чтобы больше не спрашивал (тут как вам удобнее):

B65-41

И перед нами возникает эта «божественная IDE»:

B65-42

Создаем проект (точнее их будет 2 — проект собственно прошивки и проект BSP — Board Support Package, который генерируется на основе выбранных IP) из шаблона:

B65-43

В появившемся окне указываем имя проекта (Firmware), выбираем файл настроек nios2.sopcinfo для Platform Designer, с которого прочитаются настройки, и выбираем шаблон Blank Project (в принципе можно и Hello World, для теста особой разницы нет):

B65-44

Далее можно ничего не менять:

B65-45

Примечание: не редкость, у вас на этом шаге может появится следующее окно:

B65-46

Оно может возникать по вполне очевидным ошибкам, о которых можно прочитать в окне лога. К примеру, у меня там было следующее сообщение:

SEVERE: .entry section mapping not created because reset memory region not located at base address: 0xffffffffffffffff

Которое говорит нам о том, что я забыл сменить векторы памяти процессора с дефолтных на реальную RAM, IP которой добавил позже. Вот правильный выбор векторов памяти:

B65-47

А что можно выбрать в выпадающем списке:

B65-48

Стоило просто сменить оба вектора на onchip_memory2_0.s1 и заново сгенерировать проект процессора в Platform Designer, как оба проекта прошивки для Nios II сгенерировались успешно.

Иногда для решения этой ошибки нужно запускать IDE от администратора, это в основном касается тех, кто работает на Windows 7, или же почистить все сгенерированные папки проекта Quartus и заново скомпилировать всё.

Вот и сгенерировались два проекта:

B65-49

Окей. Идём в свойства проекта Firmware_bsb и открываем свойства BSP:

B65-50

Странно. Всё серое… тупо ждём 5-10 секунд, ничего не делаем.

B65-66

Вуаля и всё доступно к редактированию:

B65-51

Здесь для начала стоит убрать поддержку С++, если она вам не нужна, и указать использование Small C Library (правда, это, к примеру, убирает возможность выводить float в printf) — это очень ощутимо сбрасывает объём скомпилированной прошивки.

B65-52

Далее открываем BSP Editor:

B65-53

Здесь редактируем ввод\вывод, выбираем jtag_uart_* для взаимодействия с консолью Eclipse во время отладки:

B65-54

Остальные настройки можно не трогать. Нажимаем Generate. После чего компилируем bsp проект:

B65-55

Успешно:

B65-56

Теперь переходим к основному проекту, который, собственно, и будет прошивкой. Если был выбран ранее шаблон Blank Project, то он будет пустой. Создаём файл main.c со следующим содержимым:

#include "system.h"
#include "altera_avalon_pio_regs.h"
#include 

int main ()
{
unsigned int leds = 0x1;
unsigned int i = 0;

printf("Hello\n");

while(1)
{
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, leds);
for (i=0; i<(ALT_CPU_CPU_FREQ/500); i++); // небольшая задержка
leds = ((leds3) & 0x1); // код Джонсона
}
return 0;
}

Здесь стоит отметить, что обращение к портам PIO происходит по адресу PIO_0_BASE, объявленному в system.h, который, в свою очередь, и генерируется на основе выбранных модулей и их заданной адресации в Platform Designer. Поэтому никогда не прописывайте в коде магические числа и адреса, прямо зависящие от добавленных IP — всегда пользуйтесь объявлениями из system.h.

Компилируем:

B65-57

Всё ок. Теперь переходим к запуску прошивки на синтезированном процессоре в железе:

B65-58

Перед нами менеджер конфигураций запуска, двойной клик на Nios II Hardware и создаётся экземпляр настроек:

B65-59

Переходим в Targert Connection, здесь должна отображаться подключенная отладочная плата:

B65-60

Но залить прошивку (кнопка Run) менеджер не даёт, в чем дело ? Раз плата нашлась, первое, что делаем — нажимаем на System ID Properties… :

B65-61

Процессор определился! ID сходится, а вот временной штамп работающего в ПЛИС и откомпилированного на данный момент в проекте процессора — нет. Это и есть причина того, что нам не дают залить прошивку. Можно, конечно, поставить две галочки с игнорированием ID\timestamp, но крайне не рекомендую этого делать и привыкать к такой практике, чтобы случайным образом не прошить не то, что надо, в другую плату или долго промучиться, почему прошивка не работает на старом процессоре (к примеру, вы добавили новое IP, проект скомпилировали, а залить в ПЛИС забыли, прошивка же в итоге со старым процессором работать не будет).

Примечание: на этом шаге также может быть такое, что процессор даже не определяется. Причины этого надо смотреть везде, возможно, вы банально забыли дать тактирование процессору, или он в сбросе постоянно (сброс у него нулём!), или в Platform Designer не подключили шину данных или адреса к jtag… И да, если были изменения в Platform Designer и перекомпилировали проект в Quartus, то необходимо заново сгенерировать BSP командой:

B65-62

В моём случае я просто забыл залить новую прошивку в ПЛИС. После обновления всё определилось и совпало с ожидаемыми значениями:

B65-63

Как и стала доступна кнопка Run…

Итог

После заливки прошивки в процессор Eclipse открывает консоль, в которую выводится ожидаемое сообщение:

B65-64

А светодиоды так же ожидаемо переливаются (код Джонсона):

B65-65

На этом всё, в целом настройка и добавление Nios II в свой проект хоть и кажется большим, трудным занятием, всё это скорее нудное, т. к. особых трудностей не должно вызвать и повторяется крайне легко! Главное не спешить и вникать в то, что ты делаешь.

Хоть проект и крайне простой, но надеюсь он даёт краткое представление, что же такое процессор Nios II и как его готовить.

Спасибо, что прочитали до конца! ;)

Ссылки

Реклама

Добавить комментарий

Please log in using one of these methods to post your comment:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход /  Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

Connecting to %s