2012年11月21日 星期三

LAB05 PS2 Keyboard & LED 7-SEGMENT DISPLAY

LAB05  PS2 Keyboard & LED 7-SEGMENT DISPLAY 
適用於DE2-70







源自於 http://www.computer-engineering.org/ps2keyboard/scancodes2.html

Keyboard Scan Codes: Set 2
*All values are in hexadecimal
101-, 102-, and 104-key keyboards:
 

KEY
MAKE
BREAK
-----
KEY
MAKE
BREAK
-----
KEY
MAKE
BREAK
A
1C
F0,1C
 
9
46
F0,46
 
[
54
FO,54
B
32
F0,32
 
`
0E
F0,0E
 
INSERT
E0,70
E0,F0,70
C
21
F0,21
 
-
4E
F0,4E
 
HOME
E0,6C
E0,F0,6C
D
23
F0,23
 
=
55
FO,55
 
PG UP
E0,7D
E0,F0,7D
E
24
F0,24
 
\
5D
F0,5D
 
DELETE
E0,71
E0,F0,71
F
2B
F0,2B
 
BKSP
66
F0,66
 
END
E0,69
E0,F0,69
G
34
F0,34
 
SPACE
29
F0,29
 
PG DN
E0,7A
E0,F0,7A
H
33
F0,33
 
TAB
0D
F0,0D
 
U ARROW
E0,75
E0,F0,75
I
43
F0,43
 
CAPS
58
F0,58
 
L ARROW
E0,6B
E0,F0,6B
J
3B
F0,3B
 
L SHFT
12
FO,12
 
D ARROW
E0,72
E0,F0,72
K
42
F0,42
 
L CTRL
14
FO,14
 
R ARROW
E0,74
E0,F0,74
L
4B
F0,4B
 
L GUI
E0,1F
E0,F0,1F
 
NUM
77
F0,77
M
3A
F0,3A
 
L ALT
11
F0,11
 
KP /
E0,4A
E0,F0,4A
N
31
F0,31
 
R SHFT
59
F0,59
 
KP *
7C
F0,7C
O
44
F0,44
 
R CTRL
E0,14
E0,F0,14
 
KP -
7B
F0,7B
P
4D
F0,4D
 
R GUI
E0,27
E0,F0,27
 
KP +
79
F0,79
Q
15
F0,15
 
R ALT
E0,11
E0,F0,11
 
KP EN
E0,5A
E0,F0,5A
R
2D
F0,2D
 
APPS
E0,2F
E0,F0,2F
 
KP .
71
F0,71
S
1B
F0,1B
 
ENTER
5A
F0,5A
 
KP 0
70
F0,70
T
2C
F0,2C
 
ESC
76
F0,76
 
KP 1
69
F0,69
U
3C
F0,3C
 
F1
05
F0,05
 
KP 2
72
F0,72
V
2A
F0,2A
 
F2
06
F0,06
 
KP 3
7A
F0,7A
W
1D
F0,1D
 
F3
04
F0,04
 
KP 4
6B
F0,6B
X
22
F0,22
 
F4
0C
F0,0C
 
KP 5
73
F0,73
Y
35
F0,35
 
F5
03
F0,03
 
KP 6
74
F0,74
Z
1A
F0,1A
 
F6
0B
F0,0B
 
KP 7
6C
F0,6C
0
45
F0,45
 
F7
83
F0,83
 
KP 8
75
F0,75
1
16
F0,16
 
F8
0A
F0,0A
 
KP 9
7D
F0,7D
2
1E
F0,1E
 
F9
01
F0,01
 
]
5B
F0,5B
3
26
F0,26
 
F10
09
F0,09
 
;
4C
F0,4C
4
25
F0,25
 
F11
78
F0,78
 
'
52
F0,52
5
2E
F0,2E
 
F12
07
F0,07
 
,
41
F0,41
6
36
F0,36
 
PRNT
SCRN
E0,12,
E0,7C 
E0,F0,
7C,E0,
F0,12 
 
.
49
F0,49
7
3D
F0,3D
 
SCROLL
7E
F0,7E
 
/
4A
F0,4A
8
3E
F0,3E
 
PAUSE
E1,14,77,
E1,F0,14,
F0,77
-NONE-

 
 
ACPI Scan Codes:

KeyMake CodeBreak Code
PowerE0, 37E0, F0, 37
SleepE0, 3FE0, F0, 3F
WakeE0, 5EE0, F0, 5E
Windows Multimedia Scan Codes:

KeyMake CodeBreak Code
Next TrackE0, 4DE0, F0, 4D 
Previous TrackE0, 15E0, F0, 15
StopE0, 3BE0, F0, 3B
Play/PauseE0, 34E0, F0, 34
MuteE0, 23E0, F0, 23
Volume UpE0, 32E0, F0, 32
Volume DownE0, 21E0, F0, 21
Media SelectE0, 50E0, F0, 50
E-MailE0, 48E0, F0, 48
CalculatorE0, 2BE0, F0, 2B
My ComputerE0, 40E0, F0, 40
WWW SearchE0, 10E0, F0, 10
WWW HomeE0, 3AE0, F0, 3A
WWW BackE0, 38E0, F0, 38
WWW ForwardE0, 30E0, F0, 30
WWW StopE0, 28E0, F0, 28
WWW RefreshE0, 20E0, F0, 20
WWW FavoritesE0, 18E0, F0, 18








    module ps2lab1(
      // Clock Input (50 MHz)
      input  CLOCK_50,
      //  Push Buttons
      input  [3:0]  KEY,
      //  DPDT Switches 
      input  [17:0]  SW,
      //  7-SEG Displays
      output  [6:0]  HEX0, HEX1, HEX2, HEX3, HEX4, HEX5, HEX6, HEX7,
      //  LEDs
      output  [8:0]  LEDG,  //  LED Green[8:0]
      output  [17:0]  LEDR,  //  LED Red[17:0]
      //  PS2 data and clock lines
      input PS2_DAT,
      input PS2_CLK,
      //  GPIO Connections
      inout  [35:0]  GPIO_0, GPIO_1
    );

    //  set all inout ports to tri-state
    assign  GPIO_0    =  36'hzzzzzzzzz;
    assign  GPIO_1    =  36'hzzzzzzzzz;

    wire RST;
    assign RST = KEY[0];


    // Connect dip switches to red LEDs
    assign LEDR[17:0] = SW[17:0];

    // turn off green LEDs
    assign LEDG = 0;

    wire reset = 1'b0;
    wire [7:0] scan_code;

    reg [7:0] history[1:4];
    wire read, scan_ready;

    oneshot pulser(
       .pulse_out(read),
       .trigger_in(scan_ready),
       .clk(CLOCK_50)
    );

    keyboard kbd(
      .keyboard_clk(PS2_CLK),
      .keyboard_data(PS2_DAT),
      .clock50(CLOCK_50),
      .reset(reset),
      .read(read),
      .scan_ready(scan_ready),
      .scan_code(scan_code)
    );

    hex_7seg dsp0(history[1][3:0],HEX0);
    hex_7seg dsp1(history[1][7:4],HEX1);

    hex_7seg dsp2(history[2][3:0],HEX2);
    hex_7seg dsp3(history[2][7:4],HEX3);

    hex_7seg dsp4(history[3][3:0],HEX4);
    hex_7seg dsp5(history[3][7:4],HEX5);

    hex_7seg dsp6(history[4][3:0],HEX6);
    hex_7seg dsp7(history[4][7:4],HEX7);



    always @(posedge scan_ready)
    begin
    history[4] <= history[3];
    history[3] <= history[2];
    history[2] <= history[1];
    history[1] <= scan_code;
    end

    // blank remaining digits
    /*
    wire [6:0] blank = 7'h7f;
    assign HEX2 = blank;
    assign HEX3 = blank;
    assign HEX4 = blank;
    assign HEX5 = blank;
    assign HEX6 = blank;
    assign HEX7 = blank;
    */

    endmodule




    module hex_7seg(hex_digit,seg);
    input [3:0] hex_digit;
    output [6:0] seg;
    reg [6:0] seg;
    // seg = {g,f,e,d,c,b,a};
    // 0 is on and 1 is off

    always @ (hex_digit)
    case (hex_digit)
    4'h0: seg = 7'b1000000;
    4'h1: seg = 7'b1111001; // ---a----
    4'h2: seg = 7'b0100100; // |  |
    4'h3: seg = 7'b0110000; // f  b
    4'h4: seg = 7'b0011001; // |  |
    4'h5: seg = 7'b0010010; // ---g----
    4'h6: seg = 7'b0000010; // |  |
    4'h7: seg = 7'b1111000; // e  c
    4'h8: seg = 7'b0000000; // |  |
    4'h9: seg = 7'b0011000; // ---d----
    4'ha: seg = 7'b0001000;
    4'hb: seg = 7'b0000011;
    4'hc: seg = 7'b1000110;
    4'hd: seg = 7'b0100001;
    4'he: seg = 7'b0000110;
    4'hf: seg = 7'b0001110;
    endcase

    endmodule




    module keyboard(keyboard_clk, keyboard_data, clock50, reset, read, scan_ready, scan_code);
    input keyboard_clk;
    input keyboard_data;
    input clock50; // 50 Mhz system clock
    input reset;
    input read;
    output scan_ready;
    output [7:0] scan_code;
    reg ready_set;
    reg [7:0] scan_code;
    reg scan_ready;
    reg read_char;
    reg clock; // 25 Mhz internal clock

    reg [3:0] incnt;
    reg [8:0] shiftin;

    reg [7:0] filter;
    reg keyboard_clk_filtered;

    // scan_ready is set to 1 when scan_code is available.
    // user should set read to 1 and then to 0 to clear scan_ready

    always @ (posedge ready_set or posedge read)
    if (read == 1) scan_ready <= 0;
    else scan_ready <= 1;

    // divide-by-two 50MHz to 25MHz
    always @(posedge clock50)
    clock <= ~clock;



    // This process filters the raw clock signal coming from the keyboard 
    // using an eight-bit shift register and two AND gates

    always @(posedge clock)
    begin
       filter <= {keyboard_clk, filter[7:1]};
       if (filter==8'b1111_1111) keyboard_clk_filtered <= 1;
       else if (filter==8'b0000_0000) keyboard_clk_filtered <= 0;
    end


    // This process reads in serial data coming from the terminal

    always @(posedge keyboard_clk_filtered)
    begin
       if (reset==1)
       begin
          incnt <= 4'b0000;
          read_char <= 0;
       end
       else if (keyboard_data==0 && read_char==0)
       begin
    read_char <= 1;
    ready_set <= 0;
       end
       else
       begin
      // shift in next 8 data bits to assemble a scan code
      if (read_char == 1)
        begin
          if (incnt < 9) 
          begin
    incnt <= incnt + 1'b1;
    shiftin = { keyboard_data, shiftin[8:1]};
    ready_set <= 0;
    end
    else
    begin
    incnt <= 0;
    scan_code <= shiftin[7:0];
    read_char <= 0;
    ready_set <= 1;
    end
    end
    end
    end

    endmodule



    module oneshot(output reg pulse_out, input trigger_in, input clk);
    reg delay;

    always @ (posedge clk)
    begin
    if (trigger_in && !delay) pulse_out <= 1'b1;
    else pulse_out <= 1'b0;
    delay <= trigger_in;
    end 
    endmodule

    沒有留言:

    張貼留言

    Messaging API作為替代方案

      LINE超好用功能要沒了!LINE Notify明年3月底終止服務,有什麼替代方案? LINE Notify將於2025年3月31日結束服務,官方建議改用Messaging API作為替代方案。 //CHANNEL_ACCESS_TOKEN = 'Messaging ...