﻿<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="thpdoc.xsl"?>
<page id="enum" suffix=" Keyword">
  <subsection>Defines an enumeration.<code>enum EnumName
{
	Value1,
	...,
	ValueN
}

enum EnumName2(BaseType)
{
	Value1,
	Value2 = ExactValue,
	...,
	ValueN
}</code>
	THDL++ supports 2 types of enumerations: typed and untyped. Untyped enumerations will be converted to VHDL enumerations, while typed enumerations (e.g. based on a logic vector) will be converted to a corresponding VHDL type. To specify an enum value, you need to specify the enumeration name as well (e.g. CurState = StateEnum.State1).
</subsection>
<subsection name="Remarks">
	<p>Typed and untyped enumerations have the same use syntax. It is recommended to use untyped enums for encoding the states, as the simulator will produce more meaningful results and the synthesis tool will be able to find a good encoding scheme. Typed enums are useful when you want to make a state variable visible outside your entity (e.g. via LEDs or a software-accessible register).</p>
</subsection>
  <examples>
	<example name="Untyped enumeration"><code>entity SomeFSM
{
    port in logic clk, reset;
    port in logic Start;
    
    enum State
    {
    	Initial,
    	Reading,
    	Writing,
    }
    
    signal State CurrentState = State.Initial;
    
    process StateFlow (clk.rising) autoreset(reset)
    {
    	switch(CurrentState)
    	{
    	case State.Initial:
    		if (Start)
    			CurrentState = State.Reading;
    		break;
    	case State.Reading:
    		CurrentState = State.Writing;
    		break;
    	case State.Writing:
    		CurrentState = State.Initial;
    		break;
    	}
    }
}</code>
	The following VHDL code will be generated:
<code>package thp_types_and_functions is
	type Some_FSM_State is (
		Initial,
		Reading,
		Writing
	);
end package thp_types_and_functions;

entity Some_FSM is
	Port (
		clk : in std_logic;
		reset : in std_logic;
		Start : in std_logic
	);
	
end entity Some_FSM;

architecture Behavioral of Some_FSM is
	signal Current_State : Some_FSM_State := Initial;
	
	begin
		StateFlow : process (clk, reset) is
		begin
			if reset = '1' then
				Current_State &lt;= Initial;
			elsif rising_edge(clk) then
				case Current_State is
					when Initial =&gt;
						if (Start /= '0') then
							Current_State &lt;= Reading;
						end if;
					when Reading =&gt;
						Current_State &lt;= Writing;
					when Writing =&gt;
						Current_State &lt;= Initial;
				end case;
			end if;
		end process StateFlow;
		
		
end architecture Behavioral;</code>
</example>
<example name="Typed enumeration">
Let's modify the previous example to make the enumeration typed:
<code>enum State(logic[2])
{
	Initial = 1,
	Reading,
	Writing,
}</code>
The generated VHDL code will now look differently. Some_FSM_State will be replaced by std_logic_vector and the state names will be replaced by named constants:
<code>package thp_types_and_functions is
	constant Some_FSM_State_Initial: std_logic_vector(1 downto 0) := B"01";
	constant Some_FSM_State_Reading: std_logic_vector(1 downto 0) := B"10";
	constant Some_FSM_State_Writing: std_logic_vector(1 downto 0) := B"11";
end package thp_types_and_functions;

entity Some_FSM is
	Port (
		clk : in std_logic;
		reset : in std_logic;
		Start : in std_logic
	);
	
end entity Some_FSM;

architecture Behavioral of Some_FSM is
	signal Current_State : std_logic_vector(1 downto 0) := Some_FSM_State_Initial;
	
	begin
		StateFlow : process (clk, reset) is
		begin
			if reset = '1' then
				Current_State &lt;= Some_FSM_State_Initial;
			elsif rising_edge(clk) then
				case Current_State is
					when Some_FSM_State_Initial =&gt;
						if (Start /= '0') then
							Current_State &lt;= Some_FSM_State_Reading;
						end if;
					when Some_FSM_State_Reading =&gt;
						Current_State &lt;= Some_FSM_State_Writing;
					when Some_FSM_State_Writing =&gt;
						Current_State &lt;= Some_FSM_State_Initial;
				end case;
			end if;
		end process StateFlow;
		
end architecture Behavioral;
</code>
</example>
  </examples>
  <seealso id="switch"/>
  <seealso id="switchall"/>
  <seealso id="select"/>
  <seealso id="selectall"/>
</page>