scanner: hoffentlich passen meinen annahmen ueber das ps/2 modul
[hwmod.git] / src / scanner.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4 use work.gen_pkg.all;
5
6 entity scanner is
7         port
8         (
9                 sys_clk : in std_logic;
10                 sys_res_n : in std_logic;
11                 -- PS/2
12                 new_data : in std_logic;
13                 data : in std_logic_vector(7 downto 0);
14                 -- History
15                 s_char : out hbyte;
16                 s_take : out std_logic;
17                 s_done : in std_logic;
18                 s_backspace : out std_logic;
19                 -- Parser
20                 do_it : out std_logic;
21                 finished : in std_logic
22         );
23 end entity scanner;
24
25 architecture beh of scanner is
26         type SCANNER_STATE is (SIDLE, SREAD, SMOD, STAKE, SDEL, SENTER);
27         signal state_int, state_next : SCANNER_STATE;
28         signal s_char_int, s_char_next : hbyte;
29         signal s_take_int, s_take_next : std_logic;
30         signal s_backspace_int, s_backspace_next : std_logic;
31         signal do_it_int, do_it_next : std_logic;
32 begin
33         s_char <= s_char_int;
34         s_take <= s_take_int;
35         s_backspace <= s_backspace_int;
36         do_it <= do_it_int;
37
38         process(sys_clk, sys_res_n)
39         begin
40                 if sys_res_n = '0' then
41                         -- internal
42                         state_int <= SIDLE;
43                         -- out
44                         s_char_int <= (others => '0');
45                         s_take_int <= '0';
46                         s_backspace_int <= '0';
47                         do_it_int <= '0';
48                 elsif rising_edge(sys_clk) then
49                         -- internal
50                         state_int <= state_next;
51                         -- out
52                         s_char_int <= s_char_next;
53                         s_take_int <= s_take_next;
54                         s_backspace_int <= s_backspace_next;
55                         do_it_int <= do_it_next;
56                 end if;
57         end process;
58
59         -- next state
60         process(state_int, new_data, data, finished, s_done)
61                 function valid_char (x : std_logic_vector(7 downto 0)) return boolean is
62                         variable y : boolean;
63                 begin
64                         case x is
65                                 -- 0 - 4
66                                 when x"30" | x"31" | x"32" | x"33" | x"34" => y := true;
67                                 -- 5 - 9
68                                 when x"35" | x"36" | x"37" | x"38" | x"39" => y := true;
69                                 -- *, +, -, /
70                                 when x"2a" | x"2b" | x"2d" | x"2f" => y := true;
71                                 when others => y := false;
72                         end case;
73                         return y;
74                 end function;
75         begin
76                 state_next <= state_int;
77
78                 case state_int is
79                         when SIDLE =>
80                                 if new_data = '1' and finished = '0' and s_done = '0' then
81                                         state_next <= SREAD;
82                                 end if;
83                         when SREAD =>
84                                 case data is
85                                         when x"e0" => state_next <= SMOD;
86                                         when x"0e" => state_next <= SDEL;
87                                         when x"1c" => state_next <= SENTER;
88                                         when x"20" => state_next <= STAKE;
89                                         when others => state_next <= SIDLE;
90                                 end case;
91                         when SMOD =>
92                                 if new_data = '1' then
93                                         if valid_char(data) then
94                                                 state_next <= STAKE;
95                                         else
96                                                 state_next <= SIDLE;
97                                         end if;
98                                 end if;
99                         when STAKE | SDEL=>
100                                 if s_done = '1' then
101                                         state_next <= SIDLE;
102                                 end if;
103                         when SENTER =>
104                                 if finished = '1' then
105                                         state_next <= SIDLE;
106                                 end if;
107                 end case;
108         end process;
109
110         -- out
111         process(state_int)
112         begin
113                 s_char_next <= (others => '0');
114                 s_take_next <= '0';
115                 s_backspace_next <= '0';
116                 do_it_next <= '0';
117
118                 case state_int is
119                         when SIDLE =>
120                                 null;
121                         when SREAD =>
122                                 null;
123                         when SMOD =>
124                                 null;
125                         when STAKE =>
126                                 s_take_next <= '1';
127                                 s_char_next <= hbyte(data);
128                         when SDEL =>
129                                 s_take_next <= '1';
130                                 s_backspace_next <= '1';
131                         when SENTER =>
132                                 do_it_next <= '1';
133                 end case;
134         end process;
135 end architecture beh;