875cddda4a88fa9979823c6bba6e46ceb2ae9f73
[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 (SINIT, SIDLE, SREAD, 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         signal was_f0_int, was_f0_next : std_logic;
33 begin
34         s_char <= s_char_int;
35         s_take <= s_take_int;
36         s_backspace <= s_backspace_int;
37         do_it <= do_it_int;
38
39         process(sys_clk, sys_res_n)
40         begin
41                 if sys_res_n = '0' then
42                         -- internal
43                         state_int <= SINIT;
44                         was_f0_int <= '0';
45                         -- out
46                         s_char_int <= (others => '0');
47                         s_take_int <= '0';
48                         s_backspace_int <= '0';
49                         do_it_int <= '0';
50                 elsif rising_edge(sys_clk) then
51                         -- internal
52                         state_int <= state_next;
53                         was_f0_int <= was_f0_next;
54                         -- out
55                         s_char_int <= s_char_next;
56                         s_take_int <= s_take_next;
57                         s_backspace_int <= s_backspace_next;
58                         do_it_int <= do_it_next;
59                 end if;
60         end process;
61
62         -- next state
63         process(state_int, new_data, data, finished, s_done, was_f0_int)
64         begin
65                 state_next <= state_int;
66
67                 case state_int is
68                         when SINIT =>
69                                 state_next <= SIDLE;
70                         when SIDLE =>
71                                 if new_data = '1' and was_f0_int = '1' then
72                                         state_next <= SREAD;
73                                 end if;
74                         when SREAD =>
75                                 case data is
76                                         when SC_BKSP => state_next <= SDEL;
77                                         when SC_ENTER => state_next <= SENTER;
78                                         when SC_KP_0 | SC_KP_1 | SC_KP_2 | SC_KP_3 |
79                                                 SC_KP_4 | SC_KP_5 | SC_KP_6 | SC_KP_7 |
80                                                 SC_KP_8 | SC_KP_9 | SC_KP_PLUS |
81                                                 SC_KP_MINUS | SC_KP_MUL | SC_SPACE |
82                                                 SC_KP_DIV => state_next <= STAKE;
83                                         when others => state_next <= SIDLE;
84                                 end case;
85                         when STAKE | SDEL=>
86                                 if s_done = '1' then
87                                         state_next <= SIDLE;
88                                 end if;
89                         when SENTER =>
90                                 if finished = '1' then
91                                         state_next <= SIDLE;
92                                 end if;
93                 end case;
94         end process;
95
96         -- out
97         process(state_int, data, s_char_int, new_data, was_f0_int)
98                 function sc2ascii (x : hbyte) return hbyte is
99                         variable y : hbyte;
100                 begin
101                         case x is
102                                 when SC_KP_0 => y := x"30";
103                                 when SC_KP_1 => y := x"31";
104                                 when SC_KP_2 => y := x"32";
105                                 when SC_KP_3 => y := x"33";
106                                 when SC_KP_4 => y := x"34";
107                                 when SC_KP_5 => y := x"35";
108                                 when SC_KP_6 => y := x"36";
109                                 when SC_KP_7 => y := x"37";
110                                 when SC_KP_8 => y := x"38";
111                                 when SC_KP_9 => y := x"39";
112                                 when SC_KP_PLUS => y := x"2b";
113                                 when SC_KP_MINUS => y := x"2d";
114                                 when SC_KP_MUL => y := x"2a";
115                                 when SC_KP_DIV => y := x"2f";
116                                 when SC_SPACE => y := x"20";
117                                 when others => y := x"41";
118                         end case;
119                         return y;
120                 end function;
121         begin
122                 s_char_next <= s_char_int;
123                 s_take_next <= '0';
124                 s_backspace_next <= '0';
125                 do_it_next <= '0';
126                 was_f0_next <= was_f0_int;
127
128                 case state_int is
129                         when SINIT =>
130                                 was_f0_next <= '0';
131                         when SIDLE =>
132                                 if new_data = '1' and data = x"f0" then
133                                         was_f0_next <= '1';
134                                 end if;
135                         when SREAD =>
136                                 was_f0_next <= '0';
137                         when STAKE =>
138                                 s_take_next <= '1';
139                                 s_char_next <= sc2ascii(hbyte(data));
140                         when SDEL =>
141                                 s_take_next <= '1';
142                                 s_backspace_next <= '1';
143                         when SENTER =>
144                                 do_it_next <= '1';
145                 end case;
146         end process;
147 end architecture beh;