Главная » Микроконтроллеры
Призовой фонд
на август 2017 г.
1. Регулируемый паяльник 60 Вт
Паяльник
2. Тестер компонентов LCR-T4
Паяльник
3. 100 руб.
От пользователей

FPGA. Просто о сложном - Создание проекта в Quartus II. Сравнение VHDL и Verilog

Самыми популярными языками описания цифровой аппаратуры являются VHDL и Verilog. В этой статье я постараюсь сравнить синтаксис двух этих языков на примере "бегущего огонька", архивы проектов будут прикреплены в конце статьи. Для полного понимания описываемых процессов настоятельно рекомендую ознакомиться с предыдущими статьями цикла: 

  1. Внутреннее устройство ПЛИС (FPGA)
  2. Философия написания конфигураций для ПЛИС

Рассмотрим структуру создаваемого модуля "бегущего огонька", который назовем 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.

Теперь напишем код и разберем его.

-- Подключение стандартных библиотек на математику и типы данных.
library ieee; 
use ieee.std_logic_1164.all;
use ieee.std_logic_ARITH.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
---------------------------------------------------------------
-- В entity указываются порты ввода и вывода. В начале статьи 
-- мы выяснили что будет один вход для тактовой частоты и четыре 
-- выхода для светодиодов. 
--------------------------------------------------------------- 
entity led_case is 
port
(
	clk  : in  std_logic; -- тип std_logic указывает на то, что сигнал будет представлен как "провод"
	leds : out std_logic_vector(3 downto 0) -- тип std_logic_vector указывает на то, что перед нами шина данных
);                                          -- (3 downto 0) указывает, что в шине leds четыре сигнала  
end led_case;

architecture led of led_case is -- в architecture под названием led описываются все процессы происходящие в модуле, который                     
                                -- связан с другими файлами в проекте через entity led_case               

	signal count : std_logic_vector(21 downto 0) := (others => '0'); -- объявляем счетный регистр count с начальным значением 0
	signal slct  : std_logic_vector(1 downto 0) := (others => '0'); --объявляем регистр выбора светодиода с начальным значением 0

begin -- начало описания процессов

	process(clk) -- первый процесс синхронизированный по clk
	begin 
	
		if (rising_edge(clk)) then -- процесс выполняется по нарастающему фронту тактирования
		
			count <= count + '1'; -- с каждым тактом значение счетчика увеличивается на единицу
			
			if (count = b"11_1111_1111_1111_1111_1111") then -- при переполнении счетчика (b"<значение>"- двоичная запись числа)   
				slct <= slct + '1'; -- изменяется значение регистра slct, который отвечает за то, какой светодиод зажечь
			end if;
			
		end if;
		
	end process;
	
	process(clk) 
	begin
		
		if (rising_edge(clk)) then
		
			case (slct) is -- функция CASE в VHDL выполняет ту же роль что и в С/С++
			
				when b"00" => leds <= b"0001"; -- Если значение регистра slct "00", то зажигаем первый светодиод
				when b"01" => leds <= b"0010"; -- Если значение регистра slct "01", то зажигаем второй светодиод
			    when b"10" => leds <= b"0100"; -- Если значение регистра slct "10", то зажигаем третий светодиод
				when b"11" => leds <= b"1000"; -- Если значение регистра slct "11", то зажигаем четвертый светодиод		
				
				when others => leds <= b"0000"; -- В любых других случаях выключаем все светодиоды
				
			end case;
			
		end if;
		
	end process;
	

end led;

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

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

 

// Как видите, никаких библиотек на математику и типы данных мы не подключаем 

module led_case // то же самое, что и entity, здесь мы объявляем порты, через которые данный модуль может быть связан с другими                
(               // файлами в проекте 
	input clk, // input - обозначение что сигнал clk вход
	output[3:0] out // output[3:0] - обозначение, что сигнал out это шина из четырех сигналов
);
	reg[3:0] leds = 4'b0; // создание регистра, куда будет записываться значение выходной шины для светодиодов 
                          // (4'b - запись четырехбитного числа в двоичном виде) 
	reg[21:0] count = 22'b0; // объявляем счетный регистр count
	reg[1:0] select = 2'b0; // объявляем регистр выбора светодиода

	always @ (posedge clk) // объявление первого процесса, который выполняется по нарастающему фронту clk
	begin
	
		count <= count + 1'b1; // с каждым тактом значение счетчика увеличивается на единицу
			
		if (count == 22'b11_1111_1111_1111_1111_1111) // при переполнении счетчика
		begin
			select <= select + 1'b1; // изменяется значение регистра select, который отвечает за то, какой светодиод зажечь
		end 
		
	end
	
	always @ (posedge clk) // объявление второго процесса, который выполняется по нарастающему фронту clk 
	begin
	
		case(select) // функция CASE выполняет ту же роль что и в С/С++
			2'b00: leds <= 4'b0001;	// Если значение регистра select "00", то зажигаем первый светодиод
			2'b01: leds <= 4'b0010;	// Если значение регистра select "01", то зажигаем второй светодиод			
			2'b10: leds <= 4'b0100; // Если значение регистра select "10", то зажигаем третий светодиод
			2'b11: leds <= 4'b1000;	// Если значение регистра select "11", то зажигаем четвертый светодиод
	
			default: leds <= 4'b0000; // В любых других случаях выключаем все светодиоды	

		endcase	
		
	end
	
	assign out = leds; // асинхронно передаем значение регистра leds на выходную шину out 
	
endmodule

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Как Вы можете убедится оба языка очень похожи и мнение о том, что синтаксис 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. Спасибо за внимание.

Прикрепленные файлы:

Теги:

Опубликована: 0 3
Я собрал 0 Участие в конкурсе 2
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 5 Проголосовало: 2 чел.

Комментарии (13) | Я собрал (0) | Подписаться

0
Публикатор #
На форуме автоматически создана тема для обсуждения статьи.
Ответить
0
Gauss #
Стартовый набор для ПЛИС прям как у меня
Ответить
0

[Автор]
sboldenko #
Так ведь дешево и сердито.
Ответить
0
Gauss #
Ловлю себя на мысли, что эти китайские макеты часто не только дешевле, но и функционально удобнее или лучше оригинальных отладочных плат
Ответить
0

[Автор]
sboldenko #
Соглашусь, что китайские макеты в десятки раз дешевле оригиналов, вот только хромают в разводке ПП: о диф.парах можно забыть, как и о выравнивании, и т.д. На больших скоростях это играет роль.
Ответить
0
Vascom #
Но там и не такие уж высокие частоты чтобы огрехи в выравнивании дорожек играли роль.
Ответить
0

[Автор]
sboldenko #
DCM-ом можно раскачать и до 400 МГц. А гигабитные приемопередатчики так и вообще на гигагерцах работают, но речь не только о выравнивании.
Отредактирован 02.03.2017 15:15
Ответить
0
Vascom #
Я к тому, что в этих дешёвых ПЛИС начального уровня нет ни гигабитных трансиверов, на поддержки таких высоких частот. А там где есть, и разводка правильная.
Ответить
0

[Автор]
sboldenko #
Купил я как-то плату, написал прошивку, назначил пины, прошил, не заработало. Начал разбираться в чем дело, оказалось на плате сигнал тактирования заведен на абсолютно рандомную ногу не связанную с gclk, после такого я не очень верю китайцам. К слову, купил именно эту плату потому что нууу очень дешево выходило. Так что все же цена влияет на качество.
Ответить
0
olega88 #
Спасибо, ждём продолжения, с картинками!
Ответить
0
Gauss #
Т.к. на самой отладочной плате нет светодиодов
1 есть, кстати, кроме индикатора питания
Ответить
0
Gauss #
Еще, скрины хорошо бы кликабельными делать или размером побольше - обратил внимание, что разглядеть на них что-то крайне проблематично, только наощупь если
Ответить
0

[Автор]
sboldenko #
Спасибо за замечание, учту.
Ответить
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется электрическое сопротивление?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

Pickit 2 - USB-программатор PIC-микроконтроллеров
Pickit 2 - USB-программатор PIC-микроконтроллеров
Arduino UNO UNI-T UT-61A
вверх