Ревизии языка: IEEE Standard VHDL Language Reference Manual
Связанные стандарты:
Описывать ЦУ можно, используя разные стили:
A <= B and C;
В качестве разделителей в данном примере используются пробелы, однако нет необходимости иметь разделитель между оператором " ; " и лексическим элементом "C".
Комментарий начинается с двух смежных дефисов и продолжается до конца строки. Комментарии не учитываются при моделировании VHDL-описаний и синтезе схем по VHDL-описаниям.
Для задания синтаксических конструкций языка VHDL используются так называемые формы Бэкуса-Наура, служащие для описания грамматик формальных языков. Для определения синтаксической конструкции используется выражение
<синтаксическая конструкция>::=<определение>
Используемые фигурные скобки служат для обозначения повторения выражения, заключенного в них. Выражение может повторяться k раз (k=0,1,2, ...). При k=0 выражение отсутствует.
Вертикальная черта служит для обозначения альтернативных случаев. Например,
letter_or_digit ::= letter|digit,
т.е. синтаксическая конструкция символ_или_число определяется как символ (letter) или цифра (digit).
В случае, например,
choices::=choice{|choise},
когда в фигурных скобках стоит то же выражение (с символом «вертикальная черта»), это означает повторение того же выражения. В данном примере повторяется выражение «choice».
Квадратные скобки служат для обозначения необязательного выражения или необязательного слова. Например, запись
return_statement::=return[expression];
эквивалентна записи
return_statement::=return;|return[expression];
Например, элементы type_name и subtype_name могут рассматриваться просто как name (имя). В случае type_name подчеркивается, что это имя типа, в случае subtype_name, что это имя подтипа.
Определение идентификатора
basic_identifier ::= letter { [ underline ] letter_or_digit }
Идентификаторы употребляются как пользовательские имена и ключевые слова.
Идентификатор должен начинаться с буквы (не цифры). Может употребляться кроме букв и цифр, знак подчеркивания. Два подряд идущих подчеркивания не допускаются.
! В VHDL-коде нет различия между прописными и строчными буквами. AbC7 эквивалентно aBC7, A_3 не эквивалентно A3.
Идентификатор не должен оканчиваться подчеркиванием.
Неправильные идентификаторы
7AB (начинается с цифры) A@B (специальный символ @) SUM_(кончается подчеркиванием) PI__A (два подчеркивания подряд)
Правильные идентификаторы
Carry_OUT Dim_Sum Count7SUB_2goX AaBBb
Как и многие другие языки программирования, VHDL имеет ключевые (специальные) слова.
Список ключевых слов (стандарт VHDL’87)
abs | access | after | alias | all |
and | architecture | array | assert | attribute |
begin | block | body | buffer | bus |
case | component | configuration | constant | disconnect |
downto | else | elsif | end | entity |
exit | file | for | function | generate |
generic | guarded | if | in | inout |
is | label | library | linkage | loop |
map | mod | nand | new | next |
nor | not | null | of | on |
open | or | others | out | package |
port | procedure | process | range | record |
register | rem | report | return | select |
severity | signal | subtype | then | to |
transport | type | units | until | use |
variable | wait | when | while | with |
xor |
В стандарт VHDL’93 добавлены следующие слова:
group | impure | inertial | literal | postponed |
pure | reject | rol | ror | shared |
sla | sll | sra | srl | unaffected |
xnor |
Литералы - константные числовые значения в языке VHDL. Десятичный литерал может быть целым, вещественным или вещественным с экспонентой.
Примеры
Целые литералы:
21, 0, 1Е2, 3e4, 123_000.
Вещественные литералы:
11.0, 0.0, 0.468, 3.141_592_6.
Вещественные литералы с экспонентой:
1.23E-11, 1.0E+4, 3.024E+23.
Знак экспоненты E может быть строчным либо прописным. Подчеркивание в десятичном литерале не является значащим. Экспонента для целого литерала не должна иметь знак минус. Базовый литерал указывает на систему счисления: от двоичной до шестнадцатеричной:
Форма представления | Литерал | Комментарий |
---|---|---|
Двоичная | 2# 1111_1100# | Все эти литералы имеют значение 252 |
Шестнадцатеричная | 16# fc# | |
Шестнадцатеричная | 016# 0FC# | |
Десятичная | 10#252# | |
Семеричная | 7# 510# |
Число 16#6#E1 означает 6*16**1 – это число 9610 в десятичной системе счисления: 9610 = 6 × 161. Символ * – знак умножения, ** – возведение в степень. Число 2E-3 не является целым, 3e4 – это число 3 × 104
Символьный литерал формируется одним из символов (букв) между апострофами:
'A','a','%', (литерал - апостроф), ' ' (пробел);
'A' отличается от 'a' в случае символьного литерала.
Строковый литерал формируется как последовательность букв (возможно пустая) между двумя кавычками, употребляемыми как строковые скобки.
Строковый литерал должен располагаться в одной строке. Для формирования "длинных" строковых литералов может быть употреблена операция конкатенации & (напомним, что для оператора логического И употребляется оператор AND).
Литерал "строка бит"
Литерал "строка бит" формируется как последовательность цифр 0, ... , 9, A, ... ,F (или a, ... , f) между двумя кавычками. Подчеркивание в таком литерале не является значащим.
Литерал "строка бит" может быть
B – бинарным; O – восьмеричным; X – шестнадцатеричным.
Очевидно, вместо прописных букв B, O, X могут употребляться строчные буквы b, o, x.
Длина строкового битового литерала есть число бит в последовательности, представляющей литерал. Для примера:
ниже все литералы имеют длину 12
X"F_FF", O"7777", B"1111_1111_1111"
Примеры
B"1010110" -- длина 7 O"126" -- эквивалентно B"001_010_110", длина 9 X"56" -- эквивалентно B"0101_0110", длина 8
Приоритет | Классы операторов |
Операторы |
---|---|---|
0 (низкий) | Логические | and, or, nand, nor, xor, xnor |
1 | Отношения | =, <, >, <=, >=, /= |
2 | Сдвиги | sll, srl, sla, sra, rol, ror |
3 | Сложение | +, –, & |
4 | Унарные | +, – |
5 | Умножение | *, /, mod, rem |
6 (высокий) | Вспомогательные | **, abs, not |
Описание системы на VHDL реализуется в двух основных частях:
Подключение библиотеки IEEE и пакета std_logic_1164 из неё. | library ieee; use ieee.std_logic_1164.all; |
интерфейс (entity) – описание взаимодействия между системой и ее окружением |
entity block2 is port ( x : in std_logic_vector(2 downto 0); y : out std_logic_vector(1 downto 0)); end block2; |
архитектура (architecture) – описание поведения (функциональности) системы | architecture beh of block2 is begin -- beh y(0) <= (not x(2) and not x(1)) or (x(1) and not x(0)); y(1) <= not x(1) and not x(0); end beh; |
when..else
architecture tabl of block1 is begin -- комментарий y <= "11" when x = "000" else "01" when x = "001" else "01" when x = "010" and x = "110" else "00"; end tabl; * важен порядок, срабатывает первое верное условие
Поскольку этот язык используется для представления аппаратных проектов в самых разных вариантах, средства типизации данных приобретают здесь особенно важное значение. Например, они дают разработчику возможность представить группу линий (проводников) шины в виде
В языке VHDL реализована строгая типизация. Это означает, что смешение различных типов в одной операции является ошибкой. Средства строгого контроля типов играют ответственную роль, поскольку позволяют уточнять намерения разработчика.
Тип – поименованное множество значений с некоторыми общими характеристиками.
Подтип – подмножество значений данного типа.
Например, тип NATURAL есть подтип типа INTEGER.
Ниже дана классификация типов языка VHDL.
Типы определяются обычно в
|
type byte_int is range 0 to 255; type signed_word_int is range –32768 to 32767; type bit_index is range 31 downto 0;
В пакете STANDARD ('93), поставляемом с системами моделирования и синтеза, декларируются типы BOOLEAN, BIT, BIT_VECTOR, INTEGER, POSITIV, NATURAL, CHARACTER, STRING, а также тип TIME.
Логические Типы | Арифметические типы | Символьные типы |
---|---|---|
BOOLEAN (булев) | INTEGER (целый) | CHARACTER (символьный) |
BIT (битовый) | POSITIV (положительный) | STRING (строковый) |
BIT_VECTOR (битовый вектор) | NATURAL (натуральный) | - |
- | REAL (вещественный) | - |
type INDEX is range 0 to 9; -- тип целый, type VOLTAGE is range 0.0 to 10.0; -- тип вещественный.
![]() |
Исходный код пакета Standard (2019) |
type TIME is range 0 to 1E20 units fs; -- femtosecond ps = 1000 fs; -- picosecond ns = 1000 ps; -- nanosecond us = 1000 ns; -- microsecond ms = 1000 us; -- millisecond sec = 1000 ms; -- second min = 60 sec; -- minute hr = 60 min; -- hour end units;
type logic_level is (unknown, low, undriven, high); type alu_function is (disable, pass, add, subtract, multiply, divide); type octal_digit is ('0', '1', '2', '3', '4', '5', '6', '7');
type severity_level is (note, warning, error, failure); type boolean is (false, true); type bit is ('0', '1');
type word is array (31 downto 0) of bit; type memory is array (address) of word; type transform is array (1 to 4, 1 to 4) of real; type register_bank is array (byte range 0 to 132) of integer;
Тип BIT_VECTOR определяет массив битов, например BIT_VECTOR (0 to 7). Тип BIT_VECTOR есть тип массива, который неявно описывается следующим образом:
type BIT_VECTOR is array (NATURAL range <>) of BIT;
BIT – базовый тип элементов массива, выражение NATURAL range (диапазон натуральный) – это стандартный способ указать, что длина массива будет задаваться диапазоном натуральных чисел.
Пользователь должен задавать конкретный диапазон при применении такого типа, например,
signal DataBus: bit_vector (7 downto 0);
1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | |
---|---|---|---|---|---|---|---|---|
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | номер разряда |
DataBus = "10010101" DataBus(7)=’1’ DataBus(6)=’0’ DataBus(5)=’0’ DataBus(4)=’1’ DataBus(3)=’0’ DataBus(2)=’1’ DataBus(1)=’0’ DataBus(0)=’1’
Пример двумерного массива.
Type TWO_DIMENSION is array (natural range <>, natural range <>) of bit;
Записи Тип "запись" – это составной тип, состоящий из ряда полей. Примеры декларации типа "запись".
type instruction is record op_code : processor_op; address_mode : mode; operand1, operand2: integer range 0 to 15; end record; type Instr_T is record Mnemonic: String (0 to 5); Code: Bit_vector (3 downto 0); ExeCycles: Integer; end record;
signal Instr1, Instr2, Instr3: Instr_T;
Например, тип DATE (дата) можно описать как тип "запись" следующим образом:
type DATE is record DAY: INTEGER range 1 to 31; MONTH: MONTH_TYPE; YEAR:INTEGER range 0 to 3000; end record;
Здесь MONTH_TYPE (имя месяца) – это перечислимый тип, содержащий имена месяцев.
VHDL предусматривает определенные типы файлов (FILE) и типы доступа (ACCSESS).
Подтип определяется как тип с ограничением (уточнением) следующим образом
subtype имя подтипа is базовый тип [уточнение];
Например, пусть базовый тип определен так
Type big_integer is range 0 to 2000;
Тогда подтип small_integer может быть определен так
Subtype small_integer is big_integer range 0 to 15;
Смешение типов в VHDL – это ошибка. Однако значения подтипа могут быть переданы типу (конверсия типов). Пример.
Type big_integer is range 0 to 2000; Subtype small_integer is big_integer range 0 to 15; Signal intermediate : small_integer; Signal final : big_integer; . . . Final <= intermediate * 5; -- нет ошибки, конверсия типов
В данном фрагменте VHDL-кода нет ошибки, так как small_integer есть подтип базового типа big_integer. Если же типы определяются независимо друг от друга, то присвоение значений одного типа другому невозможно, т.е. приводит к ошибке. Пример.
Type big_integer is range 0 to 2000; Type small_integer is range 0 to 15; Signal intermediate : small_integer; Signal final : big_integer; . . . Final <= intermediate * 5; -- ошибка, смешение типов
Сигнал типа std_logic может принимать значения:
Особенности:
Имеются три класса объектов языка VHDL:
С помощью объектов языка VHDL описываются объекты проекта, т.е. различные подсистемы проектируемой (моделируемой) цифровой системы.
Декларация константы.
Общий вид конструкции, употребляемой при декларации констант одного и того же типа
constant список констант : тип [ := выражение] ;
В VHDL константы подобны константам в других языках программирования. Примеры декларации констант.
constant PERIOD: time:=100 ns; constant PI: real:= 3.14159; constant WIDTH: integer:=32; constant DEFAULT: bit_vector(0 to 3):= "0101"; constant a, b, c, d : integer := 5;
Каждая из декларированных в последней строке констант a, b, c, d равна 5. Если символов ":=" нет в декларации константы, то константа называется задержанной. Такие константы могут быть в разделе деклараций пакета. Соответствующая полная декларация появляется в теле пакета. Если в VHDL-коде символы ":=" следуют после выражения, то выражение принимает значение объекта, находящегося справа от данных символов, при этом, естественно, не должно быть смешения типов.
Декларация переменной
Общий вид конструкции, употребляемой при декларации переменных
variable список переменных : тип [ := выражение];
Переменная в VHDL подобна идентификатору, употребляемому в других языках программирования высокого уровня. Значение переменной может быть инициализировано и изменено немедленно после выполнения предложения, присваивающего переменной новое значение. Примеры декларации переменных.
variable ROM, COLUMN: integer range 0 to 31; variable COUNT : positive :=100; variable MEMORY : TWO_DIMENSION (0 to 15, 0 to 31); variable a, b, c, d: bit :='1';
Каждая из декларированных в последней строке битовых переменных a, b, c, d равна '1'.
Декларация сигнала
Общий вид конструкции, употребляемой при декларации сигналов одного типа
signal список сигналов : тип [register | bus] [ :=выражение];
В необязательной опции [register | bus] может быть указано только одно из ключевых слов – либо слово register, либо слово bus. Концепция сигнала в VHDL является одной из самых важных. Сигналы подобны (соответствуют) физическим линиям (проводникам), которые соединяют элементы схемы. Сигналы и переменные будут рассмотрены далее. Примеры декларации сигналов.
signal CLK, RESETn: bit; signal COUNTER: integer range 0 to 31; signal RAM : TWO_DIMENSION (0 to 15, 0 to 31); signal INSTRUCTION: bit_vector (15 downto 0); signal a, b, c, d: bit :='0';
Как видно из последней строки примера, сигналам при декларации может быть присвоено начальное значение.
Декларация компонента
Общий вид конструкции, употребляемой при декларации компонента
component имя компонента generic (список параметров); port (список портов); end component;
Список портов, начинающийся с ключевого слова port, определяет имя, направление (режим – mode) и тип каждого порта. Тип порта – это тип сигнала, ассоциированного с данным портом. Направление порта может
быть: in – входной порт, out – выходной, inout – двунаправленный, linkage, buffer. Компоненты, имеющие направления портов linkage или buffer, рассматриваться не будет. Компоненты декларируются в
архитектурном теле прежде оператора begin. Ключевое слово generic служит для передачи параметров, чаще всего таких, как разрядность, число полюсов и других настраиваемых параметров. Примеры настраиваемых параметров
будут даны позже. Компонент является частью проекта. Его реализация осуществляется соответствующим entity и одним либо несколькими архитектурными телами.
! В entity и декларируемом компоненте должны совпадать спецификации.