20 июля 2015 г.

Плис (FPGA) с чего начать? Altera / Vhdl / Quartus II / ModelSim

Как начать программировать Плис / FPGA / CPLD? Как установить Quartus II / ModelSim ? И как с ними работать?

В этой статье я расскажу, как начать разрабатывать проекты на Quartus II, как промоделировать написанную на VHDL программу с помощью ModelSim и как залить это в отладочну плату.

На хабре есть хорошая статья обьясняющая чем ПЛИС хороша, как выбрать производителя, язык и почему любой, кто задумывался научиться работать с FPGA / CPLD должен уже бежать покупать отладочную плату.

В начале нужно выбрать производителя, обычно выбирают между Xilinx / Altera. Я выбрал фирму Altera по нескольким причинам:
  • Jeri Ellsworth использует Altera
  • Quartus II - IDE от Altera, дружелюбнее и интуитивно понятнее чем IDE от Xilinx
  • Мне легче выговорить Altera, чем Xilinx
  • Само название мне нравится больше
Затем я решил изучать VHDL т.к.:
  • David L. Jones хорошо отзывался о VHDL
  • в моём институте преподают VHDL (я начал изучать до этого курса)
Из того что я вычитал в интернете, я сделал несколько выводов: 
(всё это лично моё полученное в тот момент мнение и может отличаться от действительности)
  • В Verilogе можно "выстрелить себе в ногу",
  • VHDL немного сложнее на первых порах и он не похож на СИ в отличие от Verilog,
  • В VHDL нужно выполнять больше лишних телодвижений (писать строчек кода), но это оплачивается тем что ты прекрасно понимаешь что и где у тебя происходит.
  • Также встречалось сравнение как VHDL = Assembler, Verilog = C.
После того как я выбрал Altera и VHDL, следующим действием было: купить отладочную плату. Есть отличные отладочные комплекты, которые можно купить с главного сайта Altera, они богаты периферией, но стоят для бедного студента не дёшево.

Рис.1 Altera DE0 board
Многие так и начинают, к тому же вместе с платой ты получаешь пошаговую инструкцию начала работы, вместе с несколькими расписанными проектами. Но я не хотел тратить 80$
В итоге я пошёл на ebay, Нужно купить программатор USB Blaster:

Рис.2 Программатор
И саму отладочную плату. Желательно выбирать с большим количеством периферии, но обязательно  чтоб там был вход AS и кварц, дальше по желанию и капиталу: светодиоды, кнопки, VGA разьём, 2 PS/2 разьёма (мышка и клавиатура).
Я выбрал плату за ≈ 35$

Рис.3 FPGA Cyclone Altera EP1C3T144 Learning Board
Как видно слева есть 2 входа для программатора JTAG и AS. JTAG используется для отладки, через него можно запрограммировать Плис напрямую, но после выключения питания прошивка стирается.
Через AS - Active Serial мы программируем чип flash памяти, который будет хранить прошивку при отсутствии питания, каждый раз при включении питания ПЛИС считывает из него данные и конфигурируется для корректной работы.

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

Рис.4 Сокет для микросхемы
После того как мы получили плату и программатор, следует установить необходимое ПО. Нам нужен Quartus II для написания программ и прошивки отладочного комплекта. Нужно выбрать Web Edition, т.к. это бесплатная версия, затем выбирать нужную версию Quartus исходя из устройства (Device), к примеру, у меня Cyclone I, последняя версия, которая мне подойдёт это 11.0.

Рис.5 Выбор версий Quartus II
Теперь нам нужен ModelSim Altera Starter, Starter означает бесплатная версия, он нам нужен той же версии что и Quartus, если такой нет, можно выбрать больше.

Рис.6 Загрузка ModelSim
После того как это скачали, устанавливаем сперва Qurtus II, затем ModelSim следует установить в ту же папку, если вы не меняете место установки, то всё будет правильно по умолчанию.

После запуска Quartus II появится окошко предлагающее создать новый проект:

Рис.7 Окно приветствия Quartus.II
Нажимаем создать проект, если вдруг окна нет, или вы его отключили, то создать новый проект можно через File -> New Project Wizard...

Рис.8 Создание нового проекта
После этого появится окно создания нового проекта:

Рис.9 Создание проекта окно приветствия
 здесь просто нажимаем Next.

Далее идёт окно выбора рабочей папки и имени проекта.

Рис.10 Создание проекта окно N 1
Выбираем папку где будет храниться наш проект и как он будет называться. Также тут нужно выбрать имя "top-level design entity", можно сказать, что это имя "объекта" с которым мы будем работать, можно назвать его просто "test", когда будем писать код стает понятно, что это значит.

Жмём Next, перед нами окно добавления файлов:

Рис.11 Создание проекта окно N 2
Жмём Next, теперь нам нужно выбрать модель нашей микросхемы:

Рис.12 Создание проекта окно N 3
После этого жмём Next, теперь перед нами окно выбора ПО для моделирования и различных проверок, можно всё оставить по умолчанию и нажать Next.

Рис.13 Создание проекта окно N 4

Наконец финальное окно, показывающее, что же мы выбрали, нажимаем Finish

Рис.14 Создание проекта окно N 5
Перед нами открывается рабочая область Quartus II с нашим открытым проектом:

Рис.15 Открытый проект Quartus II
Но здесь пока ничего нет, нужно создать VHDL файл:
File -> New (CTRL + N)

Рис.16 Создаём новый файл
 Перед нами появится окно выбора файла, который мы хотим создать, выбираем "VHDL File"

Рис.17 Окно выбора формата нового файла
Нажимаем OK, создастся файл Vhdl1.vhd, в принципе всё равно как он называется, но если хочется его переименовать это можно сделать через File -> Save as. Также после того как мы скомпилируем файл Quartus предложит нам выбрать папку куда его следует сохранить, в том же окне его можно переименовать.

Теперь попробуем скомпилировать тестовый код. Заставим загораться светодиод при нажатии кнопки.
Код можно взять здесь.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity test is

    Port ( button  : in  std_logic;
           LED     : out std_logic);
     
end test;

architecture Behavioral of test is

begin

 LED <= button;
 
end Behavioral;

Вначале мы подключаем необходимые нам библиотеки (строки 1-3).
Далее мы создаём "объект" под названием которое мы выбрали в в первом окне при создании проекта (Рис.9). В объекте мы описываем его внешние выводы, в данном случае они идут на светодиод и на кнопку которые находятся вне микросхемы (строки 7-8).

С кнопки мы будем снимать значения, поэтому пишем "in", на светодиод будем выдавать значение, значит, пишем "out".

std_logic означает логическое значение, в данном случае нам нужно или лог.0 или лог.1.

В 12 строке мы описываем, что происходит внутри нашего объекта, там мы просто выдаём на светодиод значение, полученное с кнопки. Вместо "Behavioral" может быть любое слово, "test" это имя нашего объекта.

Попробуем скомпилировать наш код. Для этого нужно нажать на roccessing -> Start Compilation (Ctrl + L) либо эта же фиолетовая стрелка есть на нашем рабочем окне:

Рис.18 Компилирование проекта

Не должно быть никаких ошибок. После компиляции вылезет окно с отчётом:

Рис.19 Отчёт компиляции
Здесь показано, сколько использовано логических элементов, ножек и ячеек памяти.

Если мы сейчас зальём нашу готовую прошивку в Плис, то какую кнопку нужно нажимать и какой светодиод загорится? Мы ведь нигде не обозначали это...

После компиляции нужно обозначить какая ножка микросхемы соответствует какому "выводу" объекта. Для этого нужно нажать Assignments -> Pin Planner (Ctrl+Shift+N), либо на эту же иконку на рабочем окне:

Рис.20 Выбор иструмента Pin planner
После нажатия вылезет окно, в котором можно распределить выводы микросхемы:

Рис.21 Инструмент Pin planner
Как видно здесь уже есть 2 наших вывода, осталось указать к каким ножкам они подсоединяются. Это можно определить с помощью даташита либо другой документации которая имеется на данную плату.

Для того чтобы выбрать ножку, нужно дважды нажать на поле в колонке "Location", после чего появится меню выбора соответствующей ножки для данного сигнала/вывода. В моём случае я выбрал PIN 67 для кнопки и PIN 57 для светодиода.

Рис.22 Выбор ножки
После выбора ножек это окно можно просто закрыть, оно автоматически сохранит выбранные значения. Теперь нужно ещё раз скомпилировать проект.

После этого можно посмотреть, как выглядит наша схема на уровне регистров. Это можно сделать, нажав Tools -> Netlist Viewer -> RTL Viewer, либо дважды щёлкнув на него слева в окне задач "Tasks"

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

Рис.24 Структурная схема нашего кода

Теперь можно проверить работу схемы в симуляторе ModelSim, откроем его.
Можно не обращать внимания на все открытые окна, сейчас на нужно создать новый проект через File -> New Project.

Рис.25 Создание нового проекта для моделирования
Появится окно создания проекта:

Рис.26 Создание нового проекта для моделирования

Название проекта, его местонахождение и название стандартной библиотеки можно выставить любые, это не на что не повлияет. Я обычно выставляю ту же папку в котором находится мой проект Quartus.

После этого появится окно, предлагающее нам добавить файлы:

Рис.27 Окно добавления файлов
Нужно нажать "Add Existing File" выбрать наш Vhdl1.vhd, ничего больше не меняя нажать Close.
После чего откроется окно нашего проекта с добавленным нами файлом:

Рис.28 Наш проект
В колонке Status стоит вопросительный знак, это обозначает, что файл необходимо скомпилировать, прежде чем мы сможем с ним работать.

Нужно нажать Compile -> Compile ALL (или Compile Selected если нужен только 1 файл).
Либо нажать на файл правой кнопкой мыши -> Compile -> Compile Selected (или ALL)

Рис.29 Компиляция проекта
После этого вопросительный знак должен измениться на зелёную галочку. Теперь мы можем начать симуляцию. Нажмём Simulate -> Start Simulation (ALT+S ... S)

Рис.30 Начало симуляции
После этого появится окно выбора библиотеки, файлов и объектов для симуляции, нужно найти наш файл. В моём случае файл "Vhdl1.vhd" находится в библиотеке "work", в файле мы создали объект "test":

Рис.31 Окно выбора файла для симуляции
Выбираем файл и жмём ОК, появится окно симуляции.
В левом окне есть созданные нами в коде объекты, у нас только 1 объект "test", у которого есть 2 внешних сигнала: кнопка и светодиод, нужно проверить, как светодиод будет реагировать на изменение состояния кнопки, для этого необходимо их добавить в окно сигналов (Wave).

Т.к. мы используем все сигналы, можно нажать правой кнопкой на объект -> Add -> To Wave -> All items in region.
В последнем окне можно выбрать любой из 3 вариантов. То же самое можно сделать в выпадающем сверху меню "Add"

Рис.32 Добавляем все сигналы из объекта
Если нам нужны только некоторые из возможных сигналов то их можно выбрать в соседнем окне "Objects", зажав Ctrl можно выделить необходимые сигналы, после чего таким же образом как раньше добавляем их в окно сигналов.

Рис.33 Выборочно добавляем сигналы
После этого должно открыться окно сигналов (Wave),  если оно не появилось его можно открыть нажав Wave в центре экрана:

Рис.34 Открываем окно с сигналами
Если его там нет, его можно добавить через View -> Wave.

Теперь у нас должно быть открыто окно Wave в котором есть 2 добавленных нами сигнала:

Рис.35 Окно с сигналами для симуляции
Нам нужно проверить, что будет происходить со светодиодом при нажатии кнопки. ModelSim не может работать в режиме рального времени, нам нужно задать сигналы, выбрать продолжительность симуляции, запустить её, затем посмотреть полученный результат.

Для симуляции нам понадобится 3 элемента из окошек в рабочей области:

Рис.36 Часть рабочей области с выделенными элементами для симуляции
Слева направо: "Restart" - перезапуск симуляции, "100 ps" - окно с выбором времени симуляции, "Run" - запуск симуляции.

100 пс нам вполне хватит, попробуем запустить симуляцию нажав "Run".
В результате получим такой результат:

Рис.37 Результат симуляции
Как видим появились 2 красные линии напротив наших сигналов, в колонке "Msgs" - показывается значение сигнала, в нашем случае оба сигнала "выдают" U.

U обозначает "Uninitialized" - не инициализован, этот сигнал ещё не принимал никакое значение, на выводе Плис может быть случайное значение. Давайте зададим кнопке лог. 0, что будет означать что кнопка не нажата.

Это можно сделать нажав правой кнопкой на сигнал -> Force...

Рис.38 Выставляем значение на сигнал
Либо через выпадающее меню, Wave -> Force...

Рис.39 Выставляем значение на сигнал
После нажатия на Force появится окно выставления значения:

Рис.40 Окно изменения значения сигнала
Здесь есть несколько вариантов для изменения сигнала, нам нужно в окно "Value" записать 0 и затем нажать ок, подробнее об остальных вариантах можно узнать здесь и здесь, нам сейчас хватит Freeze:

Freeze - намертво изменяет значение до тех пор пока мы не нажмём "No Force" которое находилось в выпадающем меню под "Force", либо пока не закончится время выставленное в строке "Cancel After"

"Delay For" - через какой промежуток времени сигнал примет выставленное нами значение.

Записываем 0, нажимаем ОК, Ещё раз жмём Run.

Рис.40 Результат 2 симуляции
Как видим состояние сигналов изменилось, вместо красного цвета они теперь зелёные, также от середины они опустились до низа, можно нажать на сигналы курсором и убедиться что там лог. 0:

Рис.41 Результат 2 симуляции с курсором
Сделаем так чтобы кнопка сама изменяла своё состояние каждые 50 пс, таким же способом выставляются синхросигналы в симуляции которые берутся с выхода кварца.

Для этого вместо Force нужно нажать "Clock...",  появится окно Define clock:

Рис.42 Окно выбора параметров синхросигнала
Рассмотрим, что здесь есть:

Offset - через какое время начнётся наш импульс
Duty - скважность в процентах, отношение отношение длины импульса к периоду, в нашем случае 50% = пол периода высокий уровень, пол периода низкий.
Period - период сигнала в пс.
Cancel - через какое время отключить наш синхросигнал.
Рис.42 Обьяснение параметров
Нам не нужно ничего менять и мы можем просто нажать ОК.
Теперь изменим время симуляции со 100 пс до 300 пс  (рис. 36), чтобы увидеть, что светодиод всегда повторяет состояние кнопки.

Рис.43 Финальный результат
В итоге мы убедились, что наш код работает правильно, теперь осталось залить его в микросхему.

Возвращаемся в Quartus II, если вы его закрыли, то при открытии проекта может сразу не открыться наш файл Vhdl1.vhd.

Чтобы видеть все файлы нашего проекта нужно нажать View -> Utility Windows -> Project Navigator.

Рис.43 Открываем Project Navigator
Появится окно содержащие иерархию наших объектов, файлы и созданные элементы:

Рис.43 Project Navigator
Можно кликнуть 2 раза на test и откроется наш файл.

Мы его уже скомпилировали и соединили сигналы с внешними ножками микросхемы. Теперь осталось его только залить в Плис. Сперва нужно открыть окно программатора, для этого нажимаем Tools -> Programmer, либо на его иконку в рабочей области:

Рис.44 Открываем Programmer
В результате появляется окно программатора:

Рис.45 Окно Programmer
Здесь уже может быть всё выставлено, но я покажу, что нужно сделать, если нам нужно выбрать чем программировать, что и как.

В выпадающем меню Mode выберем JTAG, как я говорил в данном случае прошивка пропадёт при отключении питания, но нам это сейчас не важно.

Нам нужно добавить нашу микросхему, для этого жмём Add Device.
Появляется окно выбора устройства, выбираем наше:

Рис.46 Окно выбора устройства
Жмём ОК. Теперь наше устройство должно появиться в окне программатора:

Рис.47 Окно программатора с нашей микросхемой
Теперь следует добавить файл с прошивкой, для этого жмём на строку с нашим устройством (    EP1C3T144     0000000000   ) чтобы выбрать его. 

Затем нажимаем Add File, после чего должна открыться корневая папка нашего проекта, в котом ым можем выбрать 1 из 2 файлов .sof или .pof.

Согласно документации, .pof нужны для CPLD и Flash памяти, .sof  для FPGA. Значит, выбираем последний.

Поставим галочку в строке с нашим устройством в колонке "Programm / Configure".

Теперь нужно настроить программатор, подключаем USB Blaster к компьютеру, Если Windows не сможет сам установить для него драйвер, потребуется установить его вручную. Подробная инструкция здесь, драйвера находятся в папке:
<Папка с Quartus II>\drivers\usb-blaster

После того как компьютер опознал USB Blaster, возвращаемся к окну программатора и нажимаем Hardware Setup.

В открывшемся окне под надписью "Available hardware items" должен быть Usb Blaster:

Рис.47 Окно настройки программатора
В выпадающем меню "Currently selected hardware" выбираем Usb-Blaster и нажимаем Close.

Теперь подключаем Usb Blaster к нашей отладочной плате в разъём JTAG, включаем питание и в окне "Programmer" жмём Start.

Наконец плата запрограммирована, для того чтобы прошивка не пропала после выключения питания в выпадающем меню Mode в окне "Programmer" нужно выбрать Active Serial Programming вместо JTAG, использовать .pof файл и подключить USB Blaster в разъём AS.

Заключение


На этом всё, теперь можно изучать выбранный вами язык и делать проекты, Лучше писать код и обращаться к книгам за помощью, чем забить голову ненужной информацией прочитав несколько книг, но не написав и строки кода.

Отличный курс для Xilinix / VHDL есть здесь. Тут можно начать с изучения VHDL, не так важно какой производитель ведь код один и тот же. Здесь шаг за шагом рассматриваются основные составляющие языка на примерах со светодиодами и кнопками.

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

  • Начинающие на плис обычно идут по одному пути:
Светодиоды, кнопки, кварц, VGA, PS/2 (клавиатура мышка).

  • Несколько интересных проектов:
Светодиоды, кнопки, кварц, заставить светодиоды мигать с определённой частотой, сделать небольшой калькулятор, 7-ми сегментные индикаторы.

вывод изображения на VGA или телевизор, терминал, вывод изображений, небольшие видео игры как Pong, HDMI, работа с любыми дисплеями, обработка видео данных, камера.

Музыкальные шкатулки, ШИМ, ЦАП, АЦП, цифровой микрофон, обработка звука, распознавание и синтезирование речи.

Делаем свой процессор и его части, RAM, ROM, ALU, в книгах можно найти примеры реализаций готовых процессоров.

Финальные проекты студентов Корнелльского университета: здесь.

Литература

Мои любимые книги:
  • Circuit Design and Simulation with VHDL   -   Отличный справочник VHDL
  • Rapid Prototyping of Digital Systems            -   Много практики и примеров с кодом

Книги которые советуют:
  • Digital Design with CPLD Applications and VHDL   -   Схема к каждому коду
  • Hdl Chip Design   -  её называют просто "Синяя книга"
  • The designer guide to vhdl
Если интересна история FPGA / CPLD, кто и как их создавал, какие технологии использовались и как они вообще работают, то рекомендую эту книгу:
  • Проектирование на ПЛИС. Курс молодого бойца


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

Источники:
altera.com
pldworld.com


1 комментарий :

  1. Здравствуйте, попробовал на вашем примере назначить пины,все ок. Но в своем примере такие ошибки: Error: Can't pack LABs, Error: Can't place node "..." of type max_io, Error: Can't find fit. Не знаете ли Вы с чем это может быть связано?

    ОтветитьУдалить