Изучение VHDL

Операнды в выражениях.


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

Простейшими операндами являются литерал и идентификатор, такой как имя сигнала или переменной. Само выражение может быть операндом, если его окружить круглыми скобками. Операндами могут быть также агрегат, атрибут, вызов функции, имя с индексом, квалифицированное имя, значение комбинированного типа и его поля, вырезка регулярного типа, функция преобразования типа. Далее подробно рассматриваются эти виды операндов.

Простое выражение чаще всего представляет собой имя объекта со знаком +,- или без него. Для многих операторов операнды должны быть простыми выражениями. Особенно это касается стиля программ для синтеза.

Агрегат. Агрегатом называется операция, которая объединяет одно или несколько значений в значение составного типа, т.е. регулярного или комбинированного типа. Его упрощенный синтаксис:
\агрегат\::=(\связывание элементов\ {,\связывание элементов\})
\связывание элементов\::=[\альтернативы\ =>] \выражение\
\альтернативы\::=\альтернатива\ {,\ альтернатива\}
\альтернатива\::=\простое выражение\|\диапазон\|\имя элемента\| others .

Связывание элементов означает подстановку одного выражения в одно или несколько заданных полей или элементов значений составного типа. Связывание элементов может происходить в порядке нумерации элементов cсоставного типа. Тогда оно называется позиционированным связыванием. Например, в объявлении:
variable v_5: bit_vector (0 to 4):=('0', '0', '0', '1', '1');
битам 0, 1 и 2 присвоено начальное значение 0, а битам 2,3 - значение 1. Если каждый элемент связывается со своим значением по имени, то такое связывание называется поименованным. Например, для той же переменной v_5:
(3 |4 => '1' , others => '0'); или (0 to 2 => '0'; 3 to 4 => '1');

Здесь ключевое слово others означает остальные элементы значения и должно стоять последним в списке связываний. Возможны и комбинированные агрегаты, в которых первые представляют собой позиционное связывание, а остальные поименованное связывание, например,
('0', '0',3 to 4 => '1' , others => '0').

Такая альтернатива, как простое выражение, применяется только для регулярных типов и должна определять номер элемента из диапазона этого типа, например, агрегат (i => '1', others => '0') задает вектор в котором на i-м месте стоит 1, а остальные биты - нулевые.

Альтернатива \имя элемента\ применяется только для комбинированных типов, например:


type complex is record ( Re : integer; Im : integer ); end record; variable X is complex:=(Re => 1000, Im => 0);

Атрибут. У объектов языка имеется некоторое множество свойств и особенных значений. Атрибут объекта - это специальная функция, которая возвращает его особенное значение. Например, атрибут object1'left возвращает значение самого левого элемента объекта object1 перечисляемого типа. Подробнее об атрибутах будет рассмотрено в разделе, посвященном атрибутам.

Вызов функции. При вызове функции выполняется функция с заданными значениями параметров. Упрощенный синтасис вызова функции:

\вызов функции\::=\имя функции\ ([\имя параметра =>\] \выражение\ {,[\имя параметра\ => ] \выражение\});

где \имя функции\ - имя функции, определяемой ранее, \имя параметра\ - не обязательный формальный параметр этой функции. Выражение - параметр функции - должно давать результат типа, соответствующий имени параметра. Параметры можно задавать с поименованным или позиционированным связыванием. При позиционированном связывании параметры-выражения подставляются в порядке, определенном порядком следования имен параметров в определении функции. При поименованном связывании каждое имя, параметра связывается с соответствующим параметром с помощью символов "=>", причем порядок следования параметров может быть произвольным.

Например, в пакете IEEE.Math_Real определена функция синуса:
function SIN (X : in REAL ) return REAL;
Ее вызов по аргументу вещественного типа выглядит как:
SIN(X=>MATH_2_PI* angle) или SIN(MATH_2_PI *angle) ,
где MATH_2_PI – константа, равная 2&#960, определенная в этом пакете.

Имя с индексом дает значение элемента регулярного ти-па, номер которого задается выражением в скобках. Например, vect(4) означает 4-й бит вектора vect, arr(i, j) означает элемент (i, j) двумерного массива arr.

Квалифицированное выражение. Результат выражения может принадле-жать нескольким типам одновременно. Если необходимо, чтобы этот результат принадлежал к конкретному типу, то его необходимо обозначить как квалифицированный с заданным типом. Синтаксис такого выражения:
\квалифицированное выражение\::=\имя типа\'(\выражение\)
Например, если объявлено
type vect is bit_vector(0 to 9); var X: vect;
то выражение ('1', others => '0') может принадлежать к типу векторов любой длины. Поэтому для присваивания переменной этого выражения необходимо сделать его квалифицированным:
X:=vect'('1', others => '0');
Имя-вырезка задает цепочку элементов объекта регулярного типа. Его упрощенный синтаксис:
\имя-вырезка\::=\имя\(\выражение\ to | downto \выражение\)
\выражение\ - должно вычислять значение, не превосходящее диапазон индексов объекта регулярного типа с именем \имя\. Направление изменения индекса to или downto должно совпадать с направлением, заданным в объявлении типа. Например, если объявлен сигнал:
signal A: bit_vector(15 downto 0);
то A(15 downto 8) - старший байт сигнала А.

Поле комбинированного типа. Чтобы оперировать с полем объекта комбинированного типа его вставляют в выражение согласно синтаксису:
\поле комбинированного типа\::=\имя комбинированного типа\.\имя поля\
где \имя поля\ - может представлять поле любого типа, а также его имя с индексом, имя - вырезку, агрегат. Например, если объявлены тип и сигнал:

type comp_vect is record (Re: bit_vector(0 to 15); Im:bit_vector(0 to 15)); end record; signal A: comp_vect; то A.Re(0 to 7) - старший байт поля Re сигнала A типа cоmp_vect.

Преобразование типа. Так как в VHDL присваивание значения объекту требует строгого соответствия типов, то в случае, если типы объектов не совпадают, необходимо выполнить преобразование типа. Его синтаксис соответствует синтаксису вызова функций с одним аргументом.

Различают два вида преобразования типа: переход типа и вызов функции преобразования типа. Переход типа применяется для преобразования тесно связанных типов или подтипов. Такими парами типов являются, например, real и integer, integer и natural, регулярные типы с одинаковым числом элементов того же самого типа с одинаковыми диапазонами индексов. Например, при переходе из значения с плавающей запятой к целому значению:
С:=integer (123.5);
результат С округляется до ближайшего целого, т.е. до 124.

Если типы не тесно связанные, то необходимо выполнить вызов функции пре-обра-зо-ва-ния типа. Например, типы boolean и bit - не тесно связанные т.к. при-над-ле-жат к перечисляемым типам с различными множествами элементов. По-это-му, например, преобразование переменной Х типа boolean в переменную Y типа bit может выполняться функцией преобразования типов, которая включает оператор:
if Х then Y:='1'; else Y:='0'; end if;

Часто программисты пользуются своими функциями преобразования типов. Большинство стандартных и коммерческих библиотек содержат наборы функций преобразования типов.

Содержание раздела