1 -------------------------------------------------------------------------
\r
3 -- Filename: ps2_transceiver_beh.vhd
\r
6 -- Short Description:
\r
7 -- ==================
\r
8 -- Behavioral implementation of the PS/2 transceiver
\r
10 -------------------------------------------------------------------------
\r
13 use ieee.std_logic_1164.all;
\r
15 architecture beh of ps2_transceiver is
\r
16 constant PREPARE_TIMEOUT1_MAX : integer := CLK_FREQ / 5000; -- 200 us
\r
17 constant PREPARE_TIMEOUT2_MAX : integer := CLK_FREQ / 100000; -- 10 us
\r
18 type PS2_TRANSCEIVER_STATE_TYPE is
\r
22 PREPARE_SEND_ASSIGN_CLK, PREPARE_SEND_WAIT1, PREPARE_SEND_DATA, PREPARE_SEND_WAIT2,
\r
23 PREPARE_SEND_RELEASE_CLK, SEND_WAIT_DATA0, SEND_DATA0, SEND_WAIT_DATA1, SEND_DATA1,
\r
24 SEND_WAIT_DATA2, SEND_DATA2, SEND_WAIT_DATA3, SEND_DATA3, SEND_WAIT_DATA4, SEND_DATA4,
\r
25 SEND_WAIT_DATA5, SEND_DATA5, SEND_WAIT_DATA6, SEND_DATA6, SEND_WAIT_DATA7, SEND_DATA7,
\r
26 SEND_WAIT_PARITY, SEND_PARITY, SEND_WAIT_STOP, SEND_STOP, SEND_WAIT_ACK1, SEND_WAIT_ACK2,
\r
27 SEND_READ_ACK, SEND_FINISH,
\r
29 RECEIVE_START, RECEIVE_WAIT_DATA0, RECEIVE_DATA0, RECEIVE_WAIT_DATA1, RECEIVE_DATA1,
\r
30 RECEIVE_WAIT_DATA2, RECEIVE_DATA2, RECEIVE_WAIT_DATA3, RECEIVE_DATA3, RECEIVE_WAIT_DATA4,
\r
31 RECEIVE_DATA4, RECEIVE_WAIT_DATA5, RECEIVE_DATA5, RECEIVE_WAIT_DATA6, RECEIVE_DATA6,
\r
32 RECEIVE_WAIT_DATA7, RECEIVE_DATA7, RECEIVE_WAIT_PARITY, RECEIVE_PARITY, RECEIVE_WAIT_STOP,
\r
35 signal ps2_transceiver_state, ps2_transceiver_state_next : PS2_TRANSCEIVER_STATE_TYPE;
\r
36 signal ps2_clk_last, ps2_clk_internal, ps2_clk_next, ps2_clk_hz, ps2_clk_hz_next : std_logic;
\r
37 signal ps2_data_internal, ps2_data_next, ps2_data_hz, ps2_data_hz_next : std_logic;
\r
38 signal ps2_clk_sync, ps2_data_sync : std_logic_vector(1 to SYNC_STAGES);
\r
39 signal output_data_next, output_data_internal : std_logic_vector(7 downto 0);
\r
40 signal parity, parity_next : std_logic;
\r
41 signal new_data_next : std_logic;
\r
42 signal prepare_timeout1, prepare_timeout1_next : integer range 0 to PREPARE_TIMEOUT1_MAX;
\r
43 signal prepare_timeout2, prepare_timeout2_next : integer range 0 to PREPARE_TIMEOUT2_MAX;
\r
46 process(ps2_transceiver_state, ps2_clk_sync(SYNC_STAGES), ps2_clk_last, ps2_data_sync(SYNC_STAGES), send_request, prepare_timeout1, prepare_timeout2, output_data_internal)
\r
48 ps2_transceiver_state_next <= ps2_transceiver_state;
\r
50 case ps2_transceiver_state is
\r
52 if ps2_clk_sync(SYNC_STAGES) = '1' and ps2_clk_last = '0' then
\r
53 if ps2_data_sync(SYNC_STAGES) = '0' then
\r
54 ps2_transceiver_state_next <= RECEIVE_START;
\r
56 elsif send_request = '1' then
\r
57 ps2_transceiver_state_next <= PREPARE_SEND_ASSIGN_CLK;
\r
61 when PREPARE_SEND_ASSIGN_CLK =>
\r
62 ps2_transceiver_state_next <= PREPARE_SEND_WAIT1;
\r
63 when PREPARE_SEND_WAIT1 =>
\r
64 if prepare_timeout1 = PREPARE_TIMEOUT1_MAX - 1 then
\r
65 ps2_transceiver_state_next <= PREPARE_SEND_DATA;
\r
67 when PREPARE_SEND_DATA =>
\r
68 ps2_transceiver_state_next <= PREPARE_SEND_WAIT2;
\r
69 when PREPARE_SEND_WAIT2 =>
\r
70 if prepare_timeout2 = PREPARE_TIMEOUT2_MAX - 1 then
\r
71 ps2_transceiver_state_next <= PREPARE_SEND_RELEASE_CLK;
\r
73 when PREPARE_SEND_RELEASE_CLK =>
\r
74 ps2_transceiver_state_next <= SEND_WAIT_DATA0;
\r
75 when SEND_WAIT_DATA0 =>
\r
76 if ps2_clk_sync(SYNC_STAGES) = '0' and ps2_clk_last = '1' then
\r
77 ps2_transceiver_state_next <= SEND_DATA0;
\r
80 ps2_transceiver_state_next <= SEND_WAIT_DATA1;
\r
81 when SEND_WAIT_DATA1 =>
\r
82 if ps2_clk_sync(SYNC_STAGES) = '0' and ps2_clk_last = '1' then
\r
83 ps2_transceiver_state_next <= SEND_DATA1;
\r
86 ps2_transceiver_state_next <= SEND_WAIT_DATA2;
\r
87 when SEND_WAIT_DATA2 =>
\r
88 if ps2_clk_sync(SYNC_STAGES) = '0' and ps2_clk_last = '1' then
\r
89 ps2_transceiver_state_next <= SEND_DATA2;
\r
92 ps2_transceiver_state_next <= SEND_WAIT_DATA3;
\r
93 when SEND_WAIT_DATA3 =>
\r
94 if ps2_clk_sync(SYNC_STAGES) = '0' and ps2_clk_last = '1' then
\r
95 ps2_transceiver_state_next <= SEND_DATA3;
\r
98 ps2_transceiver_state_next <= SEND_WAIT_DATA4;
\r
99 when SEND_WAIT_DATA4 =>
\r
100 if ps2_clk_sync(SYNC_STAGES) = '0' and ps2_clk_last = '1' then
\r
101 ps2_transceiver_state_next <= SEND_DATA4;
\r
104 ps2_transceiver_state_next <= SEND_WAIT_DATA5;
\r
105 when SEND_WAIT_DATA5 =>
\r
106 if ps2_clk_sync(SYNC_STAGES) = '0' and ps2_clk_last = '1' then
\r
107 ps2_transceiver_state_next <= SEND_DATA5;
\r
110 ps2_transceiver_state_next <= SEND_WAIT_DATA6;
\r
111 when SEND_WAIT_DATA6 =>
\r
112 if ps2_clk_sync(SYNC_STAGES) = '0' and ps2_clk_last = '1' then
\r
113 ps2_transceiver_state_next <= SEND_DATA6;
\r
116 ps2_transceiver_state_next <= SEND_WAIT_DATA7;
\r
117 when SEND_WAIT_DATA7 =>
\r
118 if ps2_clk_sync(SYNC_STAGES) = '0' and ps2_clk_last = '1' then
\r
119 ps2_transceiver_state_next <= SEND_DATA7;
\r
122 ps2_transceiver_state_next <= SEND_WAIT_PARITY;
\r
123 when SEND_WAIT_PARITY =>
\r
124 if ps2_clk_sync(SYNC_STAGES) = '0' and ps2_clk_last = '1' then
\r
125 ps2_transceiver_state_next <= SEND_PARITY;
\r
127 when SEND_PARITY =>
\r
128 ps2_transceiver_state_next <= SEND_WAIT_STOP;
\r
129 when SEND_WAIT_STOP =>
\r
130 if ps2_clk_sync(SYNC_STAGES) = '0' and ps2_clk_last = '1' then
\r
131 ps2_transceiver_state_next <= SEND_STOP;
\r
134 ps2_transceiver_state_next <= SEND_WAIT_ACK1;
\r
135 when SEND_WAIT_ACK1 =>
\r
136 if ps2_clk_sync(SYNC_STAGES) = '0' and ps2_clk_last = '1' then -- ACK is written by device
\r
137 ps2_transceiver_state_next <= SEND_WAIT_ACK2;
\r
139 when SEND_WAIT_ACK2 =>
\r
140 if ps2_clk_sync(SYNC_STAGES) = '1' and ps2_clk_last = '0' then -- ACK is valid
\r
141 ps2_transceiver_state_next <= SEND_READ_ACK;
\r
143 when SEND_READ_ACK =>
\r
144 ps2_transceiver_state_next <= SEND_FINISH;
\r
145 when SEND_FINISH =>
\r
146 ps2_transceiver_state_next <= IDLE;
\r
150 when RECEIVE_START =>
\r
151 ps2_transceiver_state_next <= RECEIVE_WAIT_DATA0;
\r
152 when RECEIVE_WAIT_DATA0 =>
\r
153 if ps2_clk_sync(SYNC_STAGES) = '0' and ps2_clk_last = '1' then
\r
154 ps2_transceiver_state_next <= RECEIVE_DATA0;
\r
156 when RECEIVE_DATA0 =>
\r
157 ps2_transceiver_state_next <= RECEIVE_WAIT_DATA1;
\r
158 when RECEIVE_WAIT_DATA1 =>
\r
159 if ps2_clk_sync(SYNC_STAGES) = '0' and ps2_clk_last = '1' then
\r
160 ps2_transceiver_state_next <= RECEIVE_DATA1;
\r
162 when RECEIVE_DATA1 =>
\r
163 ps2_transceiver_state_next <= RECEIVE_WAIT_DATA2;
\r
164 when RECEIVE_WAIT_DATA2 =>
\r
165 if ps2_clk_sync(SYNC_STAGES) = '0' and ps2_clk_last = '1' then
\r
166 ps2_transceiver_state_next <= RECEIVE_DATA2;
\r
168 when RECEIVE_DATA2 =>
\r
169 ps2_transceiver_state_next <= RECEIVE_WAIT_DATA3;
\r
170 when RECEIVE_WAIT_DATA3 =>
\r
171 if ps2_clk_sync(SYNC_STAGES) = '0' and ps2_clk_last = '1' then
\r
172 ps2_transceiver_state_next <= RECEIVE_DATA3;
\r
174 when RECEIVE_DATA3 =>
\r
175 ps2_transceiver_state_next <= RECEIVE_WAIT_DATA4;
\r
176 when RECEIVE_WAIT_DATA4 =>
\r
177 if ps2_clk_sync(SYNC_STAGES) = '0' and ps2_clk_last = '1' then
\r
178 ps2_transceiver_state_next <= RECEIVE_DATA4;
\r
180 when RECEIVE_DATA4 =>
\r
181 ps2_transceiver_state_next <= RECEIVE_WAIT_DATA5;
\r
182 when RECEIVE_WAIT_DATA5 =>
\r
183 if ps2_clk_sync(SYNC_STAGES) = '0' and ps2_clk_last = '1' then
\r
184 ps2_transceiver_state_next <= RECEIVE_DATA5;
\r
186 when RECEIVE_DATA5 =>
\r
187 ps2_transceiver_state_next <= RECEIVE_WAIT_DATA6;
\r
188 when RECEIVE_WAIT_DATA6 =>
\r
189 if ps2_clk_sync(SYNC_STAGES) = '0' and ps2_clk_last = '1' then
\r
190 ps2_transceiver_state_next <= RECEIVE_DATA6;
\r
192 when RECEIVE_DATA6 =>
\r
193 ps2_transceiver_state_next <= RECEIVE_WAIT_DATA7;
\r
194 when RECEIVE_WAIT_DATA7 =>
\r
195 if ps2_clk_sync(SYNC_STAGES) = '0' and ps2_clk_last = '1' then
\r
196 ps2_transceiver_state_next <= RECEIVE_DATA7;
\r
198 when RECEIVE_DATA7 =>
\r
199 ps2_transceiver_state_next <= RECEIVE_WAIT_PARITY;
\r
200 when RECEIVE_WAIT_PARITY =>
\r
201 if ps2_clk_sync(SYNC_STAGES) = '0' and ps2_clk_last = '1' then
\r
202 ps2_transceiver_state_next <= RECEIVE_PARITY;
\r
204 when RECEIVE_PARITY =>
\r
205 ps2_transceiver_state_next <= RECEIVE_WAIT_STOP;
\r
206 when RECEIVE_WAIT_STOP =>
\r
207 if ps2_clk_sync(SYNC_STAGES) = '0' and ps2_clk_last = '1' then
\r
208 ps2_transceiver_state_next <= RECEIVE_STOP;
\r
210 when RECEIVE_STOP =>
\r
211 ps2_transceiver_state_next <= IDLE;
\r
215 process(ps2_transceiver_state, ps2_data_internal, ps2_clk_internal, parity, input_data, ps2_data_sync(SYNC_STAGES), output_data_internal, prepare_timeout1, prepare_timeout2, ps2_clk_hz, ps2_data_hz)
\r
217 input_data_send_ok <= '0';
\r
218 input_data_send_finished <= '0';
\r
219 ps2_data_next <= ps2_data_internal;
\r
220 ps2_data_hz_next <= ps2_data_hz;
\r
221 ps2_clk_next <= ps2_clk_internal;
\r
222 ps2_clk_hz_next <= ps2_clk_hz;
\r
223 parity_next <= parity;
\r
224 output_data_next <= output_data_internal;
\r
225 new_data_next <= '0';
\r
226 prepare_timeout1_next <= prepare_timeout1;
\r
227 prepare_timeout2_next <= prepare_timeout2;
\r
229 case ps2_transceiver_state is
\r
231 ps2_clk_next <= '1';
\r
232 ps2_clk_hz_next <= '1';
\r
233 ps2_data_next <= '1';
\r
234 ps2_data_hz_next <= '1';
\r
236 when PREPARE_SEND_ASSIGN_CLK =>
\r
237 ps2_clk_next <= '0';
\r
238 ps2_clk_hz_next <= '0';
\r
239 parity_next <= '1';
\r
240 prepare_timeout1_next <= 0;
\r
241 when PREPARE_SEND_WAIT1 =>
\r
242 prepare_timeout1_next <= prepare_timeout1 + 1;
\r
243 when PREPARE_SEND_DATA =>
\r
244 ps2_data_next <='0';
\r
245 ps2_data_hz_next <= '0';
\r
246 prepare_timeout2_next <= 0;
\r
247 when PREPARE_SEND_WAIT2 =>
\r
248 prepare_timeout2_next <= prepare_timeout2 + 1;
\r
249 when PREPARE_SEND_RELEASE_CLK =>
\r
250 ps2_clk_next <= '1';
\r
251 ps2_clk_hz_next <= '1';
\r
252 when SEND_WAIT_DATA0 =>
\r
255 ps2_data_next <= input_data(0);
\r
256 parity_next <= parity xor input_data(0);
\r
257 when SEND_WAIT_DATA1 =>
\r
260 ps2_data_next <=input_data(1);
\r
261 parity_next <= parity xor input_data(1);
\r
262 when SEND_WAIT_DATA2 =>
\r
265 ps2_data_next <=input_data(2);
\r
266 parity_next <= parity xor input_data(2);
\r
267 when SEND_WAIT_DATA3 =>
\r
270 ps2_data_next <=input_data(3);
\r
271 parity_next <= parity xor input_data(3);
\r
272 when SEND_WAIT_DATA4 =>
\r
275 ps2_data_next <=input_data(4);
\r
276 parity_next <= parity xor input_data(4);
\r
277 when SEND_WAIT_DATA5 =>
\r
280 ps2_data_next <=input_data(5);
\r
281 parity_next <= parity xor input_data(5);
\r
282 when SEND_WAIT_DATA6 =>
\r
285 ps2_data_next <=input_data(6);
\r
286 parity_next <= parity xor input_data(6);
\r
287 when SEND_WAIT_DATA7 =>
\r
290 ps2_data_next <=input_data(7);
\r
291 parity_next <= parity xor input_data(7);
\r
292 when SEND_WAIT_PARITY =>
\r
294 when SEND_PARITY =>
\r
295 ps2_data_next <= parity;
\r
296 when SEND_WAIT_STOP =>
\r
299 ps2_data_next <='1';
\r
300 ps2_data_hz_next <='1';
\r
301 when SEND_WAIT_ACK1 =>
\r
303 when SEND_WAIT_ACK2 =>
\r
305 when SEND_READ_ACK =>
\r
306 input_data_send_ok <= not ps2_data_sync(SYNC_STAGES);
\r
307 input_data_send_finished <= '1';
\r
308 when SEND_FINISH =>
\r
310 when RECEIVE_START =>
\r
312 when RECEIVE_WAIT_DATA0 =>
\r
314 when RECEIVE_DATA0 =>
\r
315 output_data_next <= ps2_data_sync(SYNC_STAGES) & output_data_internal(7 downto 1);
\r
316 when RECEIVE_WAIT_DATA1 =>
\r
318 when RECEIVE_DATA1 =>
\r
319 output_data_next <= ps2_data_sync(SYNC_STAGES) & output_data_internal(7 downto 1);
\r
320 when RECEIVE_WAIT_DATA2 =>
\r
322 when RECEIVE_DATA2 =>
\r
323 output_data_next <= ps2_data_sync(SYNC_STAGES) & output_data_internal(7 downto 1);
\r
324 when RECEIVE_WAIT_DATA3 =>
\r
326 when RECEIVE_DATA3 =>
\r
327 output_data_next <= ps2_data_sync(SYNC_STAGES) & output_data_internal(7 downto 1);
\r
328 when RECEIVE_WAIT_DATA4 =>
\r
330 when RECEIVE_DATA4 =>
\r
331 output_data_next <= ps2_data_sync(SYNC_STAGES) & output_data_internal(7 downto 1);
\r
332 when RECEIVE_WAIT_DATA5 =>
\r
334 when RECEIVE_DATA5 =>
\r
335 output_data_next <= ps2_data_sync(SYNC_STAGES) & output_data_internal(7 downto 1);
\r
336 when RECEIVE_WAIT_DATA6 =>
\r
338 when RECEIVE_DATA6 =>
\r
339 output_data_next <= ps2_data_sync(SYNC_STAGES) & output_data_internal(7 downto 1);
\r
340 when RECEIVE_WAIT_DATA7 =>
\r
342 when RECEIVE_DATA7 =>
\r
343 output_data_next <= ps2_data_sync(SYNC_STAGES) & output_data_internal(7 downto 1);
\r
344 when RECEIVE_WAIT_PARITY =>
\r
346 when RECEIVE_PARITY =>
\r
347 null; -- Currently igonring parity
\r
348 when RECEIVE_WAIT_STOP =>
\r
350 when RECEIVE_STOP =>
\r
351 new_data_next <= '1';
\r
355 process(sys_clk, sys_res_n)
\r
357 if sys_res_n = '0' then
\r
358 ps2_transceiver_state <= IDLE;
\r
359 ps2_clk_last <= '1';
\r
360 ps2_clk_internal <= '1';
\r
362 ps2_data_internal <= '1';
\r
363 ps2_data_hz <= '1';
\r
364 output_data_internal <= (others => '0');
\r
367 prepare_timeout1 <= 0;
\r
368 prepare_timeout2 <= 0;
\r
369 ps2_clk_sync <= (others => '1');
\r
370 ps2_data_sync <= (others => '1');
\r
371 elsif rising_edge(sys_clk) then
\r
372 ps2_transceiver_state <= ps2_transceiver_state_next;
\r
373 ps2_clk_last <= ps2_clk_sync(SYNC_STAGES);
\r
374 ps2_clk_internal <= ps2_clk_next;
\r
375 ps2_clk_hz <= ps2_clk_hz_next;
\r
376 ps2_data_internal <= ps2_data_next;
\r
377 ps2_data_hz <= ps2_data_hz_next;
\r
378 output_data_internal <= output_data_next;
\r
379 parity <= parity_next;
\r
380 new_data <= new_data_next;
\r
381 prepare_timeout1 <= prepare_timeout1_next;
\r
382 prepare_timeout2 <= prepare_timeout2_next;
\r
383 ps2_clk_sync(1) <= ps2_clk;
\r
384 ps2_data_sync(1) <= ps2_data;
\r
385 for i in 2 to SYNC_STAGES loop
\r
386 ps2_clk_sync(i) <= ps2_clk_sync(i - 1);
\r
387 ps2_data_sync(i) <= ps2_data_sync(i - 1);
\r
391 ps2_clk <= ps2_clk_internal when ps2_clk_hz = '0'
\r
393 ps2_data <= ps2_data_internal when ps2_data_hz = '0'
\r
395 output_data <= output_data_internal;
\r
396 end architecture beh;
\r