81 lines
1.8 KiB
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;
|