uart_rx: bitorder fail
[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                 -- test: uart-tx
23                 tx_data : out std_logic_vector(7 downto 0);
24                 tx_new : out std_logic;
25                 -- test: uart_rx
26                 rx_data : in std_logic_vector(7 downto 0);
27                 rx_new : in std_logic
28         );
29 end entity scanner;
30
31 architecture beh of scanner is
32         type SCANNER_STATE is (SIDLE, SIGNORE_NEXT, SREAD_NEXT, STAKE, SDEL, SENTER,
33                 STAKE_RS232);
34         signal state_int, state_next : SCANNER_STATE;
35         signal s_char_int, s_char_next : hbyte;
36         signal s_take_int, s_take_next : std_logic;
37         signal s_backspace_int, s_backspace_next : std_logic;
38         signal do_it_int, do_it_next : std_logic;
39         signal tx_data_int, tx_data_next : std_logic_vector(7 downto 0);
40         signal tx_new_int, tx_new_next : std_logic;
41 begin
42         s_char <= s_char_int;
43         s_take <= s_take_int;
44         s_backspace <= s_backspace_int;
45         do_it <= do_it_int;
46         tx_new <= tx_new_int;
47         tx_data <= tx_data_int;
48
49         process(sys_clk, sys_res_n)
50         begin
51                 if sys_res_n = '0' then
52                         -- internal
53                         state_int <= SIDLE;
54                         -- out
55                         s_char_int <= (others => '0');
56                         s_take_int <= '0';
57                         s_backspace_int <= '0';
58                         do_it_int <= '0';
59                         tx_new_int <= '0';
60                         tx_data_int <= (others => '0');
61                 elsif rising_edge(sys_clk) then
62                         -- internal
63                         state_int <= state_next;
64                         -- out
65                         s_char_int <= s_char_next;
66                         s_take_int <= s_take_next;
67                         s_backspace_int <= s_backspace_next;
68                         do_it_int <= do_it_next;
69                         tx_new_int <= tx_new_next;
70                         tx_data_int <= tx_data_next;
71                 end if;
72         end process;
73
74         -- next state
75         process(state_int, new_data, data, finished, s_done, tx_data_int)
76         begin
77                 state_next <= state_int;
78                 tx_new_next <= '0';
79                 tx_data_next <= tx_data_int;
80
81                 case state_int is
82                         when SIDLE =>
83                                 if new_data = '1' then
84                                         case data is
85                                                 when x"f0" =>
86                                                         state_next <= SIGNORE_NEXT;
87                                                 when x"e0" =>
88                                                         state_next <= SREAD_NEXT;
89                                                 when SC_BKSP =>
90                                                         state_next <= SDEL;
91                                                 when SC_ENTER =>
92                                                         state_next <= SENTER;
93                                                 when SC_KP_0 | SC_KP_1 | SC_KP_2 |
94                                                         SC_KP_3 | SC_KP_4 | SC_KP_5 | SC_KP_6 |
95                                                         SC_KP_7 | SC_KP_8 | SC_KP_9 |
96                                                         SC_0 | SC_1 | SC_2 | SC_3 | SC_4 |
97                                                         SC_5 | SC_6 | SC_7 | SC_8 | SC_9 |
98                                                         SC_PLUS | SC_KP_PLUS |
99                                                         SC_KP_MINUS | SC_KP_MUL | SC_SPACE =>
100                                                                 state_next <= STAKE;
101                                                 when others => state_next <= SIDLE;
102                                         end case;
103                                 end if;
104                                 if rx_new = '1' then
105                                         state_next <= STAKE_RS232;
106                                 end if;
107                         when SIGNORE_NEXT =>
108                                 if new_data = '1' then
109                                         state_next <= SIDLE;
110                                 end if;
111                         when SREAD_NEXT =>
112                                 if new_data = '1' then
113                                         case data is
114                                                 when x"f0" =>
115                                                         state_next <= SIGNORE_NEXT;
116                                                 when SC_ENTER =>
117                                                         state_next <= SENTER;
118                                                 when SC_KP_DIV =>
119                                                         state_next <= STAKE;
120                                                 when others => state_next <= SIDLE;
121                                         end case;
122                                 end if;
123                         when STAKE | SDEL | STAKE_RS232=>
124                                 if s_done = '1' then
125                                         state_next <= SIDLE;
126                                 end if;
127                         when SENTER =>
128                                 if finished = '1' then
129                                         tx_new_next <= '1';
130                                         tx_data_next <= x"42";
131                                         state_next <= SIDLE;
132                                 end if;
133                 end case;
134         end process;
135
136         -- out
137         process(state_int, data, s_char_int, new_data, rx_data)
138                 function sc2ascii (x : hbyte) return hbyte is
139                         variable y : hbyte;
140                 begin
141                         case x is
142                                 when SC_KP_0 | SC_0 => y := x"30";
143                                 when SC_KP_1 | SC_1 => y := x"31";
144                                 when SC_KP_2 | SC_2 => y := x"32";
145                                 when SC_KP_3 | SC_3 => y := x"33";
146                                 when SC_KP_4 | SC_4 => y := x"34";
147                                 when SC_KP_5 | SC_5 => y := x"35";
148                                 when SC_KP_6 | SC_6 => y := x"36";
149                                 when SC_KP_7 | SC_7 => y := x"37";
150                                 when SC_KP_8 | SC_8 => y := x"38";
151                                 when SC_KP_9 | SC_9 => y := x"39";
152                                 when SC_KP_PLUS | SC_PLUS => y := x"2b";
153                                 when SC_KP_MINUS => y := x"2d";
154                                 when SC_KP_MUL => y := x"2a";
155                                 when SC_KP_DIV => y := x"2f";
156                                 when SC_SPACE => y := x"20";
157                                 when others => y := x"41";
158                         end case;
159                         return y;
160                 end function;
161         begin
162                 s_char_next <= s_char_int;
163                 s_take_next <= '0';
164                 s_backspace_next <= '0';
165                 do_it_next <= '0';
166
167                 case state_int is
168                         when SIDLE => null;
169                         when SIGNORE_NEXT => null;
170                         when SREAD_NEXT => null;
171                         when STAKE =>
172                                 s_take_next <= '1';
173                                 s_char_next <= sc2ascii(hbyte(data));
174                         when STAKE_RS232 =>
175                                 s_take_next <= '1';
176                                 if rx_data >= x"30" and rx_data <= x"39" then
177                                         s_char_next <= hbyte(rx_data);
178                                 else
179                                         s_char_next <= x"41";
180                                 end if;
181                         when SDEL =>
182                                 s_take_next <= '1';
183                                 s_backspace_next <= '1';
184                         when SENTER =>
185                                 do_it_next <= '1';
186                 end case;
187         end process;
188 end architecture beh;