VHDL
프로시저에서 외부 신호를 구동할 수 있습니다. 신호가 프로시저 범위 내에 있는 한 매개변수 목록에 나열되지 않더라도 읽기 또는 쓰기를 위해 액세스할 수 있습니다.
아키텍처의 선언적 영역에 선언된 프로시저는 외부 신호를 구동할 수 없습니다. 이는 단순히 컴파일 시간에 해당 범위에 신호가 없기 때문입니다. 반면에 프로세스 내에서 선언된 프로시저는 프로세스가 볼 수 있는 모든 신호에 액세스할 수 있습니다.
이 블로그 게시물은 기본 VHDL 자습서 시리즈의 일부입니다.
이러한 절차는 동일한 작업이 여러 번 발생하는 프로세스에서 알고리즘을 정리하는 데 사용할 수 있습니다. 호출할 때 모든 입력과 출력이 로컬 신호에 할당되는 일반적인 절차를 사용할 수 있지만 그것이 요점이 아닙니다. 프로시저 호출에서 입력 및 출력 신호를 생략하여 입력을 줄여야 하며 더 중요하게는 코드를 더 읽기 쉽게 만들어야 합니다.
복잡한 통신 프로토콜을 구현하는 프로세스를 상상해 보십시오. 일부 작업이 RequestToSend()
와 같은 프로시저 호출로 대체된다면 메인 알고리즘의 실행 흐름을 이해하는 것이 훨씬 쉬울 것입니다. 또는 SendAutorizationHeader()
. 프로시저 이름만 보면 이 줄이 무엇을 했는지 알 수 있습니다.
이전 자습서에서는 불순 함수를 사용하여 유한 상태 기계(FSM) 코드를 단순화했습니다. 우리는 Counter
을(를) 운전하고 있었습니다. 불순한 함수에서 신호를 보내고 반환 값을 사용하여 상태를 변경할 시기를 결정했습니다. 하지만 State
의 할당을 옮기고 싶다면 어떻게 해야 할까요? 함수에 신호를 보내고 반환 값을 무시합니까?
VHDL에서 반환 값을 할당하지 않고는 함수를 호출할 수 없습니다. 그렇게 하려고 하면 ModelSim에서 컴파일 오류가 발생합니다. 하위 프로그램 "CounterExpired"에 대한 실행 가능한 항목이 없습니다.
대신 이를 위한 절차를 사용할 수 있습니다. 프로세스 내에서 선언된 프로시저는 해당 프로세스 범위 내의 모든 신호에 액세스할 수 있습니다. 불순 함수와 비슷하지만 프로시저이므로 반환 값이 없습니다.
이 비디오 자습서에서는 프로세스에 선언된 프로시저를 사용하여 FSM 코드를 단순화합니다.
Process in Process testbench의 최종 코드 :
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity T23_ProcedureInProcessTb is end entity; architecture sim of T23_ProcedureInProcessTb is -- We are using a low clock frequency to speed up the simulation 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 -- The Device Under Test (DUT) i_TrafficLights : entity work.T23_TrafficLights(rtl) generic map(ClockFrequencyHz => ClockFrequencyHz) port map ( Clk => Clk, nRst => nRst, NorthRed => NorthRed, NorthYellow => NorthYellow, NorthGreen => NorthGreen, WestRed => WestRed, WestYellow => WestYellow, WestGreen => WestGreen); -- 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 T23_TrafficLights is generic(ClockFrequencyHz : integer); 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 T23_TrafficLights is -- Enumerated type declaration and state signal declaration type t_State is (NorthNext, StartNorth, North, StopNorth, WestNext, StartWest, West, StopWest); signal State : t_State; -- Counter for counting clock periods, 1 minute max signal Counter : integer range 0 to ClockFrequencyHz * 60; begin process(Clk) is -- Procedure for changing state after a given time procedure ChangeState(ToState : t_State; Minutes : integer := 0; Seconds : integer := 0) is variable TotalSeconds : integer; variable ClockCycles : integer; begin TotalSeconds := Seconds + Minutes * 60; ClockCycles := TotalSeconds * ClockFrequencyHz -1; if Counter = ClockCycles then Counter <= 0; State <= ToState; end if; end procedure; begin if rising_edge(Clk) then if nRst = '0' then -- Reset values State <= NorthNext; Counter <= 0; NorthRed <= '1'; NorthYellow <= '0'; NorthGreen <= '0'; WestRed <= '1'; WestYellow <= '0'; WestGreen <= '0'; else -- Default values NorthRed <= '0'; NorthYellow <= '0'; NorthGreen <= '0'; WestRed <= '0'; WestYellow <= '0'; WestGreen <= '0'; Counter <= Counter + 1; case State is -- Red in all directions when NorthNext => NorthRed <= '1'; WestRed <= '1'; ChangeState(StartNorth, Seconds => 5); -- Red and yellow in north/south direction when StartNorth => NorthRed <= '1'; NorthYellow <= '1'; WestRed <= '1'; ChangeState(North, Seconds => 5); -- Green in north/south direction when North => NorthGreen <= '1'; WestRed <= '1'; ChangeState(StopNorth, Minutes => 1); -- Yellow in north/south direction when StopNorth => NorthYellow <= '1'; WestRed <= '1'; ChangeState(WestNext, Seconds => 5); -- Red in all directions when WestNext => NorthRed <= '1'; WestRed <= '1'; ChangeState(StartWest, Seconds => 5); -- Red and yellow in west/east direction when StartWest => NorthRed <= '1'; WestRed <= '1'; WestYellow <= '1'; ChangeState(West, Seconds => 5); -- Green in west/east direction when West => NorthRed <= '1'; WestGreen <= '1'; ChangeState(StopWest, Minutes => 1); -- Yellow in west/east direction when StopWest => NorthRed <= '1'; WestYellow <= '1'; ChangeState(NorthNext, Seconds => 5); end case; end if; end if; end process; end architecture;
run 5 min
를 입력한 후의 파형 ModelSim 콘솔의 명령:
모듈의 동작을 변경하지 않았으며 파형이 변경되지 않은 것을 볼 수 있습니다.
처음에 신호등 모듈을 만든 튜토리얼의 코드와 비교하면 FSM 코드가 훨씬 더 읽기 쉽습니다. 코드를 읽으면 구현하는 알고리즘을 쉽게 따를 수 있습니다. 단일 프로시저에 타이머와 상태 변경 로직을 포함하는 것은 그것이 사용되는 모든 곳에서 동일하게 구현되도록 보장하기 때문에 유익합니다.
VHDL
이전 튜토리얼에서 우리는 프로세스를 프로그램 스레드로 생각할 수 있다는 것을 배웠습니다. 또한 wait; 문으로 인해 프로그램이 무기한 일시 중지됩니다. 하지만 프로그램이 영원히가 아닌 다른 시간 값을 기다리게 하는 방법이 있습니까? wait;을 제거하면 프로그램을 컴파일하려고 하면 컴파일러는 무한 루프에 대해 불평할 것입니다. 컴파일러가 참조하는 루프는 프로세스 루프입니다. . VHDL의 프로세스 스레드는 절대 종료되지 않으며 begin 사이에서 계속 반복됩니다. 및 end process; 진술. wait이 있어야 합니다. 프로
A:FRP는 만드는 제품에 따라 다양한 방법으로 만들어집니다. DEFI의 당사 제품은 주로 개방형 금형 공정, 핸드 레이업 및 인발 공정으로 만들어집니다. FRP는 새로운 발명품이 아닙니다. 사실 FRP는 벨기에에서 이민 온 미국인 화학자 레오 백랜드(Leo Beckeland)가 110년에 걸쳐 발명했습니다. 그가 브랜드화한 베이클라이트는 최초의 제품이었고 독특한 특성으로 인해 혁명적이었습니다. 오늘로 빠르게 이동하면 FRP가 다양한 산업 분야에서 사용된다는 것을 알 수 있습니다. 석유 산업은 근해 유정 플랫폼에 FRP 격자를 사