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" 키워드 사이에 개체를 선언할 수 있습니다. 여기에는 상수, 변수, 유형, 하위 유형 및 별칭이 포함될 수 있지만 신호는 포함되지 않습니다.
함수와 달리 프로시저는 대기 명령문을 포함할 수 있습니다. 따라서 인터페이스를 시뮬레이션하거나 테스트 대상 장치(DUT)의 출력을 확인하기 위해 간단한 BFM과 같은 테스트벤치에서 자주 사용됩니다.
이전 자습서에서는 중첩된 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;
Minutes
가 있는 타임라인을 확대한 ModelSim의 파형 창 신호가 래핑 중입니다:
파형에서 신호 래핑이 이전 자습서에서와 같이 여전히 작동한다는 것을 알 수 있습니다. 모듈의 기능을 실제로 변경하지 않고 구현 방식만 변경했기 때문입니다.
IncrementWrap
에 대한 매개변수 목록의 첫 번째 항목 절차는 Counter
입니다. 신호. inout
방향을 사용하여 선언됩니다. 프로시저가 해당 값을 읽고 설정할 수 있도록 합니다.
매개변수 목록의 두 번째 및 세 번째 항목은 상수입니다. 즉, 여기에 입력한 값은 내부에 상수로 표시됩니다. 절차의. WrapValue
Enable
과 함께 입력 입력은 Counter
신호가 증가하거나 래핑됩니다.
매개변수 목록의 마지막 항목은 out
방향의 변수입니다. . 이 출력의 목적은 카운터가 래핑한 프로시저를 호출자에게 알리는 것입니다. 여기에서 일종의 반환 값처럼 사용합니다.
메인 프로세스에는 IncrementWrap
에 대한 네 번의 호출이 있습니다. 절차. 각 후속 호출은 Wrap
을 사용합니다. 카운트를 활성화하는 변수입니다. 신호 값은 프로세스가 절전 모드로 전환될 때만 업데이트되기 때문에 변수 대신 신호를 사용했다면 작동하지 않았을 것입니다. 한 프로시저 호출의 출력 값이 바로 다음 라인의 호출에 대한 입력으로 사용되어야 합니다. 따라서 변수여야 합니다.
다음 튜토리얼로 이동 »
VHDL
이전 자습서에서 For-Loop를 사용하여 정수 범위를 반복하는 방법을 배웠습니다. 그러나 고정된 정수 범위보다 루프를 더 자세히 제어하려면 어떻게 해야 할까요? 이를 위해 While 루프를 사용할 수 있습니다. While 루프는 테스트하는 표현식이 true로 평가되는 한 계속해서 동봉된 코드를 반복합니다. . 따라서 While-Loop는 얼마나 많은 반복이 필요한지 미리 알 수 없는 상황에 적합합니다. 이 블로그 게시물은 기본 VHDL 자습서 시리즈의 일부입니다. While 루프의 구문은 다음과 같습니다. while <
이전 튜토리얼에서 wait for를 사용하여 시간을 지연시키는 방법을 배웠습니다. 성명. 프로세스 루프에 대해서도 배웠습니다. 이제 허용하면 프로세스 스레드가 프로세스 내에서 영원히 반복된다는 것을 알고 있습니다. 그러나 프로세스의 시작 부분에서 한 번만 무언가를 하고 싶다면 어떻게 해야 할까요? 그런 다음 끝에 다른 코드를 반복합니까? VHDL에서 가장 단순한 종류의 루프는 loop을 사용하여 생성할 수 있습니다. 성명서. 이 블로그 게시물은 기본 VHDL 자습서 시리즈의 일부입니다. 단순 루프의 구문은 다음과 같습니다.