-
Notifications
You must be signed in to change notification settings - Fork 2
/
PS2_KEYBOARD2.v
178 lines (165 loc) · 4.17 KB
/
PS2_KEYBOARD2.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
module PS2_KEYBOARD2(
inout PS2_DAT,
input PS2_CLK,
input clk,
input rst,
input rst1,
output reg [7:0] scandata,
output reg key1_on,
output reg key2_on,
output reg key3_on,
output reg [7:0] key1_code,
output reg [7:0] key2_code,
output reg [7:0] key3_code
);
parameter KEY_UP = 8'h75;
parameter KEY_DOWN = 8'h72;
parameter KEY_LEFT = 8'h6B;
parameter KEY_RIGHT = 8'h74;
parameter KEY_SHIFT = 8'h12;
parameter KEY_L_ROTATE = 8'h1A;
parameter KEY_R_ROTATE = 8'h22;
parameter KEY_ENTER = 8'h5A;
parameter KEY_HOLD = 8'h21;
parameter KEY_SPACE = 8'h29;
////////////Keyboard Initially/////////
reg [10:0] MCNT;
always @(negedge rst or posedge clk)begin
if (!rst)
MCNT=0;
else if(MCNT < 500)
MCNT=MCNT+1;
end
///// sequence generator /////
reg [7:0] revcnt;
wire rev_tr=(MCNT<12)?1:0;
always @(posedge rev_tr or posedge PS2_CLK)begin
if (rev_tr)
revcnt=0;
else if (revcnt >=10)
revcnt=0;
else
revcnt=revcnt+1;
end
//////KeyBoard serial data in /////
reg [9:0]keycode_o;
always @(posedge PS2_CLK)begin
case (revcnt[3:0])
1:
keycode_o[0]=PS2_DAT;
2:
keycode_o[1]=PS2_DAT;
3:
keycode_o[2]=PS2_DAT;
4:
keycode_o[3]=PS2_DAT;
5:
keycode_o[4]=PS2_DAT;
6:
keycode_o[5]=PS2_DAT;
7:
keycode_o[6]=PS2_DAT;
8:
keycode_o[7]=PS2_DAT;
endcase
end
wire [7:0]rc=keycode_o[7:0];
wire HOST_ACK=(revcnt==10)?~(rc[7]^rc[6]^rc[5]^rc[4]^rc[3]^rc[2]^rc[1]^rc[0]) :1;
////////PS2 InOut/////////
assign PS2_DAT =(HOST_ACK)?1'bz:1'b0;
///////KeyBoard Scan-Code trigger//////
reg keyready;
always @(posedge rev_tr or negedge PS2_CLK)begin
if (rev_tr)
keyready=0;
else if (revcnt[3:0]==10)
keyready=1;
else
keyready=0;
end
/////////////////////////////////////Key1-Key2 Output///////////////////////////
wire is_key=(
(keycode_o == KEY_UP)?1:(
(keycode_o == KEY_DOWN)?1:(
(keycode_o == KEY_LEFT)?1:(
(keycode_o == KEY_RIGHT)?1:(
(keycode_o == KEY_SHIFT)?1:(
(keycode_o == KEY_L_ROTATE)?1:(
(keycode_o == KEY_R_ROTATE)?1:(
(keycode_o == KEY_HOLD)?1:(
(keycode_o == KEY_SPACE)?1:(
(keycode_o == KEY_ENTER)?1:0
)))))))))
);
//////////////key1 & key2 Assign///////////
wire keyboard_off=((MCNT==200) || (!rst1))?0:1;
always @(posedge keyready) scandata = keycode_o;
always @(negedge keyboard_off or posedge keyready)begin
if (!keyboard_off)begin
key1_on=0;
key2_on=0;
key3_on=0;
key1_code=8'hf0;
key2_code=8'hf0;
key3_code=8'hf0;
end
else if (scandata==8'hf0)begin
if (keycode_o==key1_code)begin
key1_code=8'hf0;
key1_on=0;
end
else if (keycode_o==key2_code)begin
key2_code=8'hf0;
key2_on=0;
end
else if (keycode_o==key3_code)begin
key3_code=8'hf0;
key3_on=0;
end
end
else if (is_key)begin
case(keycode_o)
KEY_ENTER:begin
key1_on=1;
key1_code=keycode_o;
end
KEY_LEFT:begin
key1_on=1;
key1_code=keycode_o;
end
KEY_RIGHT:begin
key1_on=1;
key1_code=keycode_o;
end
KEY_L_ROTATE:begin
key2_on=1;
key2_code=keycode_o;
end
KEY_R_ROTATE:begin
key2_on=1;
key2_code=keycode_o;
end
KEY_UP:begin
key2_on=1;
key2_code=keycode_o;
end
KEY_DOWN:begin
key3_on=1;
key3_code=keycode_o;
end
KEY_SHIFT:begin
key3_on=1;
key3_code=keycode_o;
end
KEY_HOLD:begin
key3_on=1;
key3_code=keycode_o;
end
KEY_SPACE:begin
key3_on=1;
key3_code=keycode_o;
end
endcase
end
end
endmodule