Proceduresort2(variable xl,x2:inoutinteger) is
Variablet:integer; begin
Ifxl>x2 then
Return; else
t:=xl; xl:=x2; x2:=t; end if; end procedure; begin
bl:*al; Ь2:=а2; ЬЗ:=аЗ; Sort2(b2,b3); Sort2(bl,b2); Sort2(b2,b3); cl<=bl; с2<=Ь2; c3<=b3; end process;
Здесь процедура Sort2 выполняет сортировку переменных xl,x2, выступающих формальными параметрами процедуры. Оператор returnдосрочно прерывает исполнение процедуры. Вызов процедуры выполняется с позиционным связыванием.
Следующий пример представляет использование процедуры со связыванием не всех формальных параметров.
procedure And4(variable xl,x2,x3,x4:in bit : = 'Г; signal y:out bit) is begin y<=xl and x2 and x3 and x4; end procedure;
При вызове этой процедуры:
And4(al,a2,a3,open,b);
четвертый входной параметр отсутствует, на что указывает ключевое слово openи вместо него подставляется начальное значение '1*.
При вызове процедуры входные параметры переменных копируются внутрь процедуры. После исполнения процедуры выходные параметры записываются на место соответствующих переменных.
Входные параметры сигналов представляются как ссылки на сигналы. Параметру сигнала нельзя присваивать начальное значение, так как источник этого сигнала недоступен. Поэтому нельзя также использовать такие атрибуты сигнала, как 'delayed,'stable,'quiet или 'transaction, которые опрашивают источник сигнала. Выходной параметр сигнала передается в процедуру вместе с источником сигнала, в котором происходит присваивание сигналу. Это эквивалентно тому, что цепочка последовательных операторов тела процедуры копируется в процесс на место вызова процедуры с соответствующей подстановкой параметров.
В отличие от вызова процедуры в обычных алгоритмических языках, в которых используется одно тело процедуры, в VHDL каждый вычислительный процесс, вызывающий процедуру, использует свой собственный экземпляр тела процедуры. И эти экземпляры исполняются параллельно, как и операторы процесса.
Спецификация функции
Спецификация функции имеет следующий синтаксис:
Хспецификация функции\::=[pure|impure] function \имя функции\ |\знак функции\ [(\список параметров\)] return \тип параметрах is {\объявление в подпрограме\} begin
^последовательный оператор\} return \выражение\; end [function][\имя функции\];
В ней знак функции - символ в кавычках, например, "+", список параметров - такой же, как в процедуре за исключением того, что
режимы параметров out и inout не допускаются. После ключевого слова return в объявлении функции указывается тип возвращаемого параметра. Объявления в функции могут быть такими же, как в процедуре. Выполнение функции должно оканчиваться оператором return, вычисляющим выражение возвращаемого параметра.
В отличие от процедуры, вызов функции возвращает только один параметр, зато он может участвовать как операнд в выражениях. В языке VHDL очень мало встроенных функций, т.е. операций. Большинство функций реализовано в виде подпрограмм. Для преобразования типов чаще всего используются функции. Например, функция
functionBit_To_int(x:bit_vector) returnnatural is variablet, j:integer:=0; begin
forI inx'reverse_range loop if ( x(i)='l') then
t:=t + 2**j; end if;
end loop; return t; end functionBit_To_int;
преобразует вектор битов в целое. При этом атрибут х'reverse_range возвращает диапазон, обратный диапазону представления входного параметра. Например, если входной параметр - bit_vector(7 downto 0), то в оператор цикла подставится диапазон 0 to 7. Таким образом, получается функция, универсальная для множества различных параметров-операндов.
Ключевые слова pure и impure обозначают идеальную и неидеальную функции. В отличие от идеальной функции, неидеальная функция может возвращать различные результаты для одинаковых наборов входных параметров. Например, если входной параметр -глобальная переменная, которая изменится в момент вызова функции, то результат будет отличаться от ожидаемого. Поэтому такие глобальные переменные не могут быть операндами в идеальных функциях.
Примером неидеальной функции является функция now из пакета standard, которая при вызове возвращает переменную предопределенного типа delay_length, равную текущему моменту времени моделирования. Естественно, что при различных вызовах этой функции она возвращает различные значения.
Объявление процедур и функций
Объявление подпрограмм вставляется в части объявлений процессов, блоков, в объявлениях объектов и пакетов, если эти подпрограммы используются в этих программных единицах. Оно представляет собой часть спецификации процедуры и функции до слова i s :
\объявление процедуры\::= procedure\имя процедуры\ [(\список параметров\)];
\объявление функции\::=[pure| impure] function\имя функции\ |\знак функции\[(\список параметров\)] return\тип параметрах;
Перегрузка процедур и функций
В языке VHDL допускается определять несколько процедур и функций с одинаковыми названиями. При вызове функции или процедуры из числа функций или процедур с одинаковым названием выбирается такая, которая подходит по типам и числу входных и выходных параметров. Такая функция загружается поверх остальных функций с таким же названием. Перегрузка (overloading) процедур и функций удобна при вычислениях с различными типами. Например, над типами integer, real, подтипами signed, unsigned определены одни и те же арифметические функции, но имеющие различное сочетание типов аргументов и результатов.
Примером перегрузки служит следующая функция, которая не входит ни в один стандартный пакет: