Function"and"(xl,x2:bit) returnboolean is begi n

return (xland x2) ='1'; end;

Если эта функция объявлена, то теперь транслятор не выдаст со­общения об ошибке при выполнении оператора if, вызывающего эту функцию:

Variablea,b,c: bit; if (a and b and c) then

* *

end if; так как выражение в скобках будет иметь правильный тип boolean.


Реализация процедур и функций в аппаратуре

Компиляторы-синтезаторы, как правило, транслируют процедуру или функцию в комбинационную схему. Процедуры с операторами wait не допускаются, например, такие, которые симулируют схему с памятью.

Атрибуты

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

Атрибут объекта записывается как:

\имя объектах1 \имя атрибутах .

Ниже рассматриваются основные предопределенные атрибуты.

Атрибуты для скалярного типа

Для скалярного типа т предопределены следующие атрибуты:

т' left - самое левое значение множества элементов скалярного типа т. т' right - самое правое значение множества элементов типа т. T'high - наибольшее значение в множестве элементов типа т. Т' low - наименьшее значение в множества элементов скалярного типа т. T'image(x) - функция строкового представление выражения х типа т. T'value(x) - функция значения типа т от строкового представления х. T'pos(x) - функция номера позиции элемента х типа т. T'val (х) - функция значения элемента типа т стоящего в позиции X.

Примеры атрибутов:

type st is (one,two,three);

st'right = three, st'pos(three) = 2, st'val(l) = two. positive'low * 1, positive'high =2147483647. integer'valueC'LOOO") =1000, integer'image(330) ="330".


Атрибуты для регулярного типа

Для регулярного типа а предопределены следующие атрибуты:

A'left[(N)] - левое значение диапазона индексов по N-й размерности.

A' right[(n)] - правое значение диапазона индексов по N-й размерности.

Afhigh[(N)] - наибольшее значение диапазона индексов по N-й размерности.

А' 1 cw [ (n) ] - наименьшее значение диапазона индексов по N-й размерности.

A' range[(N)] - диапазон индексов по N-й размерности.

A' reverse_range[(N)] - обратный диапазон индексов по N-й размерности.

A' length[(N)] - протяженность диапазона индексов по N-й размерности.

A'ascending[(N)] - функция, равная true, если диапазон индексов He-N-й размерности - возрастающий.

Примеры применения атрибутов:

type s2 is array(2 downto 1, 0 to 3) of integer;

S2'left(l) - 2, s2'right(2) - 3,

S2'high(l) * 2, s2'low(2) = 0,

s2'range(2) = 0 to 3, s2'reverse_range(l)- 1 to2,

S2'length(2) = 4.

Атрибуты сигналов

Атрибуты сигналов s:

S' stable [CO] - сигнал, равный true, если за промежуток време­ни т не было событий у сигнала S.

S'transaction - сигнал типа bit, меняет значение на противопо­ложное в циклах моделирования, в которых было присваивание нового значение сигналу S.

s'event - сигнал, равный true, если произошло событие в сигнале S в данном цикле моделирования.

sfactive - сигнал, равный true, если произошло присваивание нового значение сигналу s в данном цикле моделирования.

S'last_value - сигнал такого же типа, что и S, содержащий зна­чение s до последнего события в нем,

Примером применения атрибутов сигналов является следующий процесс, моделирующий синхронные триггеры.


Process(CLK) begin

if CLK='l' andCLK'event then--D- триггер

ql<=al;
endif;
if notCLK'stable then-- D- триггер

q2<=a2; endif; if CLK'last_value /= CLK then--D- триггер

q3<=a3;
endif;
if CLK'active -- D- триггер

q4<=a4;
endif;
q5<=CLK'transaction; — т- триггер

end process;

Атрибуты пользователя

Эти атрибуты предназначены для присваивания объектам языка дополнительных свойств, не предусмотренных встроенными типами и атрибутами. При проектировании дискретных устройств такими свойствами могут быть: способ кодирования состояний автомата, указания компилятору-синтезатору по управлению оптимизацией, размещению блоков, их исполнению, назначение портов номерам выводов, начальное состояние схем памяти и т.п. Т.е. эти свойства не связаны напрямую с алгоритмом, реализуемым в программе. За­дание атрибута состоит из его объявления и спецификации.

Объявление атрибута имеет синтаксис, похожий на объявление переменной:

\объявление атрибутах::=attribute\идентификатор\: \ тип\

где \тип\ - любой ранее определенный тип, например, string, positive, time.

Спецификация атрибута имеет синтаксис:

Хспецификация атрибутах::=attribute\идентификатор\ of \имя объектах[{Димя объекта\}] | othersI all: \класс объекта\ is\выражение\ \имя объекта\::= ((\идентификатор\ |\символьный литерал\

| \символ оператора\) [\сигнатура\]) \класс объекта\::- entity|architecture|configuration| package I procedure|function[type 1 subtype[ constant|si gnal jvari able | f i 1 e |component| label (literal |units I group

Здесь \идентификатор\ - имя атрибута, объявленного ранее, \имя объекта\ - имя объекта, которому присоединен атрибут,\сигнатура\ -


список типов параметров, если объектом является процедура, функ­ция или перечисляемый литерал, предназначенный для идентифи­кации перегружаемых процедур, функций и литералов. Специфика­ция атрибута обычно вставляется сразу же после объявления этого атрибута.

Атрибуты пользователя обычно не влияют на поведение модели и такие атрибуты игнорируются симулятором. Но они имеют большое значение для компилятора-синтезатора и для средств реализации схемы в кристалле. Поэтому, как правило, фирмы-поставщики ком­пиляторов и производители микросхем предлагают для использова­ния свои наборы атрибутов пользователя. В следующем примере ат­рибут указывает способ кодирования состояний автомата:

type\состояние\ is ( \сброс\ Дначало\,\работа\,\конеи.\); attributeenum_encoding : string;

attributeenunuencoding of \состояние\: type is "000 001 010100" ;

Атрибут foreign

Специальный атрибут foreign присоединяется к архитектуре, процедуре или функции. Он указывает симулятору, что соответст­вующий объект должен моделироваться особенным способом. Это может быть специальная программа на ассемблере или другом язы­ке, или аппаратный ускоритель.

Структура программы на VHDL

Дискретная система может быть представлена в VHDL как объект проекта. Объект - это основная составная часть проекта. Объект может быть использован в другом проекте, который, в свою очередь, описан как объект или может являться объектом более высокого уровня в данном проекте. Симулятор может моделировать ВУ, толь­ко если оно оформлено в виде объекта проекта.

Объект проекта описывается набором составных частей проекта, таких как: объявление объекта, тело архитектуры объекта (или про­сто архитектура), объявление пакета, тело пакета и объявление конфигурации. Каждая из составных частей объекта может быть скомпилирована отдельно. Составные части проекта сохраняются в одном или нескольких текстовых файлах с расширением .VHD. В одном файле может сохраняться несколько объектов проекта.

Объект проекта обычно описывается согласно синтаксису:


\объект проекта\::= [\описание 1ibrary\]

[\описание use\]

\объявление объекта\

\тело архитектуры\

[\объявление конфигурации\] [\описание library\]::= library \идентификатор\ {, \идентификатор\};

где идентификаторы - названия библиотек, которые используются в объекте проекта. Они указывают транслятору местоположение этих библиотек. Описание useуказывает, какие пакеты и какие элементы этих пакетов могут быть использованы в объекте. Части объекта проекта могут компилироваться раздельно. Но перед связыванием (elaboration) все части должны быть уже скомпилированы.

Объявление объекта

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

\объявление объекта\::= entity \идентификатор\ is

[депеп"с(\объявление настроечной константы\

{; \объявление настроечной константы\});] [port (\объявление порта\ {Добъявление порта\});]

{\объявление в объекте\} [begin

{\оператор assert\ | \пассивный вызов процедуры\

| \пассивный процесс\ }] end [entity][\идентификатор\];

Здесь \идентификатор\ - имя объекта. Синтаксис объявления на­строечной константы и объявления порта рассмотрены в разделе описания объектов и типов языка. Порты представляют собой ин­терфейсные сигналы объекта проекта. Настроечные константы genericкодируют определенные свойства объекта проекта, напри­мер, разрядность линий связи, параметры задержки, кодирование структуры моделируемого устройства.

Объявленными в объекте могут быть: объявление и тело процеду­ры или функции, объявление типа и подтипа, объявление глобаль­ной переменной, файла, псевдонима, константы, объявление и спе­цификация атрибута, объявление группы, описание use.

В исполнительной части, которая открывается словом begin, вставляются параллельные операторы, которые не выполняют при­сваиваний сигналам, т.е. не влияют на поведение объекта. Поэтому


такие вызовы процедуры и процессы называются пассивными. Наи­более частое применение этих операторов - проверка соответствия входных сигналов, поступающих через порты, заданным требовани­ям или соответствие включения объекта в окружение, задаваемое ограничениями на настроечные константы generic. Например, про­веряется время предустановки сигнала относительно фронта синхро-серии, соответствие его уровней, разрядность входных данных и т.п. При несоответствии сигналов или настроечных констант, оператор assert выдает сообщение об ошибке.

Рассмотрим пример объявления объекта RS-триггера:

entity RS_FF is

generic(delay:time); port(R, S: in bit;

Q: out bit:='0'; nQ: out bit:='l'); begin

assert (R andS) /='1' report"in rs_ff r=s=1" severity error; endentity RS_ff;

В нем настроечная константа delay задает параметр задержки, например, от входа до выхода, который будет подставлен при ком­пиляции на этапе связывания компонентов. Порты R,S имеют режим ввода in, а порты Q,nQ - режим вывода out. При единичных сигна­лах на обоих входах, т.е. когда RS-тригтер функционирует непра­вильно, оператор assert выдает сообщение об ошибке.

Архитектура объекта

Архитектура объекта представляет собой отдельную часть, в ко­торой описано, каким образом реализован объект. Ее синтаксис:

\тело архитектуры\::= architecture \идентификатор\ of \имя объекта\ is

{\объявление в 6локе\} begin

{ \параллельный оператор\} end[architecture][\идентификатор\];

Идентификатором обозначается имя конкретного тела архитекту­ры. Одному объекту проекта может соответствовать несколько архи­тектур, в каждой из которых описан один из вариантов реализации объекта. Поэтому имя объекта указывает, который из объектов опи­сан в этом теле архитектуры. Объявление в теле архитектуры такое же, как в операторе блока, который описан ниже. Им может быть: объявление и тело процедуры или функции, объявление типа и под­типа, объявление файла, псевдонима, константы, глобальной пере­менной, объявление и спецификация атрибута, объявление группы,


описание use, а также объявление компонента. Объявленные в теле архитектуры типы, сигналы, подпрограммы видимы только в преде­лах этой архитектуры.

Исполнительную часть архитектуры составляют параллельные операторы, такие как процесс, блок, параллельное присваивание сигналу и др. Так как все операторы в исполнительной части тела архитектуры - параллельные, их взаимный порядок - безразличен. Хорошим стилем считается, когда параллельные операторы ставятся в последовательности, соответствующей нумерации вершин граф-схемы алгоритма, реализуемого в архитектуре.

Примером тела архитектуры служит архитектура для вышепри­веденного объявления объекта RS-триггера:

architecture behav of rs_ff is begin

processes,R)

variable qi: bit; begin

if S^'l' then

qi:='l' ; elsif R='l' then

qi:='0'; end if;

Q<=qi after delay; nQ<=not qi after delay; end process; end architecture behav;

Данную программу, включающую объявление объекта и тело ар­хитектуры можно транслировать и моделировать. Если из объявле­ния объекта удалить исполнительную часть и описание generic, то программа будет написана синтезируемым стилем и ее можно также компилировать в логическую схему.

Объявление компонента

Объявление компонента в теле архитектуры необходимо, если в архитектуре используется оператор вставки этого компонента, кото­рый будет рассмотрен ниже. Синтаксис объявления компонента сле­дующий :

\объявление компонентах::= component \идентификатор\ [is] [депеп'с(\объявление настроечной константы\

{; \объявление настроечной константы\});] [port (\объявление порта\ {Добъявление порта\});] end component [\идентификатор\];


Объявление пакета

В пакет обычно объединяются декларации различных объектов и типов языка, связанных общим признаком. Затем декларации из пакета можно повторно использовать в различных частях проектов, ссылаясь на этот пакет. Многие пакеты стандартизированы и их ис­пользование упрощает разработку новых проектов, а также служит для стандартизации включения и тестирования этих проектов. Не­сколько пакетов, подчиненных одной цели, собирают в библиотеку library. Библиотека, в которой собраны программы и пакеты поль­зователя, по умолчанию имеет название WORK.

Синтаксис объявления пакета:

\объявление пакета\::= package\идентификатор\ is

{объявление в пакете} end[package][\идентификатор\];

В объявлении пакета могут быть объявленными объявление про­цедуры или функции, объявление типа и подтипа, объявление фай­ла, псевдонима, константы, глобальной переменной, объявление и спецификация атрибута, объявление компонента, объявление груп­пы, описание use.

Обычно в объявлении пакета объявляются типы, используемые во всех объектах проекта или ряда проектов. Если объявлены про­цедуры и функции, то их спецификации описываются в теле пакета. Т.е. объявление пакета представляет собой интерфейс пакета, также как объявление объекта - это интерфейс объекта проекта.

Константам может быть не присвоено значение. Такие константы называются отложенными (deferred). Например, это могут быть за­ранее неопределенная кодировка состояний или разрядность шин. Тогда эти константы должны получить значение в теле пакета.

При обращении к объектам с одинаковым именем, принадлежа­щим разным библиотекам, необходимо использовать селективное имя объекта, указывающее, какой библиотеке оно принадлежит, например:

signal my_bit: IEEE.std_logic_1164.x0lZ;

Тело пакета

Тело пакета необходимо приводить в паре с объявлением пакета, если в последнем объявлены подпрограммы или отложенные кон­станты. Обычно объявление и тело пакета оформляют в одном фай­ле. Тело пакета имеет синтаксис:


\тело пакета\::= package body\идентификатор\ is

{объявление в теле пакета} end [package body][\идентификатор\];

В объявлениях тела пакета должны быть приведены полные спе­цификации процедур и функций, присваивания константам, кото­рые задекларированы в объявлении этого пакета.

Ниже приведен пример пакета функций и констант, который удобно применять для упрощения программирования логики с бу­левскими и битовыми типами.

packageshort_boolean is

constantbO:boolean:=false; —псевдоним для false constantbl:boolean:=true; --псевдоним для true functionb(x:bit) returnboolean;— преобразование из bit в boolean function"not"(x:bit) returnboo7ean; —функции вместо not, and, or function"and"(xl,x2:bit) returnboolean ; functionMor"(xl,x2:bit) returnboolean ; end package; package bodyshort_boolean is