uart_rx: ein prozessmodell. spart weitere 3 logic elements :P
[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, SIGNORE_NEXT, SREAD_NEXT, 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         begin
62                 state_next <= state_int;
63
64                 case state_int is
65                         when SIDLE =>
66                                 if new_data = '1' then
67                                         case data is
68                                                 when x"f0" =>
69                                                         state_next <= SIGNORE_NEXT;
70                                                 when x"e0" =>
71                                                         state_next <= SREAD_NEXT;
72                                                 when SC_BKSP =>
73                                                         state_next <= SDEL;
74                                                 when SC_ENTER =>
75                                                         state_next <= SENTER;
76                                                 when SC_KP_0 | SC_KP_1 | SC_KP_2 |
77                                                         SC_KP_3 | SC_KP_4 | SC_KP_5 | SC_KP_6 |
78                                                         SC_KP_7 | SC_KP_8 | SC_KP_9 |
79                                                         SC_0 | SC_1 | SC_2 | SC_3 | SC_4 |
80                                                         SC_5 | SC_6 | SC_7 | SC_8 | SC_9 |
81                                                         SC_PLUS | SC_KP_PLUS |
82                                                         SC_KP_MINUS | SC_KP_MUL | SC_SPACE =>
83                                                                 state_next <= STAKE;
84                                                 when others => state_next <= SIDLE;
85                                         end case;
86                                 end if;
87                         when SIGNORE_NEXT =>
88                                 if new_data = '1' then
89                                         state_next <= SIDLE;
90                                 end if;
91                         when SREAD_NEXT =>
92                                 if new_data = '1' then
93                                         case data is
94                                                 when x"f0" =>
95                                                         state_next <= SIGNORE_NEXT;
96                                                 when SC_ENTER =>
97                                                         state_next <= SENTER;
98                                                 when SC_KP_DIV =>
99                                                         state_next <= STAKE;
100                                                 when others => state_next <= SIDLE;
101                                         end case;
102                                 end if;
103                         when STAKE | SDEL=>
104                                 if s_done = '1' then
105                                         state_next <= SIDLE;
106                                 end if;
107                         when SENTER =>
108                                 if finished = '1' then
109                                         state_next <= SIDLE;
110                                 end if;
111                 end case;
112         end process;
113
114         -- out
115         process(state_int, data, s_char_int, new_data)
116                 function sc2ascii (x : hbyte) return hbyte is
117                         variable y : hbyte;
118                 begin
119                         case x is
120                                 when SC_KP_0 | SC_0 => y := x"30";
121                                 when SC_KP_1 | SC_1 => y := x"31";
122                                 when SC_KP_2 | SC_2 => y := x"32";
123                                 when SC_KP_3 | SC_3 => y := x"33";
124                                 when SC_KP_4 | SC_4 => y := x"34";
125                                 when SC_KP_5 | SC_5 => y := x"35";
126                                 when SC_KP_6 | SC_6 => y := x"36";
127                                 when SC_KP_7 | SC_7 => y := x"37";
128                                 when SC_KP_8 | SC_8 => y := x"38";
129                                 when SC_KP_9 | SC_9 => y := x"39";
130                                 when SC_KP_PLUS | SC_PLUS => y := x"2b";
131                                 when SC_KP_MINUS => y := x"2d";
132                                 when SC_KP_MUL => y := x"2a";
133                                 when SC_KP_DIV => y := x"2f";
134                                 when SC_SPACE => y := x"20";
135                                 when others => y := x"41";
136                         end case;
137                         return y;
138                 end function;
139         begin
140                 s_char_next <= s_char_int;
141                 s_take_next <= '0';
142                 s_backspace_next <= '0';
143                 do_it_next <= '0';
144
145                 case state_int is
146                         when SIDLE => null;
147                         when SIGNORE_NEXT => null;
148                         when SREAD_NEXT => null;
149                         when STAKE =>
150                                 s_take_next <= '1';
151                                 s_char_next <= sc2ascii(hbyte(data));
152                         when SDEL =>
153                                 s_take_next <= '1';
154                                 s_backspace_next <= '1';
155                         when SENTER =>
156                                 do_it_next <= '1';
157                 end case;
158         end process;
159 end architecture beh;