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;
выполняет такие же действия, что и процесс: