advent-of-code/2020/day2/vhdl/parser.vhdl

81 lines
1.8 KiB
VHDL

library ieee;
use ieee.std_logic_1164.all;
use work.util.all;
entity parser is
port (
clk : in std_logic;
reset : in std_logic;
is_data : out std_logic;
record_end : out std_logic;
char : in character;
input_valid : in std_logic;
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;
type multiples_lookup_t is array(digit_t) 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_t := 0;
signal current_digit : digit_t;
signal complete_num : natural range 0 to 99;
begin
current_digit <= char_to_digit(char);
complete_num <= TEN_MULTIPLES(prev_digit) + current_digit;
process(clk)
begin
if rising_edge(clk) then
record_end <= '0';
if reset then
prev_digit <= 0;
state <= S_NUM1;
elsif input_valid then
prev_digit <= 0;
case state is
when S_NUM1 =>
if char = '-' then
state <= S_NUM2;
else
num1 <= complete_num;
prev_digit <= current_digit;
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 char = LF then
state <= S_NUM1;
record_end <= '1';
end if;
end case;
end if;
end if;
end process;
is_data <= '1' when state = S_DATA else '0';
end architecture;