library ieee; use ieee.std_logic_1164.all; entity parser is port ( clk : in std_logic; reset : in std_logic; is_record : in std_logic; is_data : out std_logic; char : in character; num1, num2 : out natural range 0 to 99; letter : out character ); end entity; architecture behaviour of parser is type state_t is (S_NUM1, S_NUM2, S_LETTER, S_COLON, S_END_SPACE, S_DATA); signal state : state_t := S_NUM1; subtype digit is natural range 0 to 9; type multiples_lookup_t is array(digit) of natural range 0 to 90; constant TEN_MULTIPLES : multiples_lookup_t := (0, 10, 20, 30, 40, 50, 60, 70, 80, 90); -- most significant digit of number signal prev_digit : digit := 0; signal current_digit : digit; signal complete_num : natural range 0 to 99; function char_to_digit(input : in character) return digit is begin if input >= '0' and input <= '9' then return character'pos(input) - character'pos('0'); else return 0; end if; end function; begin current_digit <= char_to_digit(char); complete_num <= TEN_MULTIPLES(prev_digit) + current_digit; process(clk) begin if rising_edge(clk) then if reset then prev_digit <= 0; state <= S_NUM1; else prev_digit <= 0; case state is when S_NUM1 => if is_record then if char = '-' then state <= S_NUM2; else num1 <= complete_num; prev_digit <= current_digit; end if; end if; when S_NUM2 => if char = ' ' then state <= S_LETTER; else num2 <= complete_num; prev_digit <= current_digit; end if; when S_LETTER => letter <= char; state <= S_COLON; when S_COLON => state <= S_END_SPACE; when S_END_SPACE => state <= S_DATA; when S_DATA => if not is_record then state <= S_NUM1; end if; end case; end if; end if; end process; is_data <= '1' when state = S_DATA else '0'; end architecture;