87 lines
1.9 KiB
VHDL
87 lines
1.9 KiB
VHDL
|
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;
|