2. ПодпрограммыШо, опять…
подпрограммы?
Обеспечивают структуризацию описания
проекта путем разделения его на
самостоятельные блоки с заданной
функциональностью
Позволяют заменить несколько описаний сходных
фрагментов алгоритма одним объявлением
подпрограммы и необходимым количеством её
вызовов в основном тексте проекта
Различают два вида подпрограмм
• процедуры (PROCEDURE)
• функции (FUNCTION)
3. Процедуры в VHDL
PROCEDURE name[(parameter_interface_list)] IS
{subprogram_declarative_item}
BEGIN
{sequential_statement}
END [PROCEDURE] [name];
SIGNAL, TYPE, FILE,
SUBTYPE, PROCEDURE,
FUNCTION, VARIABLE,
COMPONENT, CONSTANT
...-- последовательные операторы
a := 5
FOR … LOOP … END LOOP;
...
IF … THEN … ELSE … END IF;
Имя процедуры
Список формальных параметров
(может отсутствовать)
4. project_pkg.vhd
n_reg.vhd
Объявление процедуры
-- USE work.project_pkg;
ENTITY reg_file IS
GENERIC (...);
PORT (...);
END ENTITY n_reg;
ARCHITECTURE rtl OF reg_file IS
BEGIN
PROCESS(...)
BEGIN
...
END PROCESS;
...
END;
PROCEDURE inc(a: INOUT INTEGER; step: INTEGER := 1) IS
BEGIN
a := a + step;
END PROCEDURE inc;
...
PACKAGE project_pkg IS
...
PROCEDURE inc(a: INOUT INTEGER;
step: INTEGER := 1);
...
END PACKAGE project_pkg;
PACKAGE BODY project_pkg IS
END PACKAGE BODY project_pkg;
... ...
Наличие прототипа подпрограммы
необязательно, но рекомендуется
5. Список параметров процедуры
PROCEDURE name[(parameter_interface_list)] IS
...
([CONSTANT|VARIABLE|SIGNAL] identifier {,…}:
[IN|OUT|INOUT] type_indication [:= expression] {;…})
Имя/Идентификатор
параметра
Класс параметра
(может быть еще FILE)
Вид
параметра
Тип
параметра
Значение по умолчанию.
Может быть задано только
для параметров класса
CONSTANT и VARIABLE
PROCEDURE foo(val: INTEGER) -- val - CONSTANT
PROCEDURE foo(val: IN INTEGER) -- val - CONSTANT
PROCEDURE foo(val, bar: OUT INTEGER) -- val, bar - VARIABLE
PROCEDURE foo(val: INOUT INTEGER) -- val – VARIABLE
6. Вызов процедуры в VHDL
Вызов процедуры записывается в исходном коде как
отдельный оператор, который имеет следующий синтаксис:
[label:] name [(parameter_list)];
Метка Список фактических параметров
([parameter_name =>]
expression|signal_name|variable_name|OPEN, {…})
Формальный параметр
Два типа сопоставления:
Именованное (=>)
Позиционное
Фактический параметр
Выражение/Константное значение
Сигнал
Переменная
Ключевое слово OPEN - не используется или значение по умолчанию
7. Процедуры в VHDL
Если используется смешанный тип сопоставления параметров
тогда, именованное сопоставление в списке параметров
должно всегда быть последним:
do_smth(good, more => 1, even_more => 2);
do_smth(bad, more => 1, 2); -- нарушен порядок
Параметры-константы и параметры-переменные
передаются в/из процедуры по значению
При вызове процедуры с параметром сигналом происходит
передача параметра не по значению, а по ссылке:
• значение сигнала может меняться не только в
результате выполняемых в процедуре действий, но
и в результате действий, выполняемых
параллельно с ней (другими процессами,
параллельными операторами)
8. Процедуры в VHDL
Если используется формальный параметр-сигнал вида OUT, то
изменение значения этого параметра в процедуре влечет за
собой изменение значения соответствующего ему
фактического параметра сигнала в вызвавшем процедуру
процессе
Формальные параметры-сигналы также могут иметь вид
INOUT. В этом случае в качестве фактического параметра
должен выступать сигнал, внешний к объекту моделирования,
а не описанный внутри него
В качестве класса (объекта) параметра могут выступать FILE, в
таком случае вид параметра (IN, OUT, INOUT) не указывается:
PROCEDURE writeline(FILE f: text; l: INOUT line);
9. Процедуры в VHDL
В общем виде процедуры являются «синтезируемыми», если
они не содержать в своем теле оператор WAIT:
• если в теле процедуры используется оператор WAIT, то
вызов процедуры из функции недопустим, а вызов из тела
оператора PROCESS возможен в случае, если оператор
PROCESS не содержит списка чувствительности
Переменные, объявленные в подпрограмме
инициализируются заново при каждом вызове процедуры
Возможен рекурсивный вызов процедуры
не всегда «синтезируется»
Возможно использование механизма «перегрузки» процедур
• вызов соответствующей определяется исходя из набора
(количества) и типа фактических параметров
10. Процедуры в VHDL
CONSTANT
VARIABLE
ARCHITECTURE rtl OF example IS
PROCEDURE inc(a: INOUT INTEGER; step: INTEGER := 1) IS
BEGIN
a := a + step;
END PROCEDURE inc;
BEGIN
name : PROCESS IS
VARIABLE v: INTEGER := 0;
BEGIN
REPORT "v = " & INTEGER'IMAGE(v) SEVERITY NOTE;
inc(v); -- a := a + 1 v = 1
WAIT FOR 10 ns;
inc(a => v, step => 2); -- a := a + 2 v = 3
WAIT FOR 10 ns;
inc(v, step => 2 + 3); -- a := a + 2 + 3 v = 8
END PROCESS name;
END ARCHITECTURE rtl;
11. Процедуры в VHDL
PROCEDURE convert(SIGNAL sel: IN BIT_VECTOR (0 TO 1);
SIGNAL val : OUT BIT) IS
BEGIN
CASE sel IS
WHEN "00" | "11" => val <= '1';
WHEN OTHERS => val <= '0';
END CASE;
END PROCEDURE convert;
...
convert(sel => addr, val => data);
-- convert(addr, data);
...
-- Реализация XNOR
12. Процедуры в VHDL
ARCHITECTURE rtl OF adder IS
PROCEDURE addu(a, b: IN STD_LOGIC_VECTOR(N - 1 DOWNTO 0);
signal res: OUT STD_LOGIC_VECTOR(N - 1 DOWNTO 0)) IS
VARIABLE sum: STD_LOGIC_VECTOR(N - 1 DOWNTO 0);
VARIABLE carry: STD_LOGIC := '0';
BEGIN
FOR index IN sum'reverse_range LOOP
sum(index) := a(index) XOR b(index) XOR carry;
carry := (a(index) AND b(index)) OR
(carry AND (a(index) XOR b(index)));
END LOOP;
result <= sum;
END PROCEDURE addu;
BEGIN
addu(a => data_a,
b => data_b,
res => res);
END ARCHITECTURE rtl;
N = 1
N = 2
13. Процедуры в VHDL
ARCHITECTURE rtl OF adder IS
PROCEDURE addu(a, b: IN STD_LOGIC_VECTOR(N - 1 DOWNTO 0);
signal res: OUT STD_LOGIC_VECTOR(N - 1 DOWNTO 0)) IS
... -- смотри предыдущий слайд
BEGIN
... -- смотри предыдущий слайд
END PROCEDURE addu;
BEGIN
reg : PROCESS (clk) IS
BEGIN
IF rising_edge(clk) THEN
addu(data_a,
data_b,
res);
END IF;
END PROCESS reg;
END ARCHITECTURE rtl;
N = 1
N = 2
14. Процедуры в VHDL
SIGNAL en: STD_LOGIC;
...
convert(sel => addr, val => en);
reg : PROCESS (clk, en) IS
begin
IF rising_edge(clk) THEN
if en = '1' THEN
addu(a => data_a, b => data_b, res => res);
END IF;
END IF;
END PROCESS reg;
15. Процедуры в VHDL
В теле процедуры может использоваться оператор
RETURN, назначение которого – завершение выполнения
процедуры:
[label:] RETURN;
PROCEDURE sort2(VARIABLE x1,x2: INOUT INTEGER) IS
VARIABLE t: INTEGER;
BEGIN
IF x1 > x2 THEN
RETURN;
ELSE
t := x1;
x1 := x2;
x2 := t;
END IF;
END PROCEDURE;
Как это сделать без
дополнительной
переменной "t"?
16. Перегрузка процедур
-- прототипы процедур inc
PROCEDURE inc (a: INOUT word32; by: IN word32 := X"000_0001");
PROCEDURE inc (a: INOUT STD_LOGIC_VECTOR;
by: IN STD_LOGIC_VECTOR := X"000_0001");
-- формальными параметрами могут выступать массивы
-- неограниченной длины, но при вызове процедуры для них
-- должны быть определены фактические значение в строго
-- ограниченном диапазоне
PROCEDURE inc (a, b: IN STD_LOGIC_VECTOR;
by: IN STD_LOGIC_VECTOR := X"000_0001");
PROCEDURE inc (a: INOUT INTEGER; by: IN INTEGER := 1);
-- позиционное сопоставление, в зависимости от типа
-- данных count будет вызвана соответствующая процедура
inc(count);
-- именованное сопоставление
inc(a => count, by => open)
inc(a => count)