Как стать автором
Обновить

Коротенькое сравнение VHDL и Verilog в помощь начинающим знакомство с ПЛИС

Время на прочтение4 мин
Количество просмотров64K
Исторически так сложилось что ПЛИС я начал изучать только на новой работе.
Это были серии ПЛИС фирмы Altera.

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

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

Приведу пример листинга из статьи «Делаем таймер или первый проект на ПЛИС».


Исходный код на языке VHDL
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity Div_27Mhz_to_1Hz is
	 port
		 ( 
			 clk 	 in 	 std_logic; 
			 clk_out 	 out 	 std_logic
		 );
end Div_27Mhz_to_1Hz;

architecture div_behavior of Div_27Mhz_to_1Hz is

Begin

	 process(clk)
		 variable cnt : integer range 0 to 27000000;
	 begin

		  if (clk'event and clk = '1') then

			 if (cnt 	 >= 13500000) then

				 clk_out 	 <= '1';
			 else 
				 clk_out 	 <= '0';
			 end if;

			 if (cnt 	 = 27000000) then

				 cnt 	 := 0;
			 else
				 cnt 	 := cnt + 1;
			 end if; 

		 end if;
	end process;

end div_behavior;



Подробно описывать как это работает я не буду — достаточно прочитать оригинальную статью. Я же постараюсь выразить свое впечатление от листинга в целом.
Для начала невозможный блок объявления библиотек. Причем библиотеки необходимы даже для часто применяемых типов данных (std_logic) или функция конвертации типов).
Заставьте новичка сделать преобразование внутренней переменной типа integer в тип std_logic_vector и установить это значение на внешний порт!
И что мы получим? Несколько часов мучительных поисков того как же это сделать.
В итоге оказывается, что нам надо:
1. подключить библиотеки:
use ieee.std_logic_1164.ALL;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.ALL;

2. запись integer в порт std_logic_vector напрямую невозможна. Необходимо применять специальные функции преобразования типов! (Всегда возмущало понятие типа в проектах для ПЛИС)
std_logic_vector (to_unsgined(, ))
данная запись преобразует младших бит регистра в вектор std_logic_vector.
И того минимум 4 строки для записи числа в порт.

Так же для меня ужасом было явление записи вектора:
vector(M downto N)
или
vector(M upto N)

слова downto и upto просто выводили меня из равновесия своей избыточностью. По моему мнению они являются лишними.
Я уже молчу о том. что числа разных типов пишутся по разному:
integer пишется как нормально число — 1, 2, 3, 4, 5
а вот с std_logic_vector возникают проблемы.
Запись имеет вид '1' и '0' для единичного вектора, а вот вектора 2х и более разрядов по умолчанию НЕ МОГУТ принимать десятичные значения. Только HEX или BIN.

К счастью на этом мое знакомство с этим языком закончилось и я окунулся в религию языков Verilog и SystemVerilog.

Для меня это было откровение!
Никаких лишних записей. Листинг чистый и понятный. Каждый знак имеет оправданный смысл и место.
К сожалению современные компиляторы для ПЛИС не до конца поддерживают стандарт данных языков, от того не все их возможности можно использовать. (В моей личной практике Quartus II плохо понимал проект с использованием процедур и функций.
Так же он плохо понимал классы (или вообще не понимал? уже не помню).
Сравните сами листинг приведенный выше в записи на SystemVerilog:

Исходный код на языке SystemVerilog
module Div_27Mhz_to_1Hz
(
	 input 			 CLK,
	 output logic 		 CLK_OUT,

	 output logic[7:0] 		 CNT_OUT
);

integer cnt = 0;

always@(posedge CLK) begin

	 if (cnt >= 13500000) begin

		 CLK_OUT 	 <= 1;
	 end
	 else begin
		 CLK_OUT 	 <= 0;
	 end

	 if (cnt == 27000000) begin

		cnt 	 <= 0;
	end
	else begin
		 cnt 	 <= cnt + 1;
	end

	 CNT_OUT 	 <= cnt;
end

endmodule



Как видите количество строк заметно уменьшилось. Сам листинг более прост и однотипен (числа везде записываются как числа). Блок проверки фронта сигнала перекочевал к месту объявления триггера процесса.
Так же я специально расширил функционал модуля для демонстрации удобства и простоты преобразования типа данных.
Как вы можете заметить в описании портов модуля я ввел специальный восьмибитный выходной порт CNT_OUT. Тип данных порта logic.
Тут стоит сделать легкое отступление о типах в SystemVerilog.
В SV есть два основных типа данных:
цепи (wire)
регистры (reg)
все остальные типы данных не воспринимаются Quartus в полной мере и потому мной не использовались.
При этом разница между данными типами (по стандарту) в том, что тип цепь не может принимать значения.

тип данных logic указывает на то, что компилятор волен сам решать что это — цепь или регистр.

Стоит отметить что Quartus вообще игнорирует типы данных SV при компиляции. Его компилятор позволяет использовать wire как регистр и наоборот. Потому применение типа данных logic несколько условно. Мы имеем переменную счетчика типа integer (по умолчанию она 32 бита) и внешний порт вывода типа logic и разрядностью 8 бит.
Строка CNT_OUT <= cnt; делает следующее:
каждый такт в порт CNT_OUT записывается младшие 8 разрядов регистра cnt. (стоит отметить, что в данной записи не указан явно диапазон разрядов для записи в порт.
Потому берется 8 младших).

Таким образом видим, что для преобразования типов SV не требует специализированных библиотек и функций. Все эти задачи решаются компилятором.
Так же в SV есть удобство в виде автоматического выравнивания разрядности данных.
Т.е. если в проекте используется тип данных integer но по логике работы понятно что значение данного регистра не превышает 255 (в десятичной системе),
то после компиляции данный регистр будет 8 разрядным.
Таким образом налицо очередная вольность допускаемая стандартом SV — он не требует явного выравнивания длин регистров.

В общем и целом на мой взгляд листинг SystemVerilog выглядит более гармонично и удобочитаемо. Что достигается отсутствием длинных названий типов данных и строк объявления сигналов и регистров.
Так же проще и аккуратнее реализована запись векторов.

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

В общем и целом SystemVerilog придется по вкусу программистам.
Если же вы закоренелый схемотехник то вам по нраву будет AHDL.
Я не привожу его в сравнении т.к. он совсем другая тема и сравнивать его с приведенными в статье языками, все равно что сравнивать ассемблер и С.
Теги:
Хабы:
+5
Комментарии45

Публикации

Истории

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн