OpenCores
URL https://opencores.org/ocsvn/System09/System09/trunk

Subversion Repositories System09

[/] [System09/] [branches/] [mkfiles_rev1/] [rtl/] [VHDL/] [ps2_keyboard.vhd] - Blame information for rev 104

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 19 dilbert57
---------------------------------------------------------------------------------------
2
--
3
-- Author: John Clayton
4
-- Date  : April 30, 2001
5
-- Update: 4/30/01 copied this file from lcd_2.v (pared down).
6
-- Update: 5/24/01 changed the first module from "ps2_keyboard_receiver"
7
--                 to "ps2_keyboard_interface"
8
-- Update: 5/29/01 Added input synchronizing flip-flops.  Changed state
9
--                 encoding (m1) for good operation after part config.
10
-- Update: 5/31/01 Added low drive strength and slow transitions to ps2_clk
11
--                 and ps2_data in the constraints file.  Added the signal
12
--                 "tx_shifting_done" as distinguished from "rx_shifting_done."
13
--                 Debugged the transmitter portion in the lab.
14
-- Update: 6/01/01 Added horizontal tab to the ascii output.
15
-- Update: 6/01/01 Added parameter TRAP_SHIFT_KEYS.
16
-- Update: 6/05/01 Debugged the "debounce" timer functionality.
17
--                 Used 60usec timer as a "watchdog" timeout during
18
--                 receive from the keyboard.  This means that a keyboard
19
--                 can now be "hot plugged" into the interface, without
20
--                 messing up the bit_count, since the bit_count is reset
21
--                 to zero during periods of inactivity anyway.  This was
22
--                 difficult to debug.  I ended up using the logic analyzer,
23
--                 and had to scratch my head quite a bit.
24
-- Update: 6/06/01 Removed extra comments before the input synchronizing
25
--                 flip-flops.  Used the correct parameter to size the
26
--                 5usec_timer_count.  Changed the name of this file from
27
--                 ps2.v to ps2_keyboard.v
28
-- Update: 6/06/01 Removed "&& q[7:0]" in output_strobe logic.  Removed extra
29
--                 commented out "else" condition in the shift register and
30
--                 bit counter.
31
-- Update: 6/07/01 Changed default values for 60usec timer parameters so that
32
--                 they correspond to 60usec for a 49.152MHz clock.
33
--
34
--      Converted to VHDL: 10 February 2004 - John Kent
35
-- 11 Sept 04   added ctrl key 
36
--              changed undefined key codes to x"ff"
37
--              reversed clock polarity
38
--
39
-- 18th Oct 04  added ctrl keys to ASCII ROM
40
--              added CAPS Lock toggle.
41
--
42
-- 6th Feb 2007 Added Generic Clock parameter
43
--
44
---------------------------------------------------------------------------------------
45
-- Description:
46
---------------------------------------------------------------------------------------
47
-- This is a state-machine driven serial-to-parallel and parallel-to-serial
48
-- interface to the ps2 style keyboard interface.  The details of the operation
49
-- of the keyboard interface were obtained from the following website:
50
--
51
--   http:--www.beyondlogic.org/keyboard/keybrd.htm
52
--
53
-- Some aspects of the keyboard interface are not implemented (e.g, parity
54
-- checking for the receive side, and recognition of the various commands
55
-- which the keyboard sends out, such as "power on selt test passed," "Error"
56
-- and "Resend.")  However, if the user wishes to recognize these reply
57
-- messages, the scan code output can always be used to extend functionality
58
-- as desired.
59
--
60
-- Note that the "Extended" (0xE0) and "Released" (0xF0) codes are recognized.
61
-- The rx interface provides separate indicator flags for these two conditions
62
-- with every valid character scan code which it provides.  The shift keys are
63
-- also trapped by the interface, in order to provide correct uppercase ASCII
64
-- characters at the ascii output, although the scan codes for the shift keys
65
-- are still provided at the scan code output.  So, the left/right ALT keys
66
-- can be differentiated by the presence of the rx_entended signal, while the
67
-- left/right shift keys are differentiable by the different scan codes
68
-- received.
69
--
70
-- The interface to the ps2 keyboard uses ps2_clk clock rates of
71
-- 30-40 kHz, dependent upon the keyboard itself.  The rate at which the state
72
-- machine runs should be at least twice the rate of the ps2_clk, so that the
73
-- states can accurately follow the clock signal itself.  Four times 
74
-- oversampling is better.  Say 200kHz at least.  The upper limit for clocking
75
-- the state machine will undoubtedly be determined by delays in the logic 
76
-- which decodes the scan codes into ASCII equivalents.  The maximum speed
77
-- will be most likely many megahertz, depending upon target technology.
78
-- In order to run the state machine extremely fast, synchronizing flip-flops
79
-- have been added to the ps2_clk and ps2_data inputs of the state machine.
80
-- This avoids poor performance related to slow transitions of the inputs.
81
-- 
82
-- Because this is a bi-directional interface, while reading from the keyboard
83
-- the ps2_clk and ps2_data lines are used as inputs.  While writing to the
84
-- keyboard, however (which may be done at any time.  If writing interrupts a
85
-- read from the keyboard, the keyboard will buffer up its data, and send
86
-- it later) both the ps2_clk and ps2_data lines are occasionally pulled low,
87
-- and pullup resistors are used to bring the lines high again, by setting
88
-- the drivers to high impedance state.
89
--
90
-- The tx interface, for writing to the keyboard, does not provide any special
91
-- pre-processing.  It simply transmits the 8-bit command value to the
92
-- keyboard.
93
--
94
-- Pullups MUST BE USED on the ps2_clk and ps2_data lines for this design,
95
-- whether they be internal to an FPGA I/O pad, or externally placed.
96
-- If internal pullups are used, they may be fairly weak, causing bounces
97
-- due to crosstalk, etc.  There is a "debounce timer" implemented in order
98
-- to eliminate erroneous state transitions which would occur based on bounce.
99
-- 
100
-- Parameters are provided in order to configure and appropriately size the
101
-- counter of a 60 microsecond timer used in the transmitter, depending on
102
-- the clock frequency used.  The 60 microsecond period is guaranteed to be
103
-- more than one period of the ps2_clk_s signal.
104
--
105
-- Also, a smaller 5 microsecond timer has been included for "debounce".
106
-- This is used because, with internal pullups on the ps2_clk and ps2_data
107
-- lines, there is some bouncing around which occurs
108
--
109
-- A parameter TRAP_SHIFT_KEYS allows the user to eliminate shift keypresses
110
-- from producing scan codes (along with their "undefined" ASCII equivalents)
111
-- at the output of the interface.  If TRAP_SHIFT_KEYS is non-zero, the shift
112
-- key status will only be reported by rx_shift_key_on.  No ascii or scan
113
-- codes will be reported for the shift keys.  This is useful for those who
114
-- wish to use the ASCII data stream, and who don't want to have to "filter
115
-- out" the shift key codes.
116
--
117
--
118
---------------------------------------------------------------------------------------
119
 
120
library ieee;
121
   use ieee.std_logic_1164.all;
122
   use IEEE.STD_LOGIC_ARITH.ALL;
123
   use IEEE.STD_LOGIC_UNSIGNED.ALL;
124
   use ieee.numeric_std.all;
125
 
126
entity ps2_keyboard_interface is
127
  generic (
128
  Frequency_MHz   : integer
129
  );
130
 
131
  port(
132
  clk             : in    std_logic;
133
  reset           : in    std_logic;
134
  ps2_clk         : inout std_logic;
135
  ps2_data        : inout std_logic;
136
  rx_extended     : out   std_logic;
137
  rx_released     : out   std_logic;
138
  rx_shift_key_on : out   std_logic;
139
--  rx_scan_code    : out   std_logic_vector(7 downto 0);
140
  rx_ascii        : out   std_logic_vector(7 downto 0);
141
  rx_data_ready   : out   std_logic;       -- rx_read_o
142
  rx_read         : in    std_logic;       -- rx_read_ack_i
143
  tx_data         : in    std_logic_vector(7 downto 0);
144
  tx_write        : in    std_logic;
145
  tx_write_ack    : out   std_logic;
146
  tx_error_no_keyboard_ack      : out  std_logic
147
  );
148
end ps2_keyboard_interface;
149
 
150
-------------------------------------------------------------------------------
151
-- Architecture for ps2 keyboard interface
152
-------------------------------------------------------------------------------
153
architecture rtl of ps2_keyboard_interface is
154
  -----------------------------------------------------------------------------
155
 
156
 
157
constant TOTAL_BITS   : integer := 11;
158
constant EXTEND_CODE  : integer := 16#E0#;
159
constant RELEASE_CODE : integer := 16#F0#;
160
constant LEFT_SHIFT   : integer := 16#12#;
161
constant RIGHT_SHIFT  : integer := 16#59#;
162
constant CTRL_CODE    : integer := 16#14#;
163
constant CAPS_CODE    : integer := 16#58#;
164
 
165
 
166
-- constants
167
 
168
-- The timer value can be up to (2^bits) inclusive.
169
-- Values for 49.152 MHz clock
170
--constant TIMER_60USEC_VALUE_PP : integer := 2950; -- Number of sys_clks for 60usec.
171
--constant TIMER_60USEC_BITS_PP  : integer := 12;   -- Number of bits needed for timer
172
--constant TIMER_5USEC_VALUE_PP  : integer := 186;   -- Number of sys_clks for debounce
173
--constant TIMER_5USEC_BITS_PP   : integer := 8;     -- Number of bits needed for timer
174
 
175
-- Values for  12.5 MHz Clock
176
--constant TIMER_60USEC_VALUE_PP : integer := 750; -- Number of sys_clks for 60usec.
177
--constant TIMER_60USEC_BITS_PP  : integer := 10;  -- Number of bits needed for timer
178
--constant TIMER_5USEC_VALUE_PP  : integer := 62;  -- Number of sys_clks for debounce
179
--constant TIMER_5USEC_BITS_PP   : integer := 6;   -- Number of bits needed for timer
180
 
181
-- Values for  25 MHz Clock
182
--constant TIMER_60USEC_VALUE_PP : integer := 1500; -- Number of sys_clks for 60usec.
183
--constant TIMER_60USEC_BITS_PP  : integer := 11;   -- Number of bits needed for timer
184
--constant TIMER_5USEC_VALUE_PP  : integer := 125;  -- Number of sys_clks for debounce
185
--constant TIMER_5USEC_BITS_PP   : integer := 7;    -- Number of bits needed for timer
186
 
187
-- Values for  generic Clock up to 50 MHz
188
constant TIMER_60USEC_VALUE_PP : integer := Frequency_MHz * 60; -- Number of sys_clks for 60usec.
189
constant TIMER_60USEC_BITS_PP  : integer := 12;                 -- Number of bits needed for timer
190
constant TIMER_5USEC_VALUE_PP  : integer := Frequency_MHz * 5;  -- Number of sys_clks for debounce
191
constant TIMER_5USEC_BITS_PP   : integer := 8;                  -- Number of bits needed for timer
192
 
193
constant TRAP_SHIFT_KEYS_PP    : integer := 1;   -- Default: No shift key trap.
194
 
195
-- State encodings, provided as constants
196
-- for flexibility to the one instantiating the module.
197
-- In general, the default values need not be changed.
198
 
199
-- State "m1_rx_clk_l" has been chosen on purpose.  Since the input
200
-- synchronizing flip-flops initially contain zero, it takes one clk
201
-- for them to update to reflect the actual (idle = high) status of
202
-- the I/O lines from the keyboard.  Therefore, choosing 0 for m1_rx_clk_l
203
-- allows the state machine to transition to m1_rx_clk_h when the true
204
-- values of the input signals become present at the outputs of the
205
-- synchronizing flip-flops.  This initial transition is harmless, and it
206
-- eliminates the need for a "reset" pulse before the interface can operate.
207
 
208
type m1_type is ( m1_rx_clk_h, m1_rx_clk_l,
209
                  m1_tx_wait_clk_h, m1_tx_force_clk_l,
210
                                                m1_tx_clk_h, m1_tx_clk_l,
211
                                                m1_tx_wait_keyboard_ack, m1_tx_done_recovery,
212
                                                m1_tx_error_no_keyboard_ack, m1_tx_rising_edge_marker,
213
                                                m1_tx_first_wait_clk_h, m1_tx_first_wait_clk_l, m1_tx_reset_timer,
214
                  m1_rx_falling_edge_marker, m1_rx_rising_edge_marker );
215
 
216
-- Internal signal declarations
217
signal timer_60usec_done  : std_logic;
218
signal timer_5usec_done   : std_logic;
219
signal extended           : std_logic;
220
signal released           : std_logic;
221
signal shift_key_on       : std_logic;
222
signal ctrl_key_on        : std_logic;
223
signal caps_key_on        : std_logic;
224
 
225
                         -- NOTE: These two signals used to be one.  They
226
                         --       were split into two signals because of
227
                         --       shift key trapping.  With shift key
228
                         --       trapping, no event is generated externally,
229
                         --       but the "hold" data must still be cleared
230
                         --       anyway regardless, in preparation for the
231
                         --       next scan codes.
232
signal rx_output_event    : std_logic;    -- Used only to clear: hold_released, hold_extended
233
signal rx_output_strobe   : std_logic;   -- Used to produce the actual output.
234
 
235
signal tx_parity_bit      : std_logic;
236
signal rx_shifting_done   : std_logic;
237
signal tx_shifting_done   : std_logic;
238
signal shift_key_plus_code: std_logic_vector(8 downto 0);
239
 
240
signal q                  : std_logic_vector(TOTAL_BITS-1 downto 0);
241
signal m1_state           : m1_type;
242
signal m1_next_state      : m1_type;
243
signal bit_count          : std_logic_vector(3 downto 0);
244
signal enable_timer_60usec: std_logic;
245
signal enable_timer_5usec : std_logic;
246
signal timer_60usec_count : std_logic_vector(TIMER_60USEC_BITS_PP-1 downto 0);
247
signal timer_5usec_count  : std_logic_vector(TIMER_5USEC_BITS_PP-1 downto 0);
248
signal ascii              : std_logic_vector(7 downto 0);      -- "REG" type only because a case statement is used.
249
signal left_shift_key     : std_logic;
250
signal right_shift_key    : std_logic;
251
signal hold_extended      : std_logic;  -- Holds prior value, cleared at rx_output_strobe
252
signal hold_released      : std_logic;  -- Holds prior value, cleared at rx_output_strobe
253
signal ps2_clk_s          : std_logic;  -- Synchronous version of this input
254
signal ps2_data_s         : std_logic;  -- Synchronous version of this input
255
signal ps2_clk_hi_z       : std_logic;  -- Without keyboard, high Z equals 1 due to pullups.
256
signal ps2_data_hi_z      : std_logic;  -- Without keyboard, high Z equals 1 due to pullups.
257
signal tx_write_ack_o     : std_logic;
258
 
259
--
260
-- key lookup table
261
--
262
component keymap_rom
263
    Port (
264
       clk   : in  std_logic;
265
                 rst   : in  std_logic;
266
                 cs    : in  std_logic;
267
                 rw    : in  std_logic;
268
       addr  : in  std_logic_vector (8 downto 0);
269
       rdata : out std_logic_vector (7 downto 0);
270
       wdata : in  std_logic_vector (7 downto 0)
271
    );
272
end component;
273
 
274
begin
275
 
276
my_key_map : keymap_rom
277
     Port map (
278
          clk  => clk,
279
          rst  => reset,
280
          cs   => '1',
281
          rw   => '1',
282
          addr => shift_key_plus_code,
283
          rdata => ascii,
284
          wdata => "00000000"
285
          );
286
 
287
----------------------------------------------------------------------------
288
-- Module code
289
-- assign ps2_clk = ps2_clk_hi_z?1'bZ:1'b0;
290
-- assign ps2_data = ps2_data_hi_z?1'bZ:1'b0;
291
--
292
ps2_direction : process( ps2_clk_hi_z, ps2_data_hi_z )
293
begin
294
  if( ps2_clk_hi_z = '1' ) then
295
     ps2_clk <= 'Z';
296
  else
297
     ps2_clk <= '0';
298
  end if;
299
  if( ps2_data_hi_z = '1' ) then
300
     ps2_data <= 'Z';
301
  else
302
     ps2_data <= '0';
303
  end if;
304
end process;
305
 
306
-- Input "synchronizing" logic -- synchronizes the inputs to the state
307
-- machine clock, thus avoiding errors related to
308
-- spurious state machine transitions.
309
ps2_synch : process(clk, ps2_clk, ps2_data)
310
begin
311
  if clk'event and clk='0' then
312
    ps2_clk_s <= ps2_clk;
313
    ps2_data_s <= ps2_data;
314
  end if;
315
end process;
316
 
317
-- State register
318
m1_state_register : process( clk, reset, m1_state )
319
begin
320
  if clk'event and clk='0' then
321
    if (reset = '1') then
322
            m1_state <= m1_rx_clk_h;
323
    else
324
            m1_state <= m1_next_state;
325
    end if;
326
  end if;
327
end process;
328
 
329
m1_state_logic : process( m1_state, q,
330
                          tx_shifting_done, tx_write,
331
                                                                  ps2_clk_s, ps2_data_s,
332
                                                                  timer_60usec_done, timer_5usec_done )
333
begin
334
  -- Output signals default to this value, unless changed in a state condition.
335
  ps2_clk_hi_z             <= '1';
336
  ps2_data_hi_z            <= '1';
337
  tx_error_no_keyboard_ack <= '0';
338
  enable_timer_60usec      <= '0';
339
  enable_timer_5usec       <= '0';
340
 
341
  case (m1_state) is
342
  when m1_rx_clk_h =>
343
        enable_timer_60usec <= '1';
344
        if (tx_write = '1') then
345
                      m1_next_state <= m1_tx_reset_timer;
346
        elsif (ps2_clk_s = '0') then
347
                      m1_next_state <= m1_rx_falling_edge_marker;
348
        else
349
                      m1_next_state <= m1_rx_clk_h;
350
        end if;
351
 
352
  when m1_rx_falling_edge_marker =>
353
        enable_timer_60usec <= '0';
354
        m1_next_state <= m1_rx_clk_l;
355
 
356
  when m1_rx_clk_l =>
357
        enable_timer_60usec <= '1';
358
        if (tx_write = '1') then
359
                     m1_next_state <= m1_tx_reset_timer;
360
        elsif (ps2_clk_s = '1') then
361
                     m1_next_state <= m1_rx_rising_edge_marker;
362
        else
363
                     m1_next_state <= m1_rx_clk_l;
364
        end if;
365
 
366
  when m1_rx_rising_edge_marker =>
367
        enable_timer_60usec <= '0';
368
        m1_next_state <= m1_rx_clk_h;
369
 
370
  when m1_tx_reset_timer =>
371
        enable_timer_60usec <= '0';
372
        m1_next_state <= m1_tx_force_clk_l;
373
 
374
  when m1_tx_force_clk_l =>
375
        enable_timer_60usec <= '1';
376
        ps2_clk_hi_z <= '0';  -- Force the ps2_clk line low.
377
        if (timer_60usec_done = '1') then
378
                     m1_next_state <= m1_tx_first_wait_clk_h;
379
        else
380
                     m1_next_state <= m1_tx_force_clk_l;
381
        end     if;
382
 
383
  when m1_tx_first_wait_clk_h =>
384
        enable_timer_5usec <= '1';
385
        ps2_data_hi_z <= '0';        -- Start bit.
386
        if (ps2_clk_s = '0') and (timer_5usec_done = '1') then
387
          m1_next_state <= m1_tx_clk_l;
388
        else
389
          m1_next_state <= m1_tx_first_wait_clk_h;
390
        end     if;
391
 
392
    -- This state must be included because the device might possibly
393
    -- delay for up to 10 milliseconds before beginning its clock pulses.
394
    -- During that waiting time, we cannot drive the data (q[0]) because it
395
    -- is possibly 1, which would cause the keyboard to abort its receive
396
    -- and the expected clocks would then never be generated.
397
  when m1_tx_first_wait_clk_l =>
398
        ps2_data_hi_z <= '0';
399
        if (ps2_clk_s = '0') then
400
                     m1_next_state <= m1_tx_clk_l;
401
        else
402
                     m1_next_state <= m1_tx_first_wait_clk_l;
403
        end     if;
404
 
405
  when m1_tx_wait_clk_h =>
406
        enable_timer_5usec <= '1';
407
        ps2_data_hi_z <= q(0);
408
        if (ps2_clk_s = '1') and (timer_5usec_done = '1') then
409
          m1_next_state <= m1_tx_rising_edge_marker;
410
        else
411
          m1_next_state <= m1_tx_wait_clk_h;
412
        end     if;
413
 
414
  when m1_tx_rising_edge_marker =>
415
        ps2_data_hi_z <= q(0);
416
        m1_next_state <= m1_tx_clk_h;
417
 
418
  when m1_tx_clk_h =>
419
        ps2_data_hi_z <= q(0);
420
        if (tx_shifting_done = '1') then
421
                     m1_next_state <= m1_tx_wait_keyboard_ack;
422
        elsif (ps2_clk_s = '0') then
423
                     m1_next_state <= m1_tx_clk_l;
424
        else
425
                     m1_next_state <= m1_tx_clk_h;
426
        end     if;
427
 
428
  when m1_tx_clk_l =>
429
        ps2_data_hi_z <= q(0);
430
        if (ps2_clk_s = '1') then
431
                     m1_next_state <= m1_tx_wait_clk_h;
432
        else
433
                     m1_next_state <= m1_tx_clk_l;
434
        end     if;
435
 
436
  when m1_tx_wait_keyboard_ack =>
437
        if (ps2_clk_s = '0') and (ps2_data_s = '1') then
438
           m1_next_state <= m1_tx_error_no_keyboard_ack;
439
        elsif (ps2_clk_s = '0') and (ps2_data_s = '0') then
440
           m1_next_state <= m1_tx_done_recovery;
441
        else
442
                     m1_next_state <= m1_tx_wait_keyboard_ack;
443
        end     if;
444
 
445
  when m1_tx_done_recovery =>
446
        if (ps2_clk_s = '1') and (ps2_data_s = '1') then
447
                     m1_next_state <= m1_rx_clk_h;
448
        else
449
                     m1_next_state <= m1_tx_done_recovery;
450
        end     if;
451
 
452
  when m1_tx_error_no_keyboard_ack =>
453
        tx_error_no_keyboard_ack <= '1';
454
        if (ps2_clk_s = '1') and (ps2_data_s ='1') then
455
                     m1_next_state <= m1_rx_clk_h;
456
        else
457
                     m1_next_state <= m1_tx_error_no_keyboard_ack;
458
        end     if;
459
 
460
  when others =>
461
             m1_next_state <= m1_rx_clk_h;
462
  end case;
463
end process;
464
 
465
-- This is the bit counter
466
bit_counter: process(clk, reset, m1_state, bit_count )
467
begin
468
  if clk'event and clk = '0' then
469
    if ( reset = '1' ) or
470
       ( rx_shifting_done = '1' ) or
471
       (m1_state = m1_tx_wait_keyboard_ack) then       -- After tx is done.
472
       bit_count <= "0000";  -- normal reset
473
    elsif (timer_60usec_done = '1' ) and
474
          (m1_state = m1_rx_clk_h)      and
475
          (ps2_clk_s = '1') then
476
       bit_count <= "0000";  -- rx watchdog timer reset
477
    elsif (m1_state = m1_rx_falling_edge_marker) or  -- increment for rx
478
          (m1_state = m1_tx_rising_edge_marker) then  -- increment for tx
479
       bit_count <= bit_count + 1;
480
    end if;
481
  end if;
482
end process;
483
 
484
assign: process( bit_count, tx_write, tx_write_ack_o, m1_state )
485
begin
486
  if (bit_count = TOTAL_BITS) then
487
     rx_shifting_done <= '1';
488
  else
489
     rx_shifting_done <= '0';
490
  end if;
491
 
492
  if (bit_count = (TOTAL_BITS-1)) then
493
     tx_shifting_done <= '1';
494
  else
495
     tx_shifting_done <= '0';
496
  end if;
497
 
498
-- This is the signal which enables loading of the shift register.
499
-- It also indicates "ack" to the device writing to the transmitter.
500
  if ((tx_write = '1') and (m1_state = m1_rx_clk_h)) or
501
     ((tx_write = '1') and (m1_state = m1_rx_clk_l)) then
502
     tx_write_ack_o <= '1';
503
  else
504
     tx_write_ack_o <= '0';
505
  end if;
506
  tx_write_ack <= tx_write_ack_o;
507
end process;
508
 
509
-- This is the ODD parity bit for the transmitted word.
510
-- assign tx_parity_bit = ~^tx_data;
511
--
512
tx_parity_bit <= not( tx_data(7) xor tx_data(6) xor tx_data(5) xor tx_data(4) xor
513
                      tx_data(3) xor tx_data(2) xor tx_data(1) xor tx_data(0) );
514
 
515
-- This is the shift register
516
q_shift : process(clk, tx_write_ack_o, tx_parity_bit, tx_data,
517
                  m1_state, q, ps2_data_s, rx_shifting_done )
518
begin
519
  if clk'event and clk='0' then
520
    if (reset = '1') then
521
            q <= "00000000000";
522
    elsif (tx_write_ack_o = '1') then
523
            q <= "1" & tx_parity_bit & tx_data & "0";
524
    elsif ( (m1_state = m1_rx_falling_edge_marker)      or
525
            (m1_state = m1_tx_rising_edge_marker) ) then
526
       q <= ps2_data_s & q((TOTAL_BITS-1) downto 1);
527
    end if;
528
  end if;
529
 
530
-- Create the signals which indicate special scan codes received.
531
-- These are the "unlatched versions."
532
  if (q(8 downto 1) = EXTEND_CODE) and (rx_shifting_done = '1') then
533
    extended <= '1';
534
  else
535
    extended <= '0';
536
  end if;
537
  if (q(8 downto 1) = RELEASE_CODE) and (rx_shifting_done = '1') then
538
    released <= '1';
539
  else
540
    released <= '0';
541
  end if;
542
end process;
543
 
544
-- This is the 60usec timer counter
545
timer60usec: process(clk, enable_timer_60usec, timer_60usec_count)
546
begin
547
  if clk'event and clk = '0' then
548
    if (enable_timer_60usec = '0') then
549
            timer_60usec_count <= (others => '0');
550
    elsif (timer_60usec_done = '0') then
551
            timer_60usec_count <= timer_60usec_count + 1;
552
    end if;
553
  end if;
554
 
555
  if (timer_60usec_count = (TIMER_60USEC_VALUE_PP - 1)) then
556
         timer_60usec_done <= '1';
557
  else
558
    timer_60usec_done <= '0';
559
  end if;
560
end process;
561
 
562
-- This is the 5usec timer counter
563
timer5usec : process(clk, enable_timer_5usec, timer_5usec_count )
564
begin
565
  if clk'event and clk = '0' then
566
    if (enable_timer_5usec = '0') then
567
           timer_5usec_count <= (others => '0');
568
    elsif (timer_5usec_done = '0') then
569
           timer_5usec_count <= timer_5usec_count + 1;
570
    end if;
571
  end if;
572
 
573
  if( timer_5usec_count = (TIMER_5USEC_VALUE_PP - 1)) then
574
         timer_5usec_done <= '1';
575
  else
576
         timer_5usec_done <= '0';
577
  end if;
578
end process;
579
 
580
 
581
-- Store the special scan code status bits
582
-- Not the final output, but an intermediate storage place,
583
-- until the entire set of output data can be assembled.
584
special_scan : process(clk, reset, rx_output_event, rx_shifting_done, extended, released )
585
begin
586
  if clk'event and clk='0' then
587
    if (reset = '1') or (rx_output_event = '1') then
588
      hold_extended <= '0';
589
      hold_released <= '0';
590
    else
591
      if (rx_shifting_done = '1') and (extended = '1') then
592
             hold_extended <= '1';
593
      end if;
594
      if (rx_shifting_done = '1') and (released = '1') then
595
             hold_released <= '1';
596
      end if;
597
    end if;
598
  end if;
599
end process;
600
 
601
 
602
-- These bits contain the status of the two shift keys
603
left_shift_proc : process(clk, reset, q, rx_shifting_done, hold_released )
604
begin
605
  if clk'event and clk = '0' then
606
    if (reset = '1') then
607
           left_shift_key <= '0';
608
    elsif (q(8 downto 1) = LEFT_SHIFT) and
609
               (rx_shifting_done = '1') and
610
                         (hold_released = '0') then
611
      left_shift_key <= '1';
612
    elsif (q(8 downto 1) = LEFT_SHIFT) and
613
               (rx_shifting_done = '1') and
614
                         (hold_released = '1') then
615
      left_shift_key <= '0';
616
    end if;
617
  end if;
618
end process;
619
 
620
right_shift_proc : process(clk, reset, q, rx_shifting_done, hold_released )
621
begin
622
  if clk'event and clk = '0' then
623
    if (reset = '1') then
624
           right_shift_key <= '0';
625
    elsif (q(8 downto 1) = RIGHT_SHIFT) and
626
               (rx_shifting_done = '1') and
627
                         (hold_released = '0') then
628
      right_shift_key <= '1';
629
    elsif (q(8 downto 1) = RIGHT_SHIFT) and
630
               (rx_shifting_done = '1') and
631
                         (hold_released = '1') then
632
      right_shift_key <= '0';
633
    end if;
634
  end if;
635
end process;
636
 
637
shift_key_on <= left_shift_key or right_shift_key;
638
rx_shift_key_on <= shift_key_on;
639
 
640
--
641
-- Control keys
642
--
643
ctrl_proc : process(clk, reset, q, rx_shifting_done, hold_released )
644
begin
645
  if clk'event and clk = '0' then
646
    if (reset = '1') then
647
           ctrl_key_on <= '0';
648
    elsif (q(8 downto 1) = CTRL_CODE) and
649
               (rx_shifting_done = '1') and
650
                         (hold_released = '0') then
651
      ctrl_key_on <= '1';
652
    elsif (q(8 downto 1) = CTRL_CODE) and
653
               (rx_shifting_done = '1') and
654
                         (hold_released = '1') then
655
      ctrl_key_on <= '0';
656
    end if;
657
  end if;
658
end process;
659
 
660
--
661
-- Caps lock
662
--
663
caps_proc : process(clk, reset, q, rx_shifting_done, hold_released, caps_key_on )
664
begin
665
  if clk'event and clk = '0' then
666
    if (reset = '1') then
667
           caps_key_on <= '0';
668
    elsif (q(8 downto 1) = CAPS_CODE) and
669
               (rx_shifting_done = '1') and
670
                         (hold_released = '0') then
671
      caps_key_on <= not caps_key_on;
672
    end if;
673
  end if;
674
end process;
675
 
676
-- Output the special scan code flags, the scan code and the ascii
677
special_scan_proc : process(clk, reset,
678
                                                                         hold_extended, hold_released,
679
                                                                         q, ascii, ctrl_key_on )
680
begin
681
  if clk'event and clk = '0' then
682
    if (reset = '1')    then
683
      rx_extended <= '0';
684
      rx_released <= '0';
685
--      rx_scan_code <= "00000000";
686
      rx_ascii <= "00000000";
687
    elsif (rx_output_strobe = '1') then
688
      rx_extended <= hold_extended;
689
      rx_released <= hold_released;
690
--      rx_scan_code <= q(8 downto 1);
691
    elsif ctrl_key_on = '1' then
692
           rx_ascii <= ascii and x"1f";
693
    else
694
      rx_ascii <= ascii;
695
    end if;
696
  end if;
697
end process;
698
 
699
-- Store the final rx output data only when all extend and release codes
700
-- are received and the next (actual key) scan code is also ready.
701
-- (the presence of rx_extended or rx_released refers to the
702
-- the current latest scan code received, not the previously latched flags.)
703
 
704
rx_output_proc : process( clk, reset,
705
                          rx_shifting_done, rx_output_strobe,
706
                          extended, released,
707
                                                                  q, ascii, rx_read )
708
begin
709
  if (rx_shifting_done = '1') and (extended = '0') and (released = '0') then
710
    rx_output_event <= '1';
711
  else
712
    rx_output_event <= '0';
713
  end if;
714
 
715
  if clk'event and clk = '0' then
716
    if reset = '1' then
717
           rx_output_strobe <= '0';
718
    elsif (rx_shifting_done = '1') and
719
          (rx_output_strobe = '0') and
720
               (extended = '0') and
721
                         (released = '0') and
722
                         (hold_released = '0' ) and
723
          (ascii /= x"00" ) then
724
--        ((TRAP_SHIFT_KEYS_PP = 0) or
725
--          ( (q(8 downto 1) /= RIGHT_SHIFT) and 
726
--                 (q(8 downto 1) /= LEFT_SHIFT) and
727
--                      (q(8 downto 1) /= CTRL_CODE) ) )then
728
      rx_output_strobe <= '1';
729
    elsif rx_read = '1' then
730
      rx_output_strobe <= '0';
731
    end if;
732
  end if;
733
  rx_data_ready <= rx_output_strobe;
734
end process;
735
 
736
 
737
-- This part translates the scan code into an ASCII value...
738
-- Only the ASCII codes which I considered important have been included.
739
-- if you want more, just add the appropriate case statement lines...
740
-- (You will need to know the keyboard scan codes you wish to assign.)
741
-- The entries are listed in ascending order of ASCII value.
742
shift_key_plus_code <= shift_key_on & caps_key_on & q(7 downto 1);
743
 
744
--shift_map : process( shift_key_plus_code )
745
--begin
746
--  case shift_key_plus_code is
747
--  when x"066" => ascii <= x"08";  -- Backspace ("backspace" key)
748
--  when x"166" => ascii <= x"08";  -- Backspace ("backspace" key)
749
--  when x"00d" => ascii <= x"09";  -- Horizontal Tab
750
--  when x"10d" => ascii <= x"09";  -- Horizontal Tab
751
--  when x"05a" => ascii <= x"0d";  -- Carriage return ("enter" key)
752
--  when x"15a" => ascii <= x"0d";  -- Carriage return ("enter" key)
753
--  when x"076" => ascii <= x"1b";  -- Escape ("esc" key)
754
--  when x"176" => ascii <= x"1b";  -- Escape ("esc" key)
755
--  when x"029" => ascii <= x"20";  -- Space
756
--  when x"129" => ascii <= x"20";  -- Space
757
--  when x"116" => ascii <= x"21";  -- !
758
--  when x"152" => ascii <= x"22";  -- "
759
--  when x"126" => ascii <= x"23";  -- #
760
--  when x"125" => ascii <= x"24";  -- $
761
--  when x"12e" => ascii <= x"25";  --
762
--  when x"13d" => ascii <= x"26";  --
763
--  when x"052" => ascii <= x"27";  --
764
--  when x"146" => ascii <= x"28";  --
765
--  when x"145" => ascii <= x"29";  --
766
--  when x"13e" => ascii <= x"2a";  -- *
767
--  when x"155" => ascii <= x"2b";  -- +
768
--  when x"041" => ascii <= x"2c";  -- ,
769
--  when x"04e" => ascii <= x"2d";  -- -
770
--  when x"049" => ascii <= x"2e";  -- .
771
--  when x"04a" => ascii <= x"2f";  -- /
772
--  when x"045" => ascii <= x"30";  -- 0
773
--  when x"016" => ascii <= x"31";  -- 1
774
--  when x"01e" => ascii <= x"32";  -- 2
775
--  when x"026" => ascii <= x"33";  -- 3
776
--  when x"025" => ascii <= x"34";  -- 4
777
--  when x"02e" => ascii <= x"35";  -- 5
778
--  when x"036" => ascii <= x"36";  -- 6
779
--  when x"03d" => ascii <= x"37";  -- 7
780
--  when x"03e" => ascii <= x"38";  -- 8
781
--  when x"046" => ascii <= x"39";  -- 9
782
--  when x"14c" => ascii <= x"3a";  -- :
783
--  when x"04c" => ascii <= x"3b";  -- ;
784
--  when x"141" => ascii <= x"3c";  -- <
785
--  when x"055" => ascii <= x"3d";  -- =
786
--  when x"149" => ascii <= x"3e";  -- >
787
--  when x"14a" => ascii <= x"3f";  -- ?
788
--  when x"11e" => ascii <= x"40";  -- @
789
--  when x"11c" => ascii <= x"41";  -- A
790
--  when x"132" => ascii <= x"42";  -- B
791
--  when x"121" => ascii <= x"43";  -- C
792
--  when x"123" => ascii <= x"44";  -- D
793
--  when x"124" => ascii <= x"45";  -- E
794
--  when x"12b" => ascii <= x"46";  -- F
795
--  when x"134" => ascii <= x"47";  -- G
796
--  when x"133" => ascii <= x"48";  -- H
797
--  when x"143" => ascii <= x"49";  -- I
798
--  when x"13b" => ascii <= x"4a";  -- J
799
--  when x"142" => ascii <= x"4b";  -- K
800
--  when x"14b" => ascii <= x"4c";  -- L
801
--  when x"13a" => ascii <= x"4d";  -- M
802
--  when x"131" => ascii <= x"4e";  -- N
803
--  when x"144" => ascii <= x"4f";  -- O
804
--  when x"14d" => ascii <= x"50";  -- P
805
--  when x"115" => ascii <= x"51";  -- Q
806
--  when x"12d" => ascii <= x"52";  -- R
807
--  when x"11b" => ascii <= x"53";  -- S
808
--  when x"12c" => ascii <= x"54";  -- T
809
--  when x"13c" => ascii <= x"55";  -- U
810
--  when x"12a" => ascii <= x"56";  -- V
811
--  when x"11d" => ascii <= x"57";  -- W
812
--  when x"122" => ascii <= x"58";  -- X
813
--  when x"135" => ascii <= x"59";  -- Y
814
--  when x"11a" => ascii <= x"5a";  -- Z
815
--  when x"054" => ascii <= x"5b";  -- [
816
--  when x"05d" => ascii <= x"5c";  -- \
817
--  when x"05b" => ascii <= x"5d";  -- ]
818
--  when x"136" => ascii <= x"5e";  -- ^
819
--  when x"14e" => ascii <= x"5f";  -- _    
820
--  when x"00e" => ascii <= x"60";  -- `
821
--  when x"01c" => ascii <= x"61";  -- a
822
--  when x"032" => ascii <= x"62";  -- b
823
--  when x"021" => ascii <= x"63";  -- c
824
--  when x"023" => ascii <= x"64";  -- d
825
--  when x"024" => ascii <= x"65";  -- e
826
--  when x"02b" => ascii <= x"66";  -- f
827
--  when x"034" => ascii <= x"67";  -- g
828
--  when x"033" => ascii <= x"68";  -- h
829
--  when x"043" => ascii <= x"69";  -- i
830
--  when x"03b" => ascii <= x"6a";  -- j
831
--  when x"042" => ascii <= x"6b";  -- k
832
--  when x"04b" => ascii <= x"6c";  -- l
833
--  when x"03a" => ascii <= x"6d";  -- m
834
--  when x"031" => ascii <= x"6e";  -- n
835
--  when x"044" => ascii <= x"6f";  -- o
836
--  when x"04d" => ascii <= x"70";  -- p
837
--  when x"015" => ascii <= x"71";  -- q
838
--  when x"02d" => ascii <= x"72";  -- r
839
--  when x"01b" => ascii <= x"73";  -- s
840
--  when x"02c" => ascii <= x"74";  -- t
841
--  when x"03c" => ascii <= x"75";  -- u
842
--  when x"02a" => ascii <= x"76";  -- v
843
--  when x"01d" => ascii <= x"77";  -- w
844
--  when x"022" => ascii <= x"78";  -- x
845
--  when x"035" => ascii <= x"79";  -- y
846
--  when x"01a" => ascii <= x"7a";  -- z
847
--  when x"154" => ascii <= x"7b";  -- {
848
--  when x"15d" => ascii <= x"7c";  -- |
849
--  when x"15b" => ascii <= x"7d";  -- }
850
--  when x"10e" => ascii <= x"7e";  -- ~
851
--  when x"071" => ascii <= x"7f";  -- (Delete OR DEL on numeric keypad)
852
--  when x"171" => ascii <= x"7f";  -- (Delete OR DEL on numeric keypad)
853
--  when others => ascii <= x"ff";  -- 0xff used for unlisted characters.
854
--  end case;
855
--end process;
856
 
857
end rtl;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.