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

VHDL 함수 마스터하기: 효율적 설계를 위한 실전 가이드

함수는 VHDL에서 자주 쓰이는 알고리즘 구현에 쓰이는 서브프로그램입니다. 함수는 0개 이상의 입력값을 받아 항상 값을 반환합니다. 프로시저와 구별되는 점은 Wait-문장을 포함할 수 없어 항상 0 시뮬레이션 시간을 소모한다는 것입니다.

다른 언어의 함수나 메서드에 익숙하다면 VHDL 함수도 쉽게 익힐 수 있습니다. VHDL에서는 반환값을 생략하거나 void를 반환할 수 없고, 함수는 항상 무언가를 반환해야 하며 반환값은 반드시 어딘가에 할당되어야 합니다.

이 블로그 글은 Basic VHDL Tutorials 시리즈의 일부입니다.

VHDL에는 순수(pure) 함수와 비순수(impure) 함수 두 종류가 있습니다. 함수가 순수하다는 건 외부 시그널을 수정하거나 읽을 수 없다는 뜻입니다. 따라서 순수 함수를 특정 인수로 호출하면 항상 같은 값을 반환한다고 확신할 수 있습니다. 우리는 이를 함수가 부작용(side effects)이 없다고 말합니다.

VHDL에서 함수 선언 문법은 다음과 같습니다:

[pure|impure] function <function_name> (<parameter1_name> : <parameter1_type> := <default_value>;                                          <parameter2_name> : <parameter2_type> := <default_value>;                                         ... ) return <return_type> is     <constant_or_variable_declaration> begin     <code_performed_by_the_function>     return <value> end function;

pure/impure 키워드는 선택 사항이며 생략 시 pure가 기본값입니다. 모든 파라미터는 함수 내부에서 상수로 취급돼 변경할 수 없습니다. 기본값은 선택 사항이며 함수는 반드시 return 문에서 종료해야 합니다.

함수는 is와 begin 키워드 사이에 고유한 선언부를 가집니다. 여기서 선언된 상수, 시그널, 변수는 함수 내부에서만 유효하며 후속 호출 간에 값을 유지하지 않습니다.

실습

이 튜토리얼에서는 순수 함수에 집중하고, 비순수 함수는 이 시리즈의 나중 튜토리얼에서 다룹니다.

이전 튜토리얼에서 유한 상태 머신(FSM)을 써서 신호등 컨트롤러 모듈을 만들었습니다. 타이머 계산 줄을 한 상태에서 다른 상태로 복사해 붙여넣기만 하고 상수만 살짝 바꿨습니다.

함수를 써서 상태 머신 코드를 어떻게 단순화할 수 있는지 알아보세요:

함수 테스트벤치 최종 코드:

 library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity T21_FunctionTb is end entity; architecture sim of T21_FunctionTb is -- 시뮬레이션 속도 위해 낮은 클록 주파수 사용 constant ClockFrequencyHz : integer := 100; -- 100 Hz constant ClockPeriod : time := 1000 ms / ClockFrequencyHz; signal Clk : std_logic := '1'; signal nRst : std_logic := '0'; signal NorthRed : std_logic; signal NorthYellow : std_logic; signal NorthGreen : std_logic; signal WestRed : std_logic; signal WestYellow : std_logic; signal WestGreen : std_logic; begin -- Device Under Test (DUT) i_TrafficLights : entity work.T21_TrafficLights(rtl) generic map(ClockFrequencyHz => ClockFrequencyHz) port map ( Clk => Clk, nRst => nRst, NorthRed => NorthRed, NorthYellow => NorthYellow, NorthGreen => NorthGreen, WestRed => WestRed, WestYellow => WestYellow, WestGreen => WestGreen); -- 클록 생성 프로세스 Clk <= not Clk after ClockPeriod / 2; -- 테스트벤치 시퀀스 process is begin wait until rising_edge(Clk); wait until rising_edge(Clk); -- DUT를 리셋에서 해제 nRst <= '1'; wait; end process; end architecture; 

신호등 모듈 최종 코드:

 library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity T21_TrafficLights is generic(ClockFrequencyHz : natural); port( Clk : in std_logic; nRst : in std_logic; -- Negative reset NorthRed : out std_logic; NorthYellow : out std_logic; NorthGreen : out std_logic; WestRed : out std_logic; WestYellow : out std_logic; WestGreen : out std_logic); end entity; architecture rtl of T21_TrafficLights is -- 열거 타입 선언과 상태 시그널 선언 type t_State is (NorthNext, StartNorth, North, StopNorth, WestNext, StartWest, West, StopWest); signal State : t_State; -- 분/초 단위로 클록 사이클 수 계산 함수 CounterVal(Minutes : integer := 0; Seconds : integer := 0) return integer is variable TotalSeconds : integer; begin TotalSeconds := Seconds + Minutes * 60; return TotalSeconds * ClockFrequencyHz -1; end function; -- 클록 주기 카운터, 최대 1분 signal Counter : integer range 0 to CounterVal(Minutes => 1) +1; begin process(Clk) is begin if rising_edge(Clk) then if nRst = '0' then -- 리셋 값 NorthRed <= '1'; NorthYellow <= '0'; NorthGreen <= '0'; WestRed <= '1'; WestYellow <= '0'; WestGreen <= '0'; State <= NorthNext; Counter <= 0; else -- 기본 값 NorthRed <= '0'; NorthYellow <= '0'; NorthGreen <= '0'; WestRed <= '0'; WestYellow <= '0'; WestGreen <= '0'; Counter <= Counter + 1; case State is -- 모든 방향 적색 when NorthNext => NorthRed <= '1'; WestRed <= '1'; -- 5초 경과 시 if Counter = CounterVal(Seconds => 5) then Counter <= 0; State <= StartNorth; end if; -- 남북 방향 황색 when StartNorth => NorthRed <= '1'; NorthYellow <= '1'; WestRed <= '1'; -- 5초 경과 시 if Counter = CounterVal(Seconds => 5) then Counter <= 0; State <= North; end if; -- 남북 방향 녹색 when North => NorthGreen <= '1'; WestRed <= '1'; -- 1분 경과 시 if Counter = CounterVal(Minutes => 1) then Counter <= 0; State <= StopNorth; end if; -- 남북 방향 적색+황색 when StopNorth => NorthYellow <= '1'; WestRed <= '1'; -- 5초 경과 시 if Counter = CounterVal(Seconds => 5) then Counter <= 0; State <= WestNext; end if; -- 모든 방향 적색 when WestNext => NorthRed <= '1'; WestRed <= '1'; -- 5초 경과 시 if Counter = CounterVal(Seconds => 5) then Counter <= 0; State <= StartWest; end if; -- 동서 방향 황색 when StartWest => NorthRed <= '1'; WestRed <= '1'; WestYellow <= '1'; -- 5초 경과 시 if Counter = CounterVal(Seconds => 5) then Counter <= 0; State <= West; end if; -- 동서 방향 녹색 when West => NorthRed <= '1'; WestGreen <= '1'; -- 1분 경과 시 if Counter = CounterVal(Minutes => 1) then Counter <= 0; State <= StopWest; end if; -- 동서 방향 적색+황색 when StopWest => NorthRed <= '1'; WestYellow <= '1'; -- 5초 경과 시 if Counter = CounterVal(Seconds => 5) then Counter <= 0; State <= NorthNext; end if; end case; end if; end if; end process; end architecture; 

ModelSim 콘솔에서 run 5 min 명령 실행 후 파형:
VHDL 함수 마스터하기: 효율적 설계를 위한 실전 가이드

StartNorth 상태 진입/이탈 전이에 커서를 둔 파형:
VHDL 함수 마스터하기: 효율적 설계를 위한 실전 가이드

분석

이전 튜토리얼의 타이머 계산 if Counter = ClockFrequencyHz * 5 -1 then을 새로 만든 CounterVal 함수 호출 if Counter = CounterVal(Seconds => 5) then로 대체했습니다.

첫 파형 스크린샷에서 모듈 기능이 변경되지 않았음을 볼 수 있습니다. 반복 작업에 함수를 쓰는 건 좋은 설계 관행입니다. 특히 Minutes, Seconds 같은 용어를 담은 더 읽기 쉬운 줄로 계산을 대체할 수 있을 때 더욱 그렇습니다.

함수 사용의 또 다른 장점은 모든 타이머 구현을 한 번에 바꿀 수 있다는 점입니다. 예: CounterVal 함수에서 return TotalSeconds * ClockFrequencyHz;로 썼다면 모든 타이머가 한 클록 사이클만큼 길어졌을 겁니다. 이를 return TotalSeconds * ClockFrequencyHz -1;로 고치면 모든 타이머가 한 번에 수정됩니다.

마지막 파형 스크린샷을 보면 CounterVal 함수에서 반환된 타이머 값에서 1을 빼야 하는 이유를 알 수 있습니다. 이 파형은 StartNorth 상태 지속 시간을 조사하는데, 정확히 5초여야 합니다. State 시그널이 StartNorth로 바뀌면 Counter 값은 0이고 다음 클록 사이클에서만 변합니다. 500 클록 사이클까지 세면 StartNorth 상태가 실제로는 501 사이클 지속됩니다. 테스트벤치가 100Hz로 돌면 500 클록 사이클이 정확히 5초입니다.

VHDL 함수 마스터하기: 효율적 설계를 위한 실전 가이드

핵심 정리

다음 튜토리얼로 이동 »

VHDL

  1. 몰리브덴이 현대 산업을 형성하는 방식: 용도, 이점, 공급 역학
  2. VHDL 문자열 리스트 구현: 모범 사례와 예제
  3. VHDL 테스트벤치 시뮬레이션 우아하게 종료하기
  4. VHDL PWM 컨트롤러 구현: 설계, 시뮬레이션, FPGA 데모
  5. VHDL 난수 생성: 균일 분포부터 OSVVM까지
  6. 프로세스 내 프로시저로 VHDL FSM 설계 깔끔하게 만들기
  7. VHDL 비순수 함수 활용: FSM 가독성과 유지보수성 높이기
  8. C언어 realloc() 활용법: 문법, 모범 사례, 실전 예제
  9. C언어 free() 함수 마스터하기: 실전 가이드와 예제
  10. 커터 그라인더(Cutter Grinder) 마스터하기: 실전 기술 가이드