Как использовать процедуру в VHDL
Процедура — это тип подпрограммы в VHDL, которая помогает избежать повторения кода. Иногда возникает необходимость выполнить одинаковые операции в нескольких местах по всей конструкции. Хотя создание модуля может быть излишним для мелких операций, часто вам нужна процедура.
Процедуры могут быть объявлены в любой декларативной области. Объем процедуры будет ограничен тем, где она объявлена, архитектурой, пакетом или процессом. Всякий раз, когда вы вызываете процедуру, она будет вести себя так, как будто код процедуры был вставлен туда, откуда она была вызвана.
Процедура не возвращает значение, как функция, но вы можете вернуть значения, объявив out
или inout
сигналов в списке параметров.
Эта запись в блоге является частью серии учебных пособий по основам VHDL.
Основной синтаксис для создания процедуры:procedure <procedure_name> (signal|variable|constant <name1> : in|out|inout <type>;
signal|variable|constant <name2> : in|out|inout <type>;
... ) is
<declarations_for_use_within_the_procedure>
begin
<code_performed_by_the_procedure_here>
end procedure;
Список параметров процедуры определяет ее входы и выходы, что-то вроде мини-модуля. Это может быть сигнал или константа, но, в отличие от модуля, это может быть и переменная. Вы можете объявить объекты между ключевыми словами «is» и «begin», которые допустимы только внутри процедуры. Это могут быть константы, переменные, типы, подтипы и псевдонимы, но не сигналы.
В отличие от функций процедуры могут содержать операторы ожидания. Поэтому они часто используются в тестовых стендах, таких как простые BFM, для моделирования интерфейсов или для проверки выходных данных тестируемого устройства (DUT).
Упражнение
В предыдущем уроке мы создали модуль таймера, используя вложенные операторы If-Then-Else. Каждый уровень If-Then-Else внутри другого If-Then-Else усложняет дизайн, и он становится менее читаемым. На каждом уровне логики мы в основном выполняем одну и ту же операцию с другим набором сигналов. Разве нет лучшего способа сделать это?
В этом видеоуроке мы узнаем, как создать процедуру на VHDL:
Окончательный код процедуры testbench :
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity T19_ProcedureTb is end entity; architecture sim of T19_ProcedureTb is -- We're slowing down the clock to speed up simulation time constant ClockFrequencyHz : integer := 10; -- 10 Hz constant ClockPeriod : time := 1000 ms / ClockFrequencyHz; signal Clk : std_logic := '1'; signal nRst : std_logic := '0'; signal Seconds : integer; signal Minutes : integer; signal Hours : integer; begin -- The Device Under Test (DUT) i_Timer : entity work.T19_Timer(rtl) generic map(ClockFrequencyHz => ClockFrequencyHz) port map ( Clk => Clk, nRst => nRst, Seconds => Seconds, Minutes => Minutes, Hours => Hours); -- Process for generating clock Clk <= not Clk after ClockPeriod / 2; -- Testbench sequence process is begin wait until rising_edge(Clk); wait until rising_edge(Clk); -- Take the DUT out of reset nRst <= '1'; wait; end process; end architecture;
Окончательный код для модуля таймера используя процедуру:
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity T19_Timer is generic(ClockFrequencyHz : integer); port( Clk : in std_logic; nRst : in std_logic; -- Negative reset Seconds : inout integer; Minutes : inout integer; Hours : inout integer); end entity; architecture rtl of T19_Timer is -- Signal for counting clock periods signal Ticks : integer; procedure IncrementWrap(signal Counter : inout integer; constant WrapValue : in integer; constant Enable : in boolean; variable Wrapped : out boolean) is begin Wrapped := false; if Enable then if Counter = WrapValue - 1 then Wrapped := true; Counter <= 0; else Counter <= Counter + 1; end if; end if; end procedure; begin process(Clk) is variable Wrap : boolean; begin if rising_edge(Clk) then -- If the negative reset signal is active if nRst = '0' then Ticks <= 0; Seconds <= 0; Minutes <= 0; Hours <= 0; else -- Cascade counters IncrementWrap(Ticks, ClockFrequencyHz, true, Wrap); IncrementWrap(Seconds, 60, Wrap, Wrap); IncrementWrap(Minutes, 60, Wrap, Wrap); IncrementWrap(Hours, 24, Wrap, Wrap); end if; end if; end process; end architecture;
Окно сигнала в ModelSim, увеличенное на временной шкале, где Minutes
сигнал сворачивает:
Анализ
Из формы волны видно, что перенос сигналов по-прежнему работает, как и в предыдущем уроке. Это потому, что мы фактически не изменили функцию модуля, а только то, как она реализована.
Первый элемент в списке параметров для IncrementWrap
процедура Counter
сигнал. Он объявлен с использованием направления inout
чтобы процедура могла как читать, так и устанавливать его значение.
Второй и третий элементы в списке параметров являются константами. Это означает, что введенные здесь значения будут отображаться как константы внутри. процедуры. WrapValue
введите вместе с Enable
input определяет, является ли Counter
сигнал увеличивается или переносится.
Последний элемент в списке параметров — это переменная с направлением out
. . Целью этого вывода является информирование вызывающей стороны о процедуре, в которую запакован счетчик. Мы используем его здесь как возвращаемое значение.
В основном процессе у нас есть четыре обращения к IncrementWrap
процедура. Каждый из последующих вызовов использует Wrap
переменная, чтобы включить подсчет. Это не сработало бы, если бы мы использовали сигнал вместо переменной, потому что значения сигнала обновляются только тогда, когда процесс переходит в спящий режим. Нам нужно, чтобы выходное значение из одного вызова процедуры использовалось в качестве входных данных для вызова в самой следующей строке. Таким образом, это должна быть переменная.
Вывод
- Процедуры можно использовать как мини-модули, чтобы избежать копирования и вставки кода.
- Параметры (входы/выходы) процедуры могут быть сигналами, переменными или константами
- В отличие от функций, процедуры могут содержать операторы ожидания.
Перейти к следующему руководству »
VHDL
- Оператор процедуры — пример VHDL
- Как мы используем молибден?
- Как создать список строк в VHDL
- Как остановить симуляцию в тестовом стенде VHDL
- Как создать ШИМ-контроллер на VHDL
- Как генерировать случайные числа в VHDL
- Как использовать процедуру в процессе в VHDL
- Как использовать нечистую функцию в VHDL
- Как использовать функцию в VHDL
- Как использовать шлифовальный станок