VHDL
유한 상태 기계(FSM)는 출력이 입력의 현재 상태뿐만 아니라 과거 입력 및 출력 값에 따라 달라지는 메커니즘입니다.
VHDL에서 일종의 시간 종속 알고리즘을 생성해야 할 때마다 또는 FPGA에서 컴퓨터 프로그램을 구현하는 문제에 직면한 경우 일반적으로 FSM을 사용하여 해결할 수 있습니다.
VHDL의 상태 머신은 상태 신호 값에 의해 출력이 제어되는 클럭 프로세스입니다. 상태 신호는 이전 반복에서 발생한 일의 내부 메모리 역할을 합니다.
이 블로그 게시물은 기본 VHDL 자습서 시리즈의 일부입니다.
이 교차로의 신호등 상태를 고려하십시오.
신호등에는 식별 가능한 이름을 부여한 제한된 수의 상태가 있습니다. 우리의 예제 상태 머신에는 제어 입력이 없으며 출력은 북쪽/남쪽 및 서쪽/동쪽 방향의 조명 상태입니다. 이 상태 머신을 진행시키는 것은 경과 시간과 출력의 이전 상태입니다.
열거형을 사용하여 VHDL로 상태를 나타낼 수 있습니다. . signed
와 같은 데이터 유형입니다. 또는 unsigned
하지만 정수 대신 가능한 값의 사용자 지정 목록을 제공할 수 있습니다. 실제로 std_logic_1164 패키지를 살펴보면 std_ulogic
type은 값이 'U'
인 열거형에 불과합니다. , 'X'
, '0'
, '1'
, 'Z'
, 'W'
, 'L'
, 'H'
및 '-'
열거형 값으로 나열됩니다.
열거된 유형이 있으면 FSM의 현재 상태를 추적하는 데 사용할 수 있는 새 유형의 신호를 선언할 수 있습니다.
VHDL에서 열거형으로 신호를 선언하는 구문은 다음과 같습니다.type <type_name> is (<state_name1>, <state_name2>, ...);
signal <signal_name> : <type_name>;
상태 신호를 사용하여 유한 상태 기계는 Case 문이 있는 프로세스에서 구현될 수 있습니다. Case 문에는 가능한 각 상태에 대한 When 문이 포함되어 있어 프로그램이 모든 상태에 대해 다른 경로를 사용하도록 합니다. When 문에는 특정 상태에 있는 동안 실행되어야 하는 코드도 포함될 수 있습니다. 그러면 일반적으로 미리 정의된 조건이 충족되면 상태가 변경됩니다.
다음은 단일 프로세스 상태 시스템에 대한 템플릿입니다.process(Clk) is
begin
if rising_edge(Clk) then
if nRst = '0' then
State <= <reset_state>;
else
case State is
when <state_name> =>
<set_outputs_for_this_state_here>
if <state_change_condition_is_true> then
State <= <next_state_name>;
end if;
...
end case;
end if;
end if;
end process;
참고:
VHDL에서 FSM을 만드는 방법에는 여러 가지가 있습니다. 여기에서 다양한 스타일에 대해 읽어보세요.
1-프로세스 vs. 2-프로세스 vs. 3-프로세스 상태 머신
이 비디오 자습서에서는 VHDL에서 유한 상태 기계를 만드는 방법을 배웁니다.
상태 머신 testbench의 최종 코드 :
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity T20_FiniteStateMachineTb is end entity; architecture sim of T20_FiniteStateMachineTb 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.T20_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 T20_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 T20_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 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'; -- If 5 seconds have passed if Counter = ClockFrequencyHz * 5 -1 then Counter <= 0; State <= StartNorth; end if; -- Red and yellow in north/south direction when StartNorth => NorthRed <= '1'; NorthYellow <= '1'; WestRed <= '1'; -- If 5 seconds have passed if Counter = ClockFrequencyHz * 5 -1 then Counter <= 0; State <= North; end if; -- Green in north/south direction when North => NorthGreen <= '1'; WestRed <= '1'; -- If 1 minute has passed if Counter = ClockFrequencyHz * 60 -1 then Counter <= 0; State <= StopNorth; end if; -- Yellow in north/south direction when StopNorth => NorthYellow <= '1'; WestRed <= '1'; -- If 5 seconds have passed if Counter = ClockFrequencyHz * 5 -1 then Counter <= 0; State <= WestNext; end if; -- Red in all directions when WestNext => NorthRed <= '1'; WestRed <= '1'; -- If 5 seconds have passed if Counter = ClockFrequencyHz * 5 -1 then Counter <= 0; State <= StartWest; end if; -- Red and yellow in west/east direction when StartWest => NorthRed <= '1'; WestRed <= '1'; WestYellow <= '1'; -- If 5 seconds have passed if Counter = ClockFrequencyHz * 5 -1 then Counter <= 0; State <= West; end if; -- Green in west/east direction when West => NorthRed <= '1'; WestGreen <= '1'; -- If 1 minute has passed if Counter = ClockFrequencyHz * 60 -1 then Counter <= 0; State <= StopWest; end if; -- Yellow in west/east direction when StopWest => NorthRed <= '1'; WestYellow <= '1'; -- If 5 seconds have passed if Counter = ClockFrequencyHz * 5 -1 then Counter <= 0; State <= NorthNext; end if; end case; end if; end if; end process; end architecture;
run 5 min
를 입력한 후의 파형 ModelSim 콘솔의 명령:
우리는 신호등의 8가지 다른 상태를 모두 사용하여 열거형을 선언했습니다. 그런 다음 state
를 선언했습니다. 우리가 만든 이 새로운 유형의 신호. 이것은 신호가 8개의 명명된 상태 값 중 하나만 가질 수 있고 다른 값은 가질 수 없음을 의미합니다.
FSM은 클럭 프로세스 내에서 Case-statement를 사용하여 구현되었습니다. 클록의 각 상승 에지에서 프로세스가 깨어나고 state
신호가 평가됩니다. when
중 정확히 하나 내의 코드 현재 상태에 따라 선택 항목(가지)을 실행할 수 있습니다.
우리 코드에서는 Counter
의 값입니다. 상태 변화를 유발하는 신호. 카운터가 5초 또는 1분을 나타내는 사전 정의된 값에 도달하면 새 상태 인코딩이 State
에 할당됩니다. 신호. 그런 다음 상태 값이 업데이트된 후 클록의 다음 상승 에지에서 프로세스가 깨어나면 FSM은 다른 상태가 됩니다.
'0'
을 할당하지 않습니다. when
의 모든 신호에 선택. 이는 모든 출력 신호에 기본값 '0'
를 지정했기 때문입니다. 프로세스의 시작 부분에서. 이전 튜토리얼에서 유효하게 되는 신호에 할당된 마지막 값이라는 것을 기억할 수 있습니다. 신호 할당은 프로세스가 종료된 후에만 유효합니다. '0'
를 할당하면 프로세스 시작 시 신호에 연결한 다음 '1'
when
중 하나에서 선택하면 신호는 '1'
값을 얻습니다. .
파형에서 State
신호는 8개 상태를 순환합니다. 안정적인 녹색 상태는 1분 동안 지속되므로 파형 이미지가 North
에서 잘립니다. 및 West
상태.
다음 튜토리얼로 이동 »
VHDL
새로운 프로그래밍 언어를 배울 때 저는 항상 인쇄하는 방법을 배우는 것으로 시작하는 것을 좋아합니다. Hello World! 출력을 마스터하면 환경이 작동하고 있음을 알 수 있습니다. 또한 언어의 기본 골격, 출력을 생성하는 데 필요한 최소한의 코드도 보여줍니다. 라고 생각할 수도 있지만 VHDL은 하드웨어 설명 언어인데 어떻게 텍스트를 출력할 수 있습니까? FPGA에 연결된 화면이 필요하고 그 사이에 모든 종류의 로직이 필요하며 이는 전혀 간단하지 않습니다. 이 모든 것이 사실이지만 FPGA와 ASIC은 잠시 잊고 VHDL 언어
3D 프린팅에는 항상 사용자에 따라 달라지는 일련의 요소가 있습니다. , 인쇄가 만족스럽거나 실패하는 경우가 많습니다. 각 사용자가 각 3D 프린트에서 사용하는 프린트 프로필에 모든 요소가 수집됩니다. 3D FDM 인쇄 프로필에서 무한한 수의 매개변수를 수정할 수 있습니다. :프린팅 온도 및 속도, 내부 및 외부 부품 제조 방법 및 3D 프린팅에 영향을 미치는 나머지 모든 매개변수. 이러한 이유로 가장 중요한 정보는 인쇄 프로필을 만들 때 아래에서 설명합니다. 고려할 측면 인쇄 매개변수를 수정하기 전에 직접적으로 영향을 미치