Константы и др.
- Constant - константы. Значение константы определяется при ее объявлении и не может быть изменено. Константы могут иметь любой из поддерживаемых типов данных.
- Variable - переменные. Значение, хранимое в переменной, меняется везде, где встречается присваивание данной переменной. Переменные могут иметь любой из поддерживаемых типов данных.
- Signal - сигналы. Сигналы представляют значения, передаваемые по проводам и определяемые присвоением сигналов (отличным от присвоения переменных). Сигналы могут иметь ограниченный набор типов (обычно bit, bit_yector, stdjogic, std_hgic_vector, integer, и, возможно, другие - в зависимости от среды разработки).
- Повторное использование присваивания сигналов в наборе параллельных операторов не допускается. В наборе последовательных операторов такое присваивание допустимо и даст значение сигнала, соответствующее последнему по порядку присваиванию. Синтаксис объявления объектов:
Constant { name [, name] }: Type [ (indexjrange [, indexjrange ]) ]:= initial_value;
Variable { name [, name]): Type [ (indexjrange [, indexjrange ])][:= initialj/alue ];
Signal { name [, name] }: Type [ (indexjrange) ];
Диапазон значений индексов задается в виде int_value to int_value или int^yalue down to int_value,
Типы данных
Подобно высокоуровневым языкам программирования, VHDL является языком со строгой типизацией. Каждый тип данных в VHDL имеет определенный набор принимаемых значений и набор допустимых операций. В языке предопределено достаточное количество простых и сложных типов, а также имеются средства для образования типов, определяемых пользователем.
Идентификаторы
Как и любой другой язык программирования, VHDL имеет свой алфавит - набор символов, разрешенных к использованию и воспринимаемых компилятором. В алфавит языка входят:
|
- Латинские строчные и прописные буквы: А, В,..., Z и а, b,..., z
- Цифры от 0 до 9.
- Символ подчеркивания "_" (код ASCII номер 95).
Из символов, перечисленных могут конструироваться идентификаторы в программе. Написание идентификаторов должно подчиняться следующим правилам:
- идентификатор не может быть зарезервированным словом языка;
- идентификатор должен начинаться с буквы;
- идентификатор не может заканчиваться символом подчеркивания "_";
- идентификатор не может содержать двух последовательных символов подчеркивания "_";
Примеры корректных идентификаторов: cont, clock2, full_add Примеры некорректных идентификаторов: Iclock, _adder, add_sub, entity
Следует отметить, что прописные и строчные буквы не различаются, т.е. идентификаторы clock и CLOCK являются эквивалентными.
Символ "пробел" (код 32), символ табуляции (код 9), символ новой строки (коды 10 и 13) являются разделителями слов в конструкциях языка. Количество разделителей не имеет значения. Таким образом, следующие выражения для компилятора будут эквивалентны:
count:=2+2;
count:= 2 + 2;
count:= 2
+
2;
Специальные символы, участвующие в построении конструкций языка:
+ -*/ = <>.,():;#'"|
Составные символы, воспринимаемые компилятором как один символ:
<= >= =>:= /=
Разделители между элементами составных символов недопустимы.
Перечислимый тип
Перечислимый тип - это такой тип данных, при котором количество всех возможных значений конечно. Строго говоря, все описанные выше типы являются перечислимыми.
Применение перечислимых типов преследует две цели:
|
1) улучшение смысловой читаемости программы;
2) более четкий и простой визуальный контроль значений.
Наиболее часто перечислимый тип используется для обозначения состояний конечных автоматов.
Перечислимый тип объявляется путем перечисления названий элементов-значений. Объекты, тип которых объявлен как перечислимый, могут содержать только те значения, которые указаны при перечислении.
Элементы перечислимого типа должны быть идентификаторами или символами, которые должны быть уникальными в пределах одного типа. Повторное использование названий элементов в других перечислимых типах разрешается.
Объявление перечислимого типа имеет вид:
TYPE имя__типа IS (название_элемента [, название_элемента});
Пример:
Type State_type IS (stateA, stateB, stateC); VARIABLE State: State_type;
State:= stateB
В данном примере объявляется переменная State, допустимыми значениями которой являются stateA, stateB, stateC.
Любой перечислимый тип имеет внутреннюю нумерацию: первый элемент всегда имеет номер 0, второй - номер 1 и т.д. Порядок нумерации соответствует порядку перечисления.
Значения определенных пользователем перечислимых типов могут участвовать в выражениях. Операторы отношения (=, /=, <, <=, >, >=) определены как для перечислимых типов, так и для одномерных массивов, содержащих элементы этих типов. Результат выражения имеет тип BOOLEAN.
К операндами перечислимых типов применим оператор указания типа. Данный оператор используется для уточнения типа объекта в случае, если одно и то же название элемента используется различными типами.
Массивы
Массив (тип «массив») является сложным типом. Массив представляет собой упорядоченную структуру однотипных данных. Массив имеет диапазон индексов, который может быть возрастающим либо убывающим. На любой элемент массива можно сослаться, используя его индекс.
|
Несмотря на то, что стандартом языка допускается использование массивов любой размерности, для синтеза ПЛИС используются только одномерные (поддерживаются всеми средствами синтеза) и двумерные (поддерживаются ограниченным числом средств синтеза) массивы.
Также можно сослаться на часть одномерного массива, используя вместо индекса диапазон индексов.
Существуют две разновидности типа «массив»: ограниченный (constrained) и неограниченный (unconstrained).
Объявление ограниченного типа определяет границы диапазона индексов (число элементов массива) в каждом измерении при определении типа.
Объявление неограниченного типа не определяет границы диапазона индексов. В этом случае границы диапазона устанавливаются при объявлении конкретного экземпляра объекта данного типа.
Объявление ограниченного типа «массив» имеет вид:
TYPE имя__типа IS
ARRAY (диапазон_индексов [, диапазон_индексов]) OF тип_элемента;
Примеры:
1) Объявление ограниченного массивного типа:
TYPE word IS ARRAY (31 DOWNTO 0) OF STD_LOGIC;
TYPE register_barik IS ARRAY (byte RANGE 0 TO 132) OF INTEGER;
2) Объявление неограниченного массивного типа:
TYPE logic IS ARRAY (INTEGER RANGE <>) OF BOOLEAN;
3) Объявление двумерного массива:
TYPE Reg IS ARRAY (3 DOWNTO 0) OF STD_LOGIC_VECTOR{7 DOWNTO 0);
TYPE transform IS ARRAY (1 TO 4, 1 TO 4) OF BIT;
Объявление объекта типа «неограниченный массив» должно содержать ограничения на индекс. Диапазон изменения индексов может быть ограничен: путем использования ключевых слов ТО или DOWNTO.
Атрибуты
Атрибуты определяют характеристики объектов, к которым они относятся. Стандарт VHDL предусматривает как предопределенные, так и определяемые пользователем атрибуты, однако современные инструментальные средства в большинстве своем поддерживают только предопределенные атрибуты. Для обращения к атрибутам объекта используется символ "'" (например, Al 'left),
В VHDL определены следующие атрибуты, относящиеся к массивам:
'left - левая граница диапазона индексов массива 'right - правая граница диапазона индексов массива 'low - нижняя граница диапазона индексов массива 'high - верхняя граница диапазона индексов массива 'range - диапазон индексов массива 'reversejrange - обращенный диапазон индексов массива 'length - ширина диапазона индексов массива
Помимо предопределенных, пользователь может вводить дополнительные атрибуты для сигналов и других типов данных.
Интерфейс и тело объекта
Полное VHDL-описание объекта состоит как минимум из двух отдельных описаний: описания интерфейса объекта и описания тела объекта (описание архитектуры).
Интерфейс описывается в объявлении объекта entity declaration и определяет входы и выходы объекта, его входные и выходные порты ports и параметры настройки generic. Параметры настройки отражают тот факт, что некоторые объекты могут иметь управляющие входы, с помощью которых может производиться настройка экземпляров объектов, в частности, могут задаваться времена задержки.
Например, у объекта Q1 три входных порта XI, Х2, ХЗ и два выхода У1, У2. Описание его интерфейса на VHDL имеет вид:
Entity Ql is
Port (XI, Х2, ХЗ: in real; Yl, Y2: out real);
End Ql.
Порты объекта характеризуются направлением потока информации. Они могут быть:
- входными (in)
- выходными (out)
- двунаправленными (inout)
- двунаправленными буферными (buffer)
- связными (linkage)
А также имеют тип, характеризующий значения поступающих на них сигналов:
- целый (integer)
- вещественный (real)
- битовый (bit)
- символьный (character)
Операторы
Исходный текст описания на VHDL состоит из последовательностей операторов, записанных с учетом следующих правил:
- каждый оператор - это последовательность слов, содержащих буквы английского алфавита, цифры и знаки пунктуации
- слова разделяются произвольным количеством пробелов, табуляций и переводов строки
- операторы разделяются символами ";"
- в некоторых операторах могут встречаться списки объектов, разделяемые символами "," или ";"
Комментарии могут быть включены в текст программы с помощью двух подряд идущих символов "—". После появления этих символов весь текст до конца строки считается комментарием.
Для указания системы счисления для констант могут быть применены спецификаторы:
- В - двоичная система счисления, например В"0011"
- О- восьмеричная система счисления, например О"3760"
- Н - шестнадцатеричная система счисления, например Н'ТбАО"
Параллельные операторы VHDL включают:
- оператор процесса process; оператор блока block;
- параллельный оператор назначения сигнала <=;
- оператор условного назначения сигнала when;
- оператор селективного назначения сигнала select;
- параллельный оператор утверждения assert;
- параллельный оператор вызова процедуры;
- оператор конкретизации компоненты port map;
- оператор генерации конкретизации generate;
Signal <= expression
Оператор присваивания сигнала устанавливает его значение равным выражению справа.
Variable: = expression
Оператор присваивания устанавливает значение переменной равным выражению справа.
If condition then
Sequence_of_statements { Elsif condition then
Sequence_of_statements } [ else
sequence_of_statements ] end if;
Оператор if используется для ветвления алгоритма по различным условиям,
Case expression is
When choices_list => sequence_of_statements;
{ When choices_list => sequence_of_statements; }
When others => sequence_of_statements; End case;
Оператор case., подобно оператору if, задает ветвление алгоритма. Значения в списках разделяются символом "("• Когда значение выражения встречается в одном из списков значений, выполняется соответствующая последовательность операторов. Если значение выражения не присутствует ни в одном из списков, то выполняется список операторов, соответствующий ветви when others.
[ loop _label: ]
for loop_index_variable in range loop
sequence_of_statements end loop [ loop_label ];
Оператор цикла позволяет многократно выполнить последовательность операторов. Диапазон значений задается в виде valuel to valm2 или value! downto valne2. Переменная цикла последовательно принимает значения из заданного диапазона. Количество итераций равно количеству значений в диапазоне.
Wait until condition;
Приостанавливает выполнение процесса, содержащего данный оператор до момента выполнения условия.
Return expression;
Этот оператор возвращает значение из функции
Задержка
Объект с задержкой можно представить как бы состоящим из двух элементов -идеального элемента и элемента задержки.
В языке VHDL встроены две модели задержек - инерциальная и транспортная.
Инерциальная модель предполагает, что элемент не реагирует на сигналы, длительность которых меньше порога, равного времени задержки элемента. Транспортная модель лишена этого ограничения.
Инерциальная модель по умолчанию встроена в оператор назначения сигнала языка VHDL. Например, оператор назначения Y<=X1 andX2 after 10 ns; описывает работу вентиля 2И и соответствует инерциальной модели. Указание на использование транспортной модели обеспечивается ключевым словом transport в правой части оператора назначения. Например, оператор YT< =tramport XI andX2 after 10 ns; отображает транспортную модель задержки вентиля.
Задержка может быть задана не константой, а выражением, значение которого может конкретизироваться для каждого экземпляра объекта, используемого как компонента. Для этого ее следует задать как параметр настройки в описании интерфейса объекта.
Приведенное ниже описание объекта 12 включает описание интерфейса и тела 12 с инерциальной задержкой, заданной как параметр настройки:
Entity 12 is
—параметр настройки Т по умолчанию равен 10 не.
Generic (Т: time = 10 ns);
Port (XI, Х2: in bit; Y: out bit);
End 12;
Architecture Al_inert of 12 is Begin
Y<= XI and X2 after T; End Al_inert;
Architecture Al_transport of 12 is Begin
Y<= transport Xland X2 after 10 ns; End;
Более сложной представляется ситуация, когда необходимо отобразить в описании архитектуры объекта тот факт, что задержки фронта и среза сигналов не совпадают или зависят от путей прохождения сигналов в схеме и ее предыдущего состояния.
При описании более сложных ситуаций следует учитывать особенности реализации механизма учета задержек сигналов в VHDL. С сигналом ассоциируется драйвер - множество сообщений о планируемых событиях в форме пар время - значение сигнала.
В случае транспортной задержки, если новое сообщение имеет время большее, чем все ранее запланированные, оно включается в драйвер последним. В противном случае предварительно уничтожаются все сообщения, запланированные на большее время.
В случае инерциальной задержки также происходит уничтожение всех сообщений, запланированных на большее время. Однако разница в том, что происходит анализ событий, запланированных на меньшее время, и если значение сигнала отличается от нового, то они уничтожаются.
Особый случай представляет ситуация, когда в процессах отсутствуют операторы задержки. Для этого в VHDL предусмотрен механизм так называемой дельта-задержки.
В случае дельта-задержек новый цикл моделирования не связан с увеличением модельного времени.
JK-триггер (fjkc)
architecture Behavioral of fjkc is
begin
process (C, CLR)
begin
if (CLR=’1’) then
Q <= ’0’;
elsif (C’event and C=’1’) then
if (J=’0’) then
if (K=’1’) then
Q <= ’0’;
end if;
else
if (K=’0’) then
Q <= ’1’;
else
Q <= not Q;
end if;
end if;
end if;
end process;
end Behavioral;