AHDL

AHDL (англ. Altera Hardware Definition Language) комп'ютерна мова опису апаратних засобів, розроблена компанією Altera, що призначена для опису комбінаційних логічних пристроїв, цифрових автоматів і таблиць істинності з врахуванням архітектурних особливостей ПЛІС цієї фірми. Мова має Ada-подібний синтаксис; порівнюючи AHDL з Verilog можна зазначити, що це наче мова асемблера та мова високого рівня: перша має більше контролю, проте немає високорівневої підтримки.

AHDL
Парадигма паралельна
Система типізації сильна
Під впливом від Ada, VHDL, Verilog
Звичайні розширення файлів TDF (англ. Text Design File)

AHDL, природно, сумісний з компіляторами фірми Altera: Quartus та Max+PLUS та дає можливість створювати ієрархічні проєкти в рамках цієї мови чи комбінувати різні типи файлів в один проєкт.

Структура програми

Програма на мові AHDL має визначену структуру. Її розділи повинні слідувати в такому порядку:

НазваПризначенняОсобливості
Заголовок (англ. Title Statement)Дає назву модулюПочинається з ключевого слова TITLE, за яким слідує назва модуля.
Оператор включення (англ. Include Statement)Включає вміст вказаного файлу в текст програмиПочинається з ключевого слова INCLUDE, за яким слідує ім'я файлу, без шляху до нього.
Оголошення константи (англ. Constant Statement)Присвоює імені константи числоПочинається з ключевого слова CONSTANT, за яким слідує ім'я, символ (=), а далі число чи арифметичний вираз.
Оператор визначення (англ. Define Statement)Присвоює арифметичним виразам символьні іменаПочинається з ключевого слова DEFINE, за яким слідує ім'я зі списком аргументів, за яким ставиться символ (=), а далі арифметичний вираз.
Оголошення параметрів (англ. Parameters Statement)Оголошує параметри модуляПочинається з ключевого слова PARAMETERS, за яким слідує список параметрів. Значення параметру за замовчуванням вказується після символу (=).
Опис прототипу (англ. Function Prototype Statement)Описує параметри модулів, що використовуютьсяПочинається з ключевого слова FUNCTION, за яким слідує ім'я, а потім список входів. Якщо модуль параметризований, далі йде ключове слово WITH і список параметрів. Потім вказується ключове слово RETURNS і список виходів модуля.
Оператор опцій (англ. Options Statement)Визначає елемент з меншим індексомПочинається з ключевого слова OPTIONS, за яким слідує ключове слово BITO, символ (=), а далі одне з ключевих слів: LSB (молодший розряд), MSB (старший розряд) чи ANY (будь-який).
Оператор контролю (англ. Assert Statement)Перевіряє істинність логічного виразуПочинається з ключевого слова ASSERT, за яким в дужках слідує арифметичний вираз. Якщо значення виразу false, на екран виводиться повідомлення, записане після ключевого слова REPORT.
Опис модуля (англ. Subdesign Section)Задає ім'я модуля й перераховує його портиПочинається з ключевого слова SUBDESIGN, за яким слідує назва модуля та список виводів в дужках. В кінці списку однотипних виводів вказується їх тип.
Розділ змінних (англ. Variable Section)Задає внутрішні змінніПочинається з ключевого слова VARIABLE, за яким слідують імена однотипних змінних, а далі тип змінних. Розділ може містити оператор IF GENERATE, що керує створення змінних залежно від результату арифметичного виразу.
Опис логіки (англ. Logic Section)Описує функціонал модуляПочинається з ключевого слова BEGIN, закінчується ключевим словом END.

З усіх названих, лише розділи опису модуля та логіки є обов'язковими; заголовок, оператор опцій, розділи змінних, опису модуля та логіки можуть вживатися в програмі лише раз.

Конструкції мови

Множина символів мови

До множини символів мови відносять букви, цифри та спеціальні символи, призначення яких наведено в таблиці нижче.

СимволФункція
--Коментар в стилі VHDL, що продовжується до кінця рядка
 %Ставляться з обох боків коментаря в стилі AHDL
()Використовуються для підвищення пріоритету в операціях, оточують порти в іменах модуля та списки параметрів
[]Використовуються для створення діапазону значень
''Використовуються для створення символічних імен
""Використовуються в заголовку, для вказування файлу для включення, оточують цифри в недесяткових константах
.Відділяє ім'я файлу від розширення
..Розділяє найбільші та найменші значення в діапазонах
 ;Закінчує розділи і секції мови
,Розділяє елементи списків та груп
 :Відділяє символьні імена від типів
=Присвоює значення в операціях
=>Відділяє входи і виходи в таблицях істинності та операторі CASE

З символів складаються імена, що в мові AHDL можуть даватися:

Синтаксис імен в AHDL схожий на синтаксис імен в інших комп'ютерних мовах:

  • ім'я може містити букви, цифри, символ підкреслення та не може бути зарезервованим словом;
  • зарезервовані слова можна використовувати як символічні імена лише коли вони вживаються в одинарних лапках або в коментарях;
  • великі та малі літери не розрізняються;
  • ім'я повинне починатися з букви і не може закінчуватися знаком підкреслення.

Зарезервовані слова

В документації компанії Altera вказано, що для поліпшення прочитності програми зарезервовані слова варто писати великими літерами. До ключевих слів належать наступні:

AND ASSERT BEGIN BIDIR BITS BURIED CASE CLIQUE CONNECTED_PINS
CONSTANT DEFAULTS DEFINE DESIGN DEVICE DIV ELSE ELSEIF END
FOR FUNCTION GENERATE GND HELP_ID IF INCLUDE INPUT IS
LOG2 MACHINE MOD NAND NODE NOR NOT OF OPTIONS
OR OTHERS OUTPUT PARAMETERS REPORT RETURNS SEGMENTS SEVERITY STATES
SUBDESIGN TABLE THEN TITLE TO TRI_STATE_NODE VARIABLE VCC WHEN
WITH XNOR XOR

До службових імен належать:

CARRY CASCADE CEIL DFFE DFF EXP FLOOR GLOBAL JKFFE JKFF LATCH LCELL MCELL MEMORY OPENDRN SOFT
SRFFE SRFF TFFE TFF TRI USED WIRE X

Змінні

Змінні використовуються для збереження проміжних результатів обчислень. Допустимими типами змінних є:

  • NODE;
  • TRI_STATE_NODE;
  • імена примітивів, мегафункцій, макрофункцій та машин станів.

Кілька провідників, що несуть однакове смислове навантаження можна об'єднати в шину. Кожна з них може мати до 255 біт і працює як одне ціле. Визначити шину можна наступними способами, після чого [] стануть еквівалентними звертанню до всієї шини:

a[1..5]
b[7..0]
(c, d, e)

Порти

Порт — це вхід чи вихід логічної функції. Може мати один з наступних типів:

  • INPUT — вхід;
  • OUTPUT — вихід;
  • BIDIR — двонаправлений вивід;
  • MACHINE INPUT — вхід станів автомата;
  • MACHINE OUTPUT — вихід станів автомата.

Мова AHDL дає можливість описати двонаправлений порт, що корисно для зменшення кількості провідників. На прикладі нижче, двонаправлений сигнал io, що запускається примітивом TRI, використовується як вхід та вихід для D-тригера (DFF). Варто відмітити, що входи тригера clrn та prn не підключені, що видно з відділених комами місць.

SUBDESIGN bus_register
	(
		clk, oe : INPUT;
		io : BIDIR;
	)
BEGIN
	io = TRI(DFF(io, clk, , ), oe);
END;

Числа

Мова AHDL підтримує запис чисел в десятковій, двійковій, вісімковій та шістнадцятковій системах числення. Таблиця нижче ілюструє формат запису чисел.

Основа системиФормат
10<послідовність цифр 0..9>
2B"<послідовність цифр 0, 1, X>"
8O"<послідовність цифр 0..7>" чи Q"<послідовність цифр 0..7>"
16X"<послідовність цифр 0..9, A..F>" чи H"<послідовність цифр 0..9, A..F>"

Константи можна використати для того, щоб надати конкретному числу більше інформативності. Окрім підвищення прочитності програми, їх застосування стає корисним тоді, коли це число неодноразово повторюється. Нижче наведено приклад селектора адреси, що забезпечує підключення певного пристрою до шини лише за умови подання на його вхід адреси 21 в шістнадцятковій системі числення.

CONSTANT io_address = H"21";
SUBDESIGN address_selector
	(
		a[15..0] : INPUT;
		select : OUTPUT;
	)
BEGIN
	select = (a[15..0] == io_adress);
END;

Арифметичні і булеві вирази

Арифметичні вирази — це засіб формування конструкцій мови, що обраховуються компілятором і не займають ресурсів ПЛІС. Їх результатом завжди є ціле додатне число, для його отримання є функції явного задання правил округлення: CEIL (до більшого цілого) та FLOOR (до меншого цілого).

Операції, що можуть використовуватись в арифметичних виразах наведені в таблиці:

ОпераціяОписПріоритет
+ (унарний)Плюс1
— (унарний)Мінус1
 ! (NOT)Заперечення1
^Степінь1
MODЗалишок від ділення2
DIVДілення2
*Множення2
LOG2Двійковий логарифм2
+Додавання3
Віднімання3
== (numeric)Рівність чисел4
== (string)Рівність рядків4
 !=Не рівно4
>Більше4
>=Більше рівно4
<Менше4
<=Менше рівно4
& (AND)Кон'юнкція5
 !& (NAND)Штрих Шефера5
$ (XOR)Виключна диз'юнкція6
 !$ (XNOR)Заперечення виключної диз'юнкції, еквівалентність6
# (OR)Диз'юнкція7
 !# (NOR)Стрілка Пірса7
 ?Умовна операція8

Булеві вирази — це операнди, розділені знаками арифметичних, логічних операцій та операторами порівняння, згруповані дужками. Варто зазначити, що порядок слідування булевих рівнянь в програмі не важливий, оскільки логічні стани встановлюються одночасно.

Операції, що можуть використовуватись в булевих виразах наведені в таблиці:

ОпераціяОписПріоритет
Доповнення до 21
 !Інверсія1
+Додавання2
Віднімання2
==Рівно3
 !=Не рівно3
>Більше3
>=Більше рівно3
<Менше3
<=Менше рівно3
& (AND)Елемент «І»4
 !& (NAND)Елемент «І-НЕ»4
$ (XOR)Елемент «ВИКЛЮЧНЕ АБО»5
 !$ (XNOR)Елемент «ВИКЛЮЧНЕ АБО-НЕ»5
# (OR)Елемент «АБО»6
 !# (NOR)Елемент «АБО-НЕ»6

Приклади використання

Комбінаційна логіка

Комбінаційна логіка — це кінцеві автомати без пам'яті, що реалізуються за допомогою булевих виразів та таблиць істинності.

Таблична логіка

Таблична логіка в мові AHDL реалізується за допомогою наступного синтаксису:

  • оператор починається ключевим словом TABLE, за яким йде заголовок таблиці;
  • в заголовку перераховуються список входів, символ (=>) та список виходів;
  • наступні рядки таблиці містять списки значень входів і виходів, розділені символом (=>). Вхідні значення можуть бути в неважливому стані X, проте варто слідкувати, щоб діапазони значень не перекривались в межах однієї таблиці;
  • оператор закінчується ключевими словами END TABLE.

На прикладі нижче наведено контролер, що формує управляючі сигнали для відображення цифр в шістнадцятковій системі числення на семисегментному індикаторі.

%  -a-  %
% f| |b %
%  -g-  %
% e| |c %
%  -d-  %
SUBDESIGN segment7
	(
		i[3..0] : INPUT;
		a, b, c, d, e, f, g : OUTPUT;
	)
BEGIN
	TABLE
		i[3..0] => a, b, c, d, e, f, g;
		H"0" => 1, 1, 1, 1, 1, 1, 0;
		H"1" => 0, 1, 1, 0, 0, 0, 0;
		H"2" => 1, 1, 0, 1, 1, 0, 1;
		H"3" => 1, 1, 1, 1, 0, 0, 1;
		H"4" => 0, 1, 1, 0, 0, 1, 1;
		H"5" => 1, 0, 1, 1, 0, 1, 1;
		H"6" => 1, 0, 1, 1, 1, 1, 1;
		H"7" => 1, 1, 1, 0, 0, 0, 0;
		H"8" => 1, 1, 1, 1, 1, 1, 1;
		H"9" => 1, 1, 1, 1, 0, 1, 1;
		H"A" => 1, 1, 1, 0, 1, 1, 1;
		H"B" => 0, 0, 1, 1, 1, 1, 1;
		H"C" => 1, 0, 0, 1, 1, 1, 0;
		H"D" => 0, 1, 1, 1, 1, 0, 1;
		H"E" => 1, 0, 0, 1, 1, 1, 1;
		H"F" => 1, 0, 0, 0, 1, 1, 1;
	END TABLE;
END;

Умовна логіка

Умовна логіка в мові реалізується операторами IF та CASE.

Оператор CASE, як і в більшості комп'ютерних мовах, визначає вписок альтернативних варіантів, один з яких виконується при певному значенні селектора. Його синтаксис наступний:

  • оператор починається ключевим словом CASE, за яким записується селектор, а потім — ключове слово IS;
  • кожен альтернативний варіант починається ключевим словом WHEN, після якого йде константа, потім символ (=>) та набір операторів;
  • на відміну від інших, останній альтернативний варіант може починатися з WHEN OTHERS;
  • якщо селектор рівний одній з констант, виконується блок її операторів, якщо ж така константа не передбачена — виконується блок з WHEN OTHERS;
  • завершується оператор ключевими словами END CASE.

Нижче наведено приклад дешифратора, що перетворює двохрозрядний код на вході в код «one hot» (чотири значення, кожне має одну одиницю):

SUBDESIGN decoder2x4
	(
		code[1..0] : INPUT;
		out[3..0] : OUTPUT;
	)
BEGIN
	CASE code[] IS
		WHEN 0 => out[] = B"0001";
		WHEN 1 => out[] = B"0010";
		WHEN 2 => out[] = B"0100";
		WHEN 3 => out[] = B"1000";
	END CASE;
END;

Регістр

Регістр необхідний для збереження інформації і створюється після його оголошення в розділі змінних. На прикладі нижче сформовано восьмирозрядний регістр, що використовує виходи як D-тригери, що дає економію ресурсів мікросхеми.

SUBDESIGN register8
	(
		clk, load, d[7..0] : INPUT;
		q[7..0] : OUTPUT;
	)
VARIABLE q[7..0] : DFFE; -- виводи оголошені тригерами 
BEGIN
	q[].clk = clk;
	q[].ena = load;
	q[] = d[];
END;

Лічильник

Лічильник зазвичай створюється з використанням оператора IF. Синтаксис його використання наступний:

  • оператор починається з ключевого слова IF, за яким вказується булева умова, а потім ключеве слово THEN і список операторів, що виконуються при вірності умови;
  • між ключевими словами ELSEIF та THEN може бути додатковий вираз, а за THEN — список операторів, що виконуються якщо цей вираз виконується;
  • за цією конструкцією (що є необов'язковою, але може повторюватись багато разів), може слідувати ключове слово ELSE з списком операторів, що виконуються тоді, коли інші умови не вірні;
  • оператор завершується ключевим словом END IF.

В наступному прикладі реалізовано чотирьохрозрядний лічильник зі скиданням.

SUBDESIGN counter4
	(
		clk, load, ena, clr, d[3..0] : INPUT;
		q[3..0] : OUTPUT;
	)
VARIABLE count[3..0] : DFF;
BEGIN
	count[].clk = clk;
	count[].clrn = !clr;
	IF load THEN
		count[].d = d[];
	ELSEIF ena THEN
		count[].d = count[].q + 1;
	ELSE
		count[].d = count[].q;
	END IF;
	q[] = count[];
END;

Машина станів

Машина станів в AHDL — це мовна структура, що дозволяє описувати скінченний автомат в вигляді множини внутрішніх станів. Переходи між станами синхронізуються тактовим сигналом. Умова та напрямок переходу визначаються для кожного стану індивідуально. Кожному стану можна поставити у відповідність один чи кілька управляючих сигналів.

Машина станів описується як змінна в відповідному розділі, а її поведінка — у розділі логіки. Поведінку машини можна описати двома способами:

  • за допомогою оператора CASE;
  • за допомогою конструкції TABLE.

Нижче наведено приклади двох видів автоматів автомата Мура та автомата Мілі. Відмінності між ними полягають в тому, що автомат Мура — машина станів з синхронними сигналами на виходах. Формування вихідного сигналу виконується синхронно з переходом до наступного стану по стробу синхросигналу.

SUBDESIGN moore
	(
		clk, reset, y : INPUT;
		z : OUTPUT;
	)
VARIABLE 
	ss: MACHINE WITH STATES (s0, s1, s2, s3);
	zd: NODE;
BEGIN
	ss.clk = clk;
	ss.reset = reset;
	z = DFF(zd, clk, VCC, VCC); -- вихідний тригер, що синхронізує зміну сигналу 
	TABLE
		-- поточний стан, вхідний сигнал, наступний стан, вихідний сигнал 
		ss, y => ss, zd;
		s0, 0 => s0, 0;
		s0, 1 => s2, 1;
		s1, 0 => s0, 0;
		s1, 1 => s2, 1;
		s2, 0 => s2, 1;
		s2, 1 => s3, 0;
		s3, 0 => s3, 0;
		s3, 1 => s1, 1;
	END TABLE;
END;

А от автомат Мілі — це машина станів з асинхронними сигналами на виходах. Формування вихідного сигналу здійснюється комбінаційною логікою. Після переходу до наступного стану, синхронізованого тактовим сигналом, зміна вихідного сигналу відбувається з затримкою, яку вносить комбінаційна логіка.

SUBDESIGN mealy
	(
		clk, reset, y : INPUT;
		z : OUTPUT;
	)
VARIABLE ss: MACHINE WITH STATES (s0, s1, s2, s3);
BEGIN
	ss.clk = clk;
	ss.reset = reset;
	TABLE
		-- поточний стан, вхідний сигнал, вихідний сигнал, наступний стан 
		ss, y => z, ss;
		s0, 0 => 0, s0;
		s0, 1 => 1, s1;
		s1, 0 => 1, s1;
		s1, 1 => 0, s2;
		s2, 0 => 0, s2;
		s2, 1 => 1, s3;
		s3, 0 => 0, s3;
		s3, 1 => 1, s0;
	END TABLE;
END;

Див. також

Література

  • Бродин В. Б., Калинин А. В. Системы на микроконтроллерах и БИС программируемой логики. — М.: Издательство ЭКОМ, 2002. — 400 с.: илл. — ISBN 5-7163-0089-8. (рос.)
  • Каршенбойм И., Косткин М. Шпаргалка для перехода от AHDL к VHDL. — Компоненты и технологии № 1, 2003. (рос.)
  • Стешенко В. Б. ПЛИС фирмы ALTERA: проектирование устройств обработки сигналов. — М.: ДОДЭКА, 2000. — 128 с. — ISBN 5-94020-001-X. (рос.)
This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.