Куланов В.А.
[v.kulanov@csn.khai.edu]
Подпрограммы.
Процедуры в языке VHDL
«Технологии проектирования
компьютерных систем»
ПодпрограммыШо, опять…
подпрограммы?
 Обеспечивают структуризацию описания
проекта путем разделения его на
самостоятельные блоки с заданной
функциональностью
 Позволяют заменить несколько описаний сходных
фрагментов алгоритма одним объявлением
подпрограммы и необходимым количеством её
вызовов в основном тексте проекта
 Различают два вида подпрограмм
• процедуры (PROCEDURE)
• функции (FUNCTION)
Процедуры в 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;
Имя процедуры
Список формальных параметров
(может отсутствовать)
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;
... ...
Наличие прототипа подпрограммы
необязательно, но рекомендуется
Список параметров процедуры
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
Вызов процедуры в VHDL
 Вызов процедуры записывается в исходном коде как
отдельный оператор, который имеет следующий синтаксис:
[label:] name [(parameter_list)];
Метка Список фактических параметров
([parameter_name =>]
expression|signal_name|variable_name|OPEN, {…})
Формальный параметр
Два типа сопоставления:
 Именованное (=>)
 Позиционное
Фактический параметр
 Выражение/Константное значение
 Сигнал
 Переменная
 Ключевое слово OPEN - не используется или значение по умолчанию
Процедуры в VHDL
 Если используется смешанный тип сопоставления параметров
тогда, именованное сопоставление в списке параметров
должно всегда быть последним:
do_smth(good, more => 1, even_more => 2);
do_smth(bad, more => 1, 2); -- нарушен порядок
 Параметры-константы и параметры-переменные
передаются в/из процедуры по значению
 При вызове процедуры с параметром сигналом происходит
передача параметра не по значению, а по ссылке:
• значение сигнала может меняться не только в
результате выполняемых в процедуре действий, но
и в результате действий, выполняемых
параллельно с ней (другими процессами,
параллельными операторами)
Процедуры в VHDL
 Если используется формальный параметр-сигнал вида OUT, то
изменение значения этого параметра в процедуре влечет за
собой изменение значения соответствующего ему
фактического параметра сигнала в вызвавшем процедуру
процессе
 Формальные параметры-сигналы также могут иметь вид
INOUT. В этом случае в качестве фактического параметра
должен выступать сигнал, внешний к объекту моделирования,
а не описанный внутри него
 В качестве класса (объекта) параметра могут выступать FILE, в
таком случае вид параметра (IN, OUT, INOUT) не указывается:
PROCEDURE writeline(FILE f: text; l: INOUT line);
Процедуры в VHDL
 В общем виде процедуры являются «синтезируемыми», если
они не содержать в своем теле оператор WAIT:
• если в теле процедуры используется оператор WAIT, то
вызов процедуры из функции недопустим, а вызов из тела
оператора PROCESS возможен в случае, если оператор
PROCESS не содержит списка чувствительности
 Переменные, объявленные в подпрограмме
инициализируются заново при каждом вызове процедуры
 Возможен рекурсивный вызов процедуры
 не всегда «синтезируется»
 Возможно использование механизма «перегрузки» процедур
• вызов соответствующей определяется исходя из набора
(количества) и типа фактических параметров
Процедуры в 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;
Процедуры в 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
Процедуры в 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
Процедуры в 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
Процедуры в 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;
Процедуры в 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"?
Перегрузка процедур
-- прототипы процедур 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)
Subprograms in VHDL, Procedures in VHDL

Subprograms in VHDL, Procedures in VHDL

  • 1.
    Куланов В.А. [v.kulanov@csn.khai.edu] Подпрограммы. Процедуры вязыке VHDL «Технологии проектирования компьютерных систем»
  • 2.
    ПодпрограммыШо, опять… подпрограммы?  Обеспечиваютструктуризацию описания проекта путем разделения его на самостоятельные блоки с заданной функциональностью  Позволяют заменить несколько описаний сходных фрагментов алгоритма одним объявлением подпрограммы и необходимым количеством её вызовов в основном тексте проекта  Различают два вида подпрограмм • процедуры (PROCEDURE) • функции (FUNCTION)
  • 3.
    Процедуры в VHDL PROCEDUREname[(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 Объявление процедуры -- USEwork.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.
    Список параметров процедуры PROCEDUREname[(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 ARCHITECTURErtl 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 PROCEDUREconvert(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 ARCHITECTURErtl 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 ARCHITECTURErtl 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 SIGNALen: 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)