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

Subversion Repositories zx_ula

[/] [zx_ula/] [branches/] [xilinx/] [spectrum_48k_for_digilent_spartan3_starter_kit_with_ps2_keyboard/] [ps2controller.v] - Blame information for rev 10

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 10 mcleod_ide
//-------------------------------------------------------------------------------------
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
//
35
//
36
//
37
//
38
// Description
39
//-------------------------------------------------------------------------------------
40
// This is a state-machine driven serial-to-parallel and parallel-to-serial
41
// interface to the ps2 style keyboard interface.  The details of the operation
42
// of the keyboard interface were obtained from the following website:
43
//
44
//   http://www.beyondlogic.org/keyboard/keybrd.htm
45
//
46
// Some aspects of the keyboard interface are not implemented (e.g, parity
47
// checking for the receive side, and recognition of the various commands
48
// which the keyboard sends out, such as "power on selt test passed," "Error"
49
// and "Resend.")  However, if the user wishes to recognize these reply
50
// messages, the scan code output can always be used to extend functionality
51
// as desired.
52
//
53
// Note that the "Extended" (0xE0) and "Released" (0xF0) codes are recognized.
54
// The rx interface provides separate indicator flags for these two conditions
55
// with every valid character scan code which it provides.  The shift keys are
56
// also trapped by the interface, in order to provide correct uppercase ASCII
57
// characters at the ascii output, although the scan codes for the shift keys
58
// are still provided at the scan code output.  So, the left/right ALT keys
59
// can be differentiated by the presence of the rx_entended signal, while the
60
// left/right shift keys are differentiable by the different scan codes
61
// received.
62
//
63
// The interface to the ps2 keyboard uses ps2_clk clock rates of
64
// 30-40 kHz, dependent upon the keyboard itself.  The rate at which the state
65
// machine runs should be at least twice the rate of the ps2_clk, so that the
66
// states can accurately follow the clock signal itself.  Four times 
67
// oversampling is better.  Say 200kHz at least.  The upper limit for clocking
68
// the state machine will undoubtedly be determined by delays in the logic 
69
// which decodes the scan codes into ASCII equivalents.  The maximum speed
70
// will be most likely many megahertz, depending upon target technology.
71
// In order to run the state machine extremely fast, synchronizing flip-flops
72
// have been added to the ps2_clk and ps2_data inputs of the state machine.
73
// This avoids poor performance related to slow transitions of the inputs.
74
// 
75
// Because this is a bi-directional interface, while reading from the keyboard
76
// the ps2_clk and ps2_data lines are used as inputs.  While writing to the
77
// keyboard, however (which may be done at any time.  If writing interrupts a
78
// read from the keyboard, the keyboard will buffer up its data, and send
79
// it later) both the ps2_clk and ps2_data lines are occasionally pulled low,
80
// and pullup resistors are used to bring the lines high again, by setting
81
// the drivers to high impedance state.
82
//
83
// The tx interface, for writing to the keyboard, does not provide any special
84
// pre-processing.  It simply transmits the 8-bit command value to the
85
// keyboard.
86
//
87
// Pullups MUST BE USED on the ps2_clk and ps2_data lines for this design,
88
// whether they be internal to an FPGA I/O pad, or externally placed.
89
// If internal pullups are used, they may be fairly weak, causing bounces
90
// due to crosstalk, etc.  There is a "debounce timer" implemented in order
91
// to eliminate erroneous state transitions which would occur based on bounce.
92
// 
93
// Parameters are provided in order to configure and appropriately size the
94
// counter of a 60 microsecond timer used in the transmitter, depending on
95
// the clock frequency used.  The 60 microsecond period is guaranteed to be
96
// more than one period of the ps2_clk_s signal.
97
//
98
// Also, a smaller 5 microsecond timer has been included for "debounce".
99
// This is used because, with internal pullups on the ps2_clk and ps2_data
100
// lines, there is some bouncing around which occurs
101
//
102
// A parameter TRAP_SHIFT_KEYS allows the user to eliminate shift keypresses
103
// from producing scan codes (along with their "undefined" ASCII equivalents)
104
// at the output of the interface.  If TRAP_SHIFT_KEYS is non-zero, the shift
105
// key status will only be reported by rx_shift_key_on.  No ascii or scan
106
// codes will be reported for the shift keys.  This is useful for those who
107
// wish to use the ASCII data stream, and who don't want to have to "filter
108
// out" the shift key codes.
109
//
110
//-------------------------------------------------------------------------------------
111
`resetall
112
`timescale 1ns/100ps
113
 
114
`define TOTAL_BITS   11          //total data bits of the data package
115
`define EXTEND_CODE  8'hE0      //extend code
116
`define RELEASE_CODE 8'hF0      //release code
117
 
118
module ps2_keyboard(
119
  clk,
120
  reset,
121
  ps2_clk,
122
  ps2_data,
123
  interrupt,
124
  rx_scan_code
125
  );
126
 
127
// Parameters
128
 
129
// The timer value can be up to (2^bits) inclusive.
130
parameter TIMER_60USEC_VALUE_PP = 840; // Number of sys_clks for 60usec. (for a 14Mhz clock)
131
parameter TIMER_60USEC_BITS_PP  = 10;   // Number of bits needed for timer
132
 
133
// State encodings, provided as parameters
134
// for flexibility to the one instantiating the module.
135
// In general, the default values need not be changed.
136
 
137
// State "m1_rx_clk_l" has been chosen on purpose.  Since the input
138
// synchronizing flip-flops initially contain zero, it takes one clk
139
// for them to update to reflect the actual (idle = high) status of
140
// the I/O lines from the keyboard.  Therefore, choosing 0 for m1_rx_clk_l
141
// allows the state machine to transition to m1_rx_clk_h when the true
142
// values of the input signals become present at the outputs of the
143
// synchronizing flip-flops.  This initial transition is harmless, and it
144
// eliminates the need for a "reset" pulse before the interface can operate.
145
 
146
parameter m1_rx_clk_h = 1;
147
parameter m1_rx_clk_l = 0;
148
parameter m1_rx_falling_edge_marker = 3;
149
parameter m1_rx_rising_edge_marker = 4;
150
 
151
 
152
// I/O declarations
153
input clk;
154
input reset;
155
input ps2_clk;
156
input ps2_data;
157
output interrupt;
158
output [7:0] rx_scan_code;
159
//output [7:0] rx_ascii;
160
 
161
reg rx_extended;
162
reg rx_released;
163
reg [7:0] rx_scan_code;
164
reg interrupt;
165
 
166
 
167
 
168
// Internal signal declarations
169
wire timer_60usec_done;
170
wire extended;
171
wire released;
172
                         // NOTE: These two signals used to be one.  They
173
                         //       were split into two signals because of
174
                         //       shift key trapping.  With shift key
175
                         //       trapping, no event is generated externally,
176
                         //       but the "hold" data must still be cleared
177
                         //       anyway regardless, in preparation for the
178
                         //       next scan codes.
179
wire rx_output_strobe;   // Used to produce the actual output.
180
wire rx_shifting_done;
181
 
182
 
183
reg [`TOTAL_BITS-1:0] q;
184
reg [3:0] m1_state;
185
reg [3:0] m1_next_state;
186
reg [3:0] bit_count;
187
 
188
reg enable_timer_60usec;
189
reg [TIMER_60USEC_BITS_PP-1:0] timer_60usec_count;
190
 
191
 
192
reg ps2_clk_s;        // Synchronous version of this input
193
reg ps2_data_s;       // Synchronous version of this input
194
 
195
 
196
//--------------------------------------------------------------------------
197
// Module code
198
 
199
// Input "synchronizing" logic -- synchronizes the inputs to the state
200
// machine clock, thus avoiding errors related to
201
// spurious state machine transitions.
202
always @(posedge clk)
203
begin
204
  ps2_clk_s <= ps2_clk;
205
  ps2_data_s <= ps2_data;
206
end
207
 
208
// State register
209
always @(posedge clk)
210
begin : m1_state_register
211
  if (reset) m1_state <= m1_rx_clk_h;
212
  else m1_state <= m1_next_state;
213
end
214
 
215
// State transition logic
216
always @(m1_state
217
         or q
218
         or ps2_clk_s
219
         or ps2_data_s
220
         or timer_60usec_done
221
         )
222
begin : m1_state_logic
223
 
224
  // Output signals default to this value, unless changed in a state condition.
225
 
226
  enable_timer_60usec <= 0;
227
 
228
  case (m1_state)
229
 
230
    m1_rx_clk_h :
231
      begin
232
        enable_timer_60usec <= 1;
233
                  if (~ps2_clk_s) m1_next_state <= m1_rx_falling_edge_marker;
234
        else m1_next_state <= m1_rx_clk_h;
235
      end
236
 
237
    m1_rx_falling_edge_marker :
238
      begin
239
        enable_timer_60usec <= 0;
240
        m1_next_state <= m1_rx_clk_l;
241
      end
242
 
243
    m1_rx_rising_edge_marker :
244
      begin
245
        enable_timer_60usec <= 0;
246
        m1_next_state <= m1_rx_clk_h;
247
      end
248
 
249
    m1_rx_clk_l :
250
      begin
251
        enable_timer_60usec <= 1;
252
                  if (ps2_clk_s) m1_next_state <= m1_rx_rising_edge_marker;
253
        else m1_next_state <= m1_rx_clk_l;
254
      end
255
    default : m1_next_state <= m1_rx_clk_h;
256
  endcase
257
end
258
 
259
 
260
// This is the bit counter
261
 
262
always @(posedge clk)
263
begin
264
  if ( reset
265
        || rx_shifting_done
266
      )
267
                bit_count <= 0;  // normal reset
268
  else if (timer_60usec_done
269
           && (m1_state == m1_rx_clk_h)
270
           && (ps2_clk_s)
271
      )
272
                bit_count <= 0;  // rx watchdog timer reset
273
  else if ( (m1_state == m1_rx_falling_edge_marker)   // increment for rx
274
           )
275
    bit_count <= bit_count + 1;
276
end
277
// This signal is high for one clock at the end of the timer count.
278
 
279
assign rx_shifting_done = (bit_count == `TOTAL_BITS);
280
 
281
 
282
 
283
// This is the signal which enables loading of the shift register.
284
// It also indicates "ack" to the device writing to the transmitter.
285
 
286
 
287
// This is the ODD parity bit for the transmitted word.
288
 
289
 
290
// This is the shift register
291
always @(posedge clk)
292
begin
293
  if (reset) q <= 0;
294
  else if ( (m1_state == m1_rx_falling_edge_marker) )
295
    q <= {ps2_data_s,q[`TOTAL_BITS-1:1]};
296
end
297
 
298
// This is the 60usec timer counter
299
 
300
always @(posedge clk)
301
begin
302
  if (~enable_timer_60usec) timer_60usec_count <= 0;
303
  else if (~timer_60usec_done) timer_60usec_count <= timer_60usec_count + 1;
304
end
305
 
306
assign timer_60usec_done = (timer_60usec_count == (TIMER_60USEC_VALUE_PP - 1));
307
 
308
 
309
 
310
// Create the signals which indicate special scan codes received.
311
// These are the "unlatched versions."
312
 
313
assign extended = (q[8:1] == `EXTEND_CODE) && rx_shifting_done;
314
assign released = (q[8:1] == `RELEASE_CODE) && rx_shifting_done;
315
 
316
 
317
// Store the special scan code status bits
318
// Not the final output, but an intermediate storage place,
319
// until the entire set of output data can be assembled.
320
 
321
// Output the special scan code flags, the scan code and the ascii
322
always @(posedge clk)
323
begin
324
  if (reset)
325
  begin
326
    rx_scan_code <= 0;
327
    interrupt<=0;
328
  end
329
  else if (rx_output_strobe)      //if not extended, not relaeased,get the scan_code 
330
  begin
331
    rx_scan_code <= q[8:1];
332
    interrupt<=1;
333
  end
334
  else
335
  begin
336
  //rx_scan_code<=rx_scan_code;
337
  interrupt<=0;
338
  end
339
end
340
 
341
// Store the final rx output data only when all extend and release codes
342
// are received and the next (actual key) scan code is also ready.
343
// (the presence of rx_extended or rx_released refers to the
344
// the current latest scan code received, not the previously latched flags.)
345
 
346
 
347
assign rx_output_strobe = rx_shifting_done;
348
//                          && ~extended 
349
//                          && ~released
350
//                          );
351
 
352
// This part translates the scan code into an ASCII value...
353
// Only the ASCII codes which I considered important have been included.
354
// if you want more, just add the appropriate case statement lines...
355
// (You will need to know the keyboard scan codes you wish to assign.)
356
// The entries are listed in ascending order of ASCII value.
357
 
358
endmodule
359
 
360
//`undefine TOTAL_BITS
361
//`undefine EXTEND_CODE
362
//`undefine RELEASE_CODE
363
//`undefine LEFT_SHIFT
364
//`undefine RIGHT_SHIFT
365
 

powered by: WebSVN 2.1.0

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