FPGA. Просто о сложном — Создание проекта в Quartus II. Сравнение VHDL и Verilog
Самыми популярными языками описания цифровой аппаратуры являются VHDL и Verilog. В этой статье я постараюсь сравнить синтаксис двух этих языков на примере «бегущего огонька», архивы проектов будут прикреплены в конце статьи. Для полного понимания описываемых процессов настоятельно рекомендую ознакомиться с предыдущими статьями цикла:
Рассмотрим структуру создаваемого модуля «бегущего огонька», который назовем leds_case. В модуле будет один вход для тактового сигнала clk, и четыре выхода (четырехбитная шина) для светодиодов.

В модуле будет всего два процесса, которые будут выполнятся параллельно друг-другу, синхронно с тактовым сигналом clk. В первом процессе сделаем счетчик, который бы считал равные временные отрезки, через которые происходит переключение с одного светодиода на другой. Во втором процессе реализуем функцию, которая бы включала поочередно светодиоды по истечению определенного промежутка времени заданного счетчиком из первого процесса.
Чтобы не быть голословным, реализуем данный модуль на отладочной плате от ALTERA с CPLD семейства MAX II.

Плата прошивается по JTAG программатором USB BLASTER.

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

Итак, теперь создадим новый проект в среде Quartus II, которую можно скачать на официальном сайте Altera. Запускаем среду, для создания нового проекта кликаем на New Project Wizard (на картинке обведено красным).

В этом окне среда нам сообщает какие операции нужно совершить для создания проекта. Пропускаем.

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

Далее выбираем Empty project, тем самым подтверждаем создание абсолютно чистого проекта.

В следующем диалоговом окне нам предлагают подключить файлы проекта, но так-как нам нечего подключать, то пропустим этот шаг.

В этом диалоговом окне выбираем микросхему, которую мы будем программировать. Выбираем параметры соответствующие микросхеме на нашей плате: семейство MAX II корпус TQFP и количество ножек 100. Немного остановимся на параметре Core Speed grade — это параметр характеризующий время задержки прохождения сигнала между внутренними соединениями в ПЛИС. Проект созданный для ПЛИС со speed grade 5 без проблем заработает на ПЛИС со speed grade 10, но проект созданный для ПЛИС со speed grade 10 не будет адекватно работать, если вообще разведется, на ПЛИС со speed grade 5. Как определить speed grade? Очень просто: в названии микросхемы EPM240T100C5 последняя цифра 5 и есть значение speed grade.

В этом окне среда предлагает нам указать на средства симуляции, в которых мы бы хотели отлаживать код, но т.к. код будет простым, то пропустим этот шаг. Средства симуляции разберем в другой статье.

В этом диалоговом окне среда показывает нам суммарные сведения о выбранных нами настройках.

Для начала напишем модуль на VHDL. Cоздадим VHDL файл. Выберем File -> New

В появившемся окне выбираем VHDL file.

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

// Как видите, никаких библиотек на математику и типы данных мы не подключаем
Как Вы можете убедится оба языка очень похожи и мнение о том, что синтаксис Verilog подобен высокоуровневому языку С сильно преувеличено. Как я и говорил ранее, выбор на чем писать сугубо личный и основан исключительно на популярности языка, так что о том что для читателя является достоинством, а что недостатком я доверю решать самому читателю. А вообще, никто не мешает Вам выучить и Verilog и VHDL. В одном проекте допускается то, что один модуль может быть написан на Verilog, а другой на VHDL. Хочется еще сказать пару слов о переносимости проектов на разные ПЛИС: если Вы не используете специфические ресурсы ПЛИС, такие как аппаратные умножители, множители частоты и т.д., то перенести проект на другую ПЛИС не составит труда. Например наш проект не использует ничего кроме таблиц соответствия и триггеров, и следовательно его можно перенести не только на ПЛИС из другого семейства, но и на ПЛИС другой фирмы!
Раз у нас уже есть прошивка, то самое время научиться прошивать плату и посмотреть на результаты своих трудов, но перед этим давайте сначала синтезируем проект. Для этого кликаем на значок вверху экрана. Должен предупредить сразу, что синтез проекта для ПЛИС требует ресурсов компьютера и занимает долго времени, по сравнению с микроконтроллерами.

После того как синтез проекта выполнится успешно, настало время присвоить портам из модуля реальные пины ПЛИС. Для этого кликнем на значок Pin Planning вверху экрана.

Перед нами откроется изображение нашей микросхемы. Мы видим на какие ножки мы можем «повесить» наши сигналы, но перед тем как это сделать расскажу Вам, что есть три типа пинов: обычные пины входа/выхода, на них можно заводить переферию (у ПЛИС есть несколько банков, куда входят группы пинов), пины тактирования, на них заводится тактовая частота, а еще есть пины сброса (reset) на которые заводится сигнал сброса. У меня на плате нет кнопки reset’а, поэтому эти пины трогать не будем. На PIN_14 нужно завести сигнал clk, чтобы затактировать банк с пинами номер 1. PIN_2, PIN_3, PIN_4, PIN_5 входят в банк пинов номер 1, и следовательно на них «повесим» выходную шину управления светодиодами. После того, как Вы назначили все требуемые пины, просто закройте окно Pin Planner’а, все результаты сохранятся.

После того как мы все правильно присвоили, сделаем синтез и имплементацию проекта нажав на соответствующую иконку вверху экрана.

После успешной сборки проекта откроем утилиту Programmer в верней части экрана, в которой можно прошить нашу ПЛИС.

В появившемся окне Programmera нажмите Hardware Setup, если Ваш программатор не определился автоматически. Драйвера на программатор должны установиться автоматически, но если по каким-то причинам этого не произошло, то их можно найти в папке с установленной средой. Нажмите Add File, чтобы загрузить сгенерированный средой файл прошивки.

Файл прошивки можно найти в папке output_files вашего проекта. Выбираем его.

Далее появится вот такое окошко. Внизу мы можем увидеть, что ПЛИС выбрана правильно. Чтобы запрограммировать нашу ПЛИС ставим галочки Program/Configure и Verify и жмем Start. Если все сделано правильно, то статус-бар Progress станет зеленым и будет отображать 100%.

Добавлю видео работы прошивки, чтобы Вы убедились что все написанное правда, а так же два варианта прошивки: на Verilog и на VHDL. Спасибо за внимание.
Настройка Sublime Text 3 для работы с VHDL файлами
Редактор Sublime Text существенно экономит время при работе с vhdl и verilog файлами. Для тех, кто не работал с редакторами типа Sublime Text, Notepad++ и т.п. опишу основные полезные функции данных редакторов:
- множественное выделение/редактирование строк кода (нажатие средней кнопки мыши или при зажатой клавише Ctrl)
- установка меток (закладок) в коде, помогает ориентироваться в больших файлах. (Ctrl + F2 или через пункт меню Goto→ Bookmarks)
- возможность разделения рабочей области на несколько окон (Alt + Shift + 2 или из меню View→ Layout)
- открытие одного файла несколько раз (File→ New View into File)
- комментирование выделенных строк кода (Ctrl + /)
- поиск и замена (Ctrl + h)
- поиск по всем открытым файлам (Ctrl+Shift+f)
- вставка сниппетов (шаблонов кода) (написать ключевое слово + клавиша Tab)
- написание и использование функций на языке python
- возможность установки различных дополнений
- гибкая настройка
Интеграция Sublime Text
Для начала состыкуем САПР для работы с ПЛИС и редактор Sublime.
-
Интеграция Sublime Text с Xilinx ISE:
в ISE идем в меню Edit → Preferences → Editors: Text Editor → Editor = Custom
Вставляем строку в окно «Command line syntax»:
Плагины
Различные плагины (packages) расширяют функциональность редактора. Packages можно
устанавливать как в онлайн так и оффлайн-режиме.
Для установки плагинов в офлайн-режиме нужно проделать нехитрые манипуляции:
- Скачиваем нужный плагин с GitHub
- Извлекаем из архива
- Переименовываем папку, например, «Sublime-HDL-master» в «Sublime HDL»
- Полученные папки копируем в папку Packages (расположение данной папки легко найти, выбрав в Sublime Text пункт меню Preferences → Browse Packages)
Text Pastry – плагин для автоматической множественной нумерации. Очень помогает при работе с большим количеством нумерованных сигналов/портов.
- Выделяем нужные участки строк
- Вызываем меню Ctrl+Shift+P
- Ищем пункт “Text Pasty Command Line”
- В появившемся окне, расположенном в нижней части экрана, вводим:
- 0 — нумерация от 0
- \i(1,10) — нумерация от 1 с инкрементом 10
- 1 end=4 — нумерация 1, 2, 3, 4, 1, 2, 3, 4 и т.д.
- letters a-c upper — A, B, C, A, B, C, и т.д.
- letters a-c upper x3 — A, A, A, B, B, B, C, C, C и т.д.
- 1 x3 — 1, 1, 1, 2, 2, 2, 3, 3, 3, и т.д.
- x y z — x, y, z, x, y, z, x, y, z, и т.д.
Sublime Verilog — поддержка синтаксиса языка Verilog
Verilog Gadget – набор функций и сниппетов для работы с Verilog файлами.
SmartVHDL — поддержка синтаксиса языка VHDL. Также при наведении на сигнал или порт в коде появится окно с подсказкой о типе (количество бит) данного сигнала/порта. При наведении на сигнал в контекстном меню появится пункт “Goto Definishion” — переход к месту объявления сигнала.
VHDL Mode – набор функций и сниппетов для работы с VHDL файлами. Основная часть функций запускается, например, сочетанием клавиш Atl+K, C, P, где C и P нажимаются поочередно. Основные функции:
- Копирование данных портов (названия портов, типы данных)
- Вставка данных портов как объявление сигналов
- Вставка данных портов как объявление компонента
- Генерация тестбенча по скопированным данным портов
- Автоформатирование кода (выравнивание табуляции и т.п.)
Поддержка ucf файлов
По умолчанию редактор Sublime не у меет работать с ucf-файлами. Разметка ucf эквивалентна разметке языка tcl. Осталось только объяснить это редактору:
- Создадим в папке Packages новый файл Tcl.sublime-settings
- Заполним файл строкой
- Сохраним файл
Создание шаблонов кода (snippets)
Пусть нам надо вставить шаблон кода:
Причем нам бы хотелось, чтобы после вставки текста по нажатию Tab курсор устанавливался на позиции My_proc, clk, rst, data_in, для быстрого изменения значений этих данных. Для этого создадим новый сниппет:Tools → Developer → New Snippet. Редактируем данные:
Сохраняем данный сниппет. Теперь при написании ключевого слова procrst в текущую позицию курсора будет вставлен наш шаблон.
Подробнее о создании шаблонов читайте в статье «Как создать сниппет?».
Написание собственных функций на языке python
Подробно о создании функций (плагинов) описывалось в статьях «Как написать простой плагин», «Как написать сложный плагин».
Вставка сниппетов это, конечно хорошо, но хотелось бы, например, чтобы тот же шаблон создания процесса заполнялся автоматически в зависимости от входных сигналов, а также чтобы процесс модифицировался при наличии таких сигналов как rst и ce. Еще обычно после процесса идет присвоение внешним портам модуля значений внутренних сигналов, пусть тоже делается автоматически.
Для парсинга данных файла VHDL воспользуемся функциями плагина Vhdl mode.
Примерный алгоритм наших действий:
- Получить данные о всех портах модуля
- Все порты типа «in» включить в шапку процесса
- Если есть порты с названием ce и/или rst, то добавить соответствующие условия if else в процесс
- За процессом вставить строки присвоения выходным портам значений внутренних сигналов (обычно такие сигналы называют также как и порт, добавляя приставку «s_» или «_net»)
Здесь $
$
Сохраним его под именем, например, test.sublime-snippet в папку VHDL Mode/Snippets.
Воспользуемся написанными функциями в папке VHDL Mode. Так как знания языка python у меня начальные, то будем модифицировать функции плагина, по аналогии с уже описанными в нем.
Создадим в файле vhdl_lang.py новые функции в классе Interface(), назовем их in_port и out_port:
Функция out_port вставляет за процессом строки, например:
data_out1 <= data_out1_net;
data_out2 <= data_out2_net;
Создадим в папке VHDL Mode новый файл, назовем его my_func.py, вставим текст:
Осталось присвоить горячие клавиши. Так как наш класс называется PasteAsProcess, то команда должна называться paste_as_process (перед символами, кроме первого, написанными в верхнем регистре нужно поставить знак нижнего подчеркивания).
Идем Preferences → Key Bildings. Вставляем строку:
Теперь для работы нам надо сначала скопировать значения портов vhdl файла сочетанием клавиш «alt+k», «p», «w» (по умолчанию). Затем вызвать нашу функцию клавишами «alt+k», «p», «z».
Вывод
Сниппеты и функции значительно упрощают работу с vhdl файлами.
Даже начальных знаний языка python достаточно для написания простых, но рабочих функций.
VHDL coding tips and tricks
Case 2 — Instantiating Verilog modules in VHDL components:
This case is also straightforward. You don’t need to worry about anything. Just instantiate as you normally do it with a vhdl file.
Take this verilog module for instance,
module a1 (
output Q ,
input [ 1 : 0 ] D
) ;
and ( Q , D [ 0 ] , D [ 1 ] ) ;
A simpe vhdl code for instantiating this Verilog code can look like this:
library IEEE ;
use IEEE . STD_LOGIC_1164 . ALL ;
entity test is
port (
Q : out std_logic_vector ( 1 downto 0 ) ;
D : in std_logic_vector ( 3 downto 0 )
) ;
end test ;
architecture Behavioral of test is
component a1 is
port (
Q : out std_logic ;
D : in std_logic_vector ( 1 downto 0 )
) ;
end component ;
a11 : a1 port map ( Q ( 0 ) ,D ( 1 downto 0 ) ) ;
a22 : a1 port map ( Q ( 1 ) ,D ( 3 downto 2 ) ) ;
how to include vhdl in verilog?
is there an easy way to put a design in vhdl inside a verilog design?
i have a nice dynamic verilog file with port declarations towards the external hw, but i want to write my own logic in vhdl. not so familiar with verilog yet.
can i write some kind of wrapper for the vhdl? if so, how?
- Mar 25, 2008
- #2
echo47
Advanced Member level 6
verilog include vhdl
Which HDL compiler software are you using?
With ModelSim and Xilinx XST, I can build projects that include both Verilog and VHDL source files without doing anything special. VHDL can instantiate a Verilog module, and vice-versa, without using any wrapper file. But don't mix Verilog and VHDL source code in the same file, use separate files.
- Mar 25, 2008
- #3
godis_knugen
Newbie level 4
include vhdl
im using xilinx ise 9.1
have tried using the verilog file as top and simlpy instantiate the vhdl as a module,
example:
u_l user_l(
. clk(usr_clk),
.addr(ht_wr_addr)
);
but it says unexpected error when i run synthesis.
- Mar 25, 2008
- #4
echo47
Advanced Member level 6
ise include path
Mixed-language compiling usually works in ISE XST. You may have triggered some other bug that caused the "unexpected error" crash. Maybe an ISE update would help you.
Try this example. It works fine in ISE 9.2.04:
taha.zand
- Oct 18, 2021
- Mar 25, 2008
- #5
godis_knugen
Newbie level 4
rpsyscore_api.v
ok, that worked, but not when i have this:
module top `include "rpsyscore_api.v"
wire clk;
wire [3:0] q;
wire [3:0] icount;
count4 counter(.clk(clk), .Q(q));
where rpsyscore_api.v specifies the ports and the "verilog include path" under synthesis properties is set to the destination of the api file.
then i get :
error Analyzing hierarchy for module <top> in library <work>.
ERROR:Xst:2683 — Unexpected error found while building hierarchy.
- Mar 25, 2008
- #6
echo47
Advanced Member level 6
include vhdl to verilog
That worked for me in both ISE and ModelSim. I assume rpsyscore_api.v contains this line:
(clk, icount);
I run ISE from command-line scripts, not from Project Navigator. The fragment line in rpsyscore_api.v looks like gibberish, not a Verilog module, so try giving it a different extension than ".v", or put it outside the Verilog search path, so Project Navigator doesn't try to automatically interpret it as a Verilog file. That's just a guess.
- Mar 25, 2008
- #7
godis_knugen
Newbie level 4
instantiate vhdl block in verilog
but rpsyscore_api.v is a verilog module .
looks something like:
input usr_clk;
input usr_rst;
.
"here goes lots of `ifdef and `ifndef statements"
- Mar 26, 2008
- #8
echo47
Advanced Member level 6
ise design verilog vhdl
rpsyscore_api.v may be fine when "included" into your top file, but by itself it is incomplete. It begins with a parenthesis instead of a 'module' keyword.
In other words, you put a non-Verilog file into ISE's include path and gave it a ".v" extension, so ISE may be stumbling over it.
godis_knugen
- Mar 26, 2008
- Mar 26, 2008
- #9
godis_knugen
Newbie level 4
can we mix vhdl and verilog in xst
aha, i see. oh and bythe way the property i set was "verilog include directories" under synthesis- properties.
Nope, didn´t help.
but it works if i comment the line " count4 counter(.CLK(clk), .Q(q)); " that instantiates the vhdl block
- Mar 26, 2008
- #10
echo47
Advanced Member level 6
`include verilog vhdl
I can't reproduce your problem. Can you upload your various source files to be sure we are both looking at the same files?
godis_knugen
- Mar 26, 2008
- Mar 26, 2008
- #11
godis_knugen
Newbie level 4
how to write a verilog wraper for vhdl design
finally it works, i tried starting a new fresh project and using ise9.2 with the latest sp. i still dont know why it didn´t work before though. ¨
anyway, thanks for the help.
- Mar 26, 2008
- #12
echo47
Advanced Member level 6
ise verilog `ifndef
That's good news! Maybe your code was simply triggering some obscure bug in the older version.
- Apr 18, 2010
- #13
ishwarayya
Newbie level 1
Dear echo47 & godis_knugen ,
i have tried the counter example in modelsim XE3/starter 6.3c version,by modifiying the code as like below
*********top.v file*******************
`include "count4.vhd"
module top (clk, icount);
input clk;
wire [3] q;
output [3] icount;
count4 counter(.clk(clk), .Q(q));
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity count4 is
port
(
CLK : in std_logic;
Q : out std_logic_vector(3 downto 0)
);
end count4;
architecture archi of count4 is
signal tmp: std_logic_vector(3 downto 0) := "0000";
begin
process (CLK)
begin
if (rising_edge(CLK)) then
tmp <= tmp + 1;
end if;
end process;
Q <= tmp;
end archi;
************************
—> but when i simulate .v file its shows following error
** Error: count4.vhd(1): near ";": syntax error, unexpected ';', expecting "STRING_LITERAL"
is there any extra settings u did while simulating .
Added after 23 minutes:
Dear echo47 & godis_knugen ,
i have tried the counter example in modelsim XE3/starter 6.3c version,by modifiying the code as like below
*********top.v file*******************
`include "count4.vhd"
module top (clk, icount);
input clk;
wire [3:0] q;
output [3:0] icount;
count4 counter(.clk(clk), .Q(q));
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity count4 is
port
(
CLK : in std_logic;
Q : out std_logic_vector(3 downto 0)
);
end count4;
architecture archi of count4 is
signal tmp: std_logic_vector(3 downto 0) := "0000";
begin
process (CLK)
begin
if (rising_edge(CLK)) then
tmp <= tmp + 1;
end if;
end process;
Q <= tmp;
end archi;
************************
—> but when i simulate .v file its shows following error
** Error: count4.vhd(1): near ";": syntax error, unexpected ';', expecting "STRING_LITERAL"