산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Industrial programming >> VHDL

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

  1. 절차문 - VHDL 예
  2. 몰리브덴은 어떻게 사용합니까?
  3. VHDL에서 문자열 목록을 만드는 방법
  4. VHDL 테스트벤치에서 시뮬레이션을 중지하는 방법
  5. VHDL에서 PWM 컨트롤러를 만드는 방법
  6. VHDL에서 난수를 생성하는 방법
  7. VHDL의 프로세스에서 프로시저를 사용하는 방법
  8. VHDL에서 불순 함수를 사용하는 방법
  9. VHDL에서 함수를 사용하는 방법
  10. 커터 그라인더 사용 방법