Function Mor"(xl,x2:bit) return boolean is begi n

return (xl or x2) ='l'', end; end package body;

Теперь, если данный пакет присоединить к объекту проекта с по­мощью описаний library и use, то подстановка констант и функций этого пакета во многих местах, например, в операторах if, when со­кращает запись программы.

Описание use

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


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

\описание use\::= use \селективное имя\ {, \селективное имя\ };

\селективное имя\::= \имя1\. \имя2\

\имя2\::= \идентификатор\ | \символьный литерал\ |аП

Здесь \имя1\ представляет собой обозначение места, где находит­ся объект, который должен быть видимым. Чаще всего это иденти­фикатор библиотеки и идентификатор пакета в ней, разделенные точкой. Идентификатор - название объекта, который должен быть видимым, символьный литерал - символьное имя функции, напри­мер, "*". Ключевое слово all означает, что видимы все объекты, объявленные в указанном месте. Например, чтобы были видимы функции сложения и вычитания из пакета std_7ogic_arith библио­теки IEEE используют описание:

use IEEE.std_logic_arith.,,-n, iEEE.std_logic_arith."+" ;

а если все объявления из этого пакета должны быть видимыми то используют use IEEE.std_logic_arith.all;

Псевдонимы

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

\объявление псевдонимах::= alias \идентификатор\ |

символьный литерал\ | \символ оператора\ [:\подтип\] is \имя\ [\сигнатура\];

Наиболее часто псевдоним дают константам, переменным и сиг­налам. Например, псевдоним

alias COP: bit_vector(7 downto0) isINSTRUCTION(31 downto24);

помогает обращаться с полем кода операции сор команды instruction как с отдельным сигналом, не объявляя этот сигнал. При этом бит сор(7) равен биту instruction(31) .

j. акуке псевдоним можно присваивать типу. Например, если дать псевдоним

alias vect is std_logic_vector;

то можно сократить текст программы, объявляя сигнал типа vect вместо std_logic_vector, правда, при этом ухудшится чтение её дру­гими программистами.


Можно давать псевдоним функциям и процедурам. Например:

alias to_v is conv_std_logic_vector

[integer, integer return std_logic_vector];

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

Часто псевдоним дают длинным селективным именам, которые обозначают объекты, принадлежащие различным библиотекам, как например:

alias PI is IEEE.math_real.math_pi ;

- это псевдоним константы числа пи.

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

Метки в программе

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

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

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

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

При моделировании симулятор работает со скомпилированной программой, в которой всем параллельным операторам поставлены


метки. Если у оператора не было метки, то симулятор ставит метку по своему усмотрению, например, номер строки. По этой метке про­граммист ищет в модели переменные и сигналы, изменяемые в опе­раторе. Поэтому удобнее это делать по метке, название которой по смыслу указывает на место в программе.

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

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

Объявление конфигурации

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

\объявпение конфигурации::=

configuration \идентификатор\ of \имя объекта\ is for \имя архитектуры\

{for Хуказатели вставки компонентах: \имя компонентах Хуказатель связываниях; end for;} end for; end [configuration] [\идентификатор\];

\ указатели вставки компонента \::=\метка вставки компонентах

{Дметка вставки компонентах} | others | all Хуказатель связываниях::= use entity

\имя объектах [(^идентификатор архитектуры\)]

При разработке вычислительного устройства его обычно тестиру­ют на различных этапах проектирования с помощью одного и того же испытательного стенда (test bench), который также описан с по­мощью пары объект-архитектура, например, alu_tb(tb_arch). В этом случае вставленный в испытательный стенд компонент тести-


руемого объекта, например, ALU с меткой иит (unit under test), имеет различное исполнение, т.е. архитектуру, например, RTL. Для того, чтобы не изменять описание архитектуры испытательного стенда, изменяют только его конфигурацию, например:

configuration testbench_for_alu of alu_tb is

for TB_ARCH

for UUT: ALU

use entity work.ALU(RTL); end for; end for;

end TESTBENCH_FOR_ALU;

Расширенный синтаксис объявления конфигурации предполагает такие возможности, как подключение других конфигураций, встав­ку компонента непосредственно в конфигурации (в указателе связы­вания), связывание настроечных констант компонента с новыми значениями, отключение компонента от схемы (отложенное включе­ние, когда в указателе связывания - ключевые слова use open).

Если в конфигурации используются компоненты, описанные в другой библиотеке, то их делают видимыми с помощью описаний library и use, которые ставят перед конфигурацией.

Конфигурации обычно игнорируются компиляторами-синтезато­рами.

Параллельные операторы

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

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


Оператор параллельного присваивания

Этот оператор имеет такой же синтаксис, как и оператор при­сваивания сигналу в процессе. Такой оператор эквивалентен опера­тору процесса, в котором этот оператор повторен в его исполнитель­ной части, а последним оператором стоит оператор wait со списком чувствительности. Например, следующие два оператора эквивалент­ны:

ADDER_D:A<=B+C;

adder_p:process begin А<=в+С; wait on в,С; end process;

Оператор условного параллельного присваивания

Оператор условного параллельного присваивания имеет синтак­сис:

\условное параллельное присваивание\::= \имя\<= [\способ задержки\]

{\график\ when \6улевское выражение\ else } \график\|>пеп \6улевское выражение\];

где определение способа задержки и графика представлено выше при описании оператора присваивания сигналу.

Любой оператор условного параллельного присваивания имеет эквивалентное представление в виде процесса, как например, опера­тор:

cntrl<= one when st=l else

two when st=2 or st=3 else three;

эквивалентен оператору

process(st,one,two,three) begin

if st=l then

cntrl<= one; elsif st=2 or st=3 then

cntrl<= two; else

cntrl<=three; end if; end process;

Оператор селективного параллельного присваивания

Оператор селективного параллельного присваивания имеет син­таксис:


\селективное параллельное присваивание\::= with\выражение\ select{\имя\<= [\способ задержки\]{\график\ when\альтернативы\,}

\rpa0MK\[when others ];

где \альтернативы\ имеют то же значение, что и в операторе case. Этот оператор эквивалентен соответствующему процессу, как на­пример, оператор:

With st select

cntrl<= one when 1,

two when2 to 3, three when others;

выполняет такие же действия, что и процесс: