1 |
3 |
olegodints |
`timescale 1ns / 1ps
|
2 |
|
|
//////////////////////////////////////////////////////////////////////////////////
|
3 |
|
|
// Company: BMSTU
|
4 |
|
|
// Engineer: Oleg Odintsov
|
5 |
|
|
//
|
6 |
|
|
// Create Date: 00:26:47 02/26/2012
|
7 |
|
|
// Design Name:
|
8 |
|
|
// Module Name: ag_keyb
|
9 |
|
|
// Project Name: Agat Hardware Project
|
10 |
|
|
// Target Devices:
|
11 |
|
|
// Tool versions:
|
12 |
|
|
// Description:
|
13 |
|
|
//
|
14 |
|
|
// Dependencies:
|
15 |
|
|
//
|
16 |
|
|
// Revision:
|
17 |
|
|
// Revision 0.01 - File Created
|
18 |
|
|
// Additional Comments:
|
19 |
|
|
//
|
20 |
|
|
//////////////////////////////////////////////////////////////////////////////////
|
21 |
|
|
|
22 |
|
|
|
23 |
|
|
module signal_filter(input clk, input in, output reg out);
|
24 |
|
|
always @(posedge clk) begin
|
25 |
|
|
out <= in;
|
26 |
|
|
end
|
27 |
|
|
endmodule
|
28 |
|
|
|
29 |
|
|
|
30 |
|
|
module ps2_keyb_driver(ps2_clk, ps2_data, ps2_code, ps2_up, ps2_ext, ps2_event);
|
31 |
|
|
input wire ps2_clk, ps2_data;
|
32 |
|
|
output reg[7:0] ps2_code = 0;
|
33 |
|
|
output reg ps2_up = 0, ps2_ext = 0, ps2_event = 0;
|
34 |
|
|
|
35 |
|
|
reg[10:0] shreg = 11'b11111111111;
|
36 |
|
|
wire[10:0] shnew = {ps2_data, shreg[10:1]};
|
37 |
|
|
wire start = shnew[0], stop = shnew[10], parity = shnew[9];
|
38 |
|
|
wire[7:0] data = shnew[8:1];
|
39 |
|
|
|
40 |
|
|
always @(negedge ps2_clk) begin
|
41 |
|
|
if (!start && stop && (parity == ~^data)) begin
|
42 |
|
|
if (data == 8'hE0) begin
|
43 |
|
|
ps2_ext <= 1;
|
44 |
|
|
end else if (data == 8'hF0) begin
|
45 |
|
|
ps2_up <= 1;
|
46 |
|
|
end else begin
|
47 |
|
|
ps2_code <= data;
|
48 |
|
|
ps2_event <= 1;
|
49 |
|
|
end
|
50 |
|
|
shreg <= 11'b11111111111;
|
51 |
|
|
end else begin
|
52 |
|
|
if (ps2_event) begin
|
53 |
|
|
ps2_up <= 0;
|
54 |
|
|
ps2_ext <= 0;
|
55 |
|
|
ps2_event <= 0;
|
56 |
|
|
end
|
57 |
|
|
shreg <= shnew;
|
58 |
|
|
end
|
59 |
|
|
end
|
60 |
|
|
endmodule
|
61 |
|
|
|
62 |
|
|
module ag_reg_decoder(keyb_in, shift, ctrl, keyb_out);
|
63 |
|
|
input wire[6:0] keyb_in;
|
64 |
|
|
input wire shift, ctrl;
|
65 |
|
|
output wire[6:0] keyb_out;
|
66 |
|
|
|
67 |
|
|
wire is_alpha = keyb_in[6] && !keyb_in[5];
|
68 |
|
|
wire is_digit = !keyb_in[6] && keyb_in[5] && keyb_in[3:0];
|
69 |
|
|
|
70 |
|
|
assign keyb_out =
|
71 |
|
|
is_alpha?
|
72 |
|
|
(shift?{1'b1,1'b1,keyb_in[4:0]}:
|
73 |
|
|
ctrl?{1'b0,1'b0,keyb_in[4:0]}:
|
74 |
|
|
keyb_in):
|
75 |
|
|
is_digit?
|
76 |
|
|
(shift?{1'b0,1'b1,~keyb_in[4],keyb_in[3:0]}:
|
77 |
|
|
keyb_in):
|
78 |
|
|
keyb_in;
|
79 |
|
|
endmodule
|
80 |
|
|
|
81 |
|
|
module ag_keyb_decoder(ps2_code, ps2_ext, shift, ctrl, alt, rus, keyb_code);
|
82 |
|
|
input wire[7:0] ps2_code;
|
83 |
|
|
input wire ps2_ext, shift, ctrl, alt, rus;
|
84 |
|
|
output wire[6:0] keyb_code;
|
85 |
|
|
reg[6:0] keyb_table[0:511]; // eng + rus
|
86 |
|
|
integer i;
|
87 |
|
|
|
88 |
|
|
wire[6:0] keyb_in;
|
89 |
|
|
|
90 |
|
|
assign keyb_in = keyb_table[{rus,ps2_code}];
|
91 |
|
|
ag_reg_decoder rd(keyb_in, shift, ctrl, keyb_code);
|
92 |
|
|
|
93 |
|
|
initial begin
|
94 |
|
|
for (i = 0; i < 512; i = i + 1) keyb_table[i] = 0;
|
95 |
|
|
|
96 |
|
|
// eng table
|
97 |
|
|
keyb_table['h15] = 'h51; // Q
|
98 |
|
|
keyb_table['h1D] = 'h57; // W
|
99 |
|
|
keyb_table['h24] = 'h45; // E
|
100 |
|
|
keyb_table['h2D] = 'h52; // R
|
101 |
|
|
keyb_table['h2C] = 'h54; // T
|
102 |
|
|
keyb_table['h35] = 'h59; // Y
|
103 |
|
|
keyb_table['h3C] = 'h55; // U
|
104 |
|
|
keyb_table['h43] = 'h49; // I
|
105 |
|
|
keyb_table['h44] = 'h4F; // O
|
106 |
|
|
keyb_table['h4D] = 'h50; // P
|
107 |
|
|
keyb_table['h54] = 'h5B; // {
|
108 |
|
|
keyb_table['h5B] = 'h5D; // }
|
109 |
|
|
|
110 |
|
|
keyb_table['h1C] = 'h41; // A
|
111 |
|
|
keyb_table['h1B] = 'h53; // S
|
112 |
|
|
keyb_table['h23] = 'h44; // D
|
113 |
|
|
keyb_table['h2B] = 'h46; // F
|
114 |
|
|
keyb_table['h34] = 'h47; // G
|
115 |
|
|
keyb_table['h33] = 'h48; // H
|
116 |
|
|
keyb_table['h3B] = 'h4A; // J
|
117 |
|
|
keyb_table['h42] = 'h4B; // K
|
118 |
|
|
keyb_table['h4B] = 'h4C; // L
|
119 |
|
|
keyb_table['h4C] = 'h2A; // :
|
120 |
|
|
keyb_table['h52] = 'h22; // "
|
121 |
|
|
keyb_table['h5D] = 'h5C; // \
|
122 |
|
|
keyb_table['h5A] = 'h0D; // enter
|
123 |
|
|
|
124 |
|
|
keyb_table['h1A] = 'h5A; // Z
|
125 |
|
|
keyb_table['h22] = 'h58; // X
|
126 |
|
|
keyb_table['h21] = 'h43; // C
|
127 |
|
|
keyb_table['h2A] = 'h56; // V
|
128 |
|
|
keyb_table['h32] = 'h42; // B
|
129 |
|
|
keyb_table['h31] = 'h4E; // N
|
130 |
|
|
keyb_table['h3A] = 'h4D; // M
|
131 |
|
|
keyb_table['h41] = 'h2C; // <
|
132 |
|
|
keyb_table['h49] = 'h2E; // >
|
133 |
|
|
keyb_table['h4A] = 'h2F; // ?
|
134 |
|
|
|
135 |
|
|
keyb_table['h05] = 'h04; // F1
|
136 |
|
|
keyb_table['h06] = 'h05; // F2
|
137 |
|
|
keyb_table['h04] = 'h06; // F3
|
138 |
|
|
|
139 |
|
|
keyb_table['h75] = 'h99; // UP
|
140 |
|
|
keyb_table['h74] = 'h95; // RIGHT
|
141 |
|
|
keyb_table['h6B] = 'h88; // LEFT
|
142 |
|
|
keyb_table['h66] = 'h88; // BS
|
143 |
|
|
keyb_table['h72] = 'h9A; // DOWN
|
144 |
|
|
keyb_table['h76] = 'h9B; // ESC
|
145 |
|
|
keyb_table['h29] = 'h20; // SPACE
|
146 |
|
|
|
147 |
|
|
keyb_table['h0E] = 'h00; // `
|
148 |
|
|
keyb_table['h16] = 'h31; // 1
|
149 |
|
|
keyb_table['h1E] = 'h32; // 2
|
150 |
|
|
keyb_table['h26] = 'h33; // 3
|
151 |
|
|
keyb_table['h25] = 'h34; // 4
|
152 |
|
|
keyb_table['h2E] = 'h35; // 5
|
153 |
|
|
keyb_table['h36] = 'h36; // 6
|
154 |
|
|
keyb_table['h3D] = 'h37; // 7
|
155 |
|
|
keyb_table['h3E] = 'h38; // 8
|
156 |
|
|
keyb_table['h46] = 'h39; // 9
|
157 |
|
|
keyb_table['h45] = 'h30; // 0
|
158 |
|
|
keyb_table['h4E] = 'h2D; // -
|
159 |
|
|
keyb_table['h55] = 'h3B; // =
|
160 |
|
|
|
161 |
|
|
// rus table + 100h
|
162 |
|
|
keyb_table['h115] = 'h4A; // Q
|
163 |
|
|
keyb_table['h11D] = 'h43; // W
|
164 |
|
|
keyb_table['h124] = 'h55; // E
|
165 |
|
|
keyb_table['h12D] = 'h4B; // R
|
166 |
|
|
keyb_table['h12C] = 'h45; // T
|
167 |
|
|
keyb_table['h135] = 'h4E; // Y
|
168 |
|
|
keyb_table['h13C] = 'h47; // U
|
169 |
|
|
keyb_table['h143] = 'h5B; // I
|
170 |
|
|
keyb_table['h144] = 'h5D; // O
|
171 |
|
|
keyb_table['h14D] = 'h5A; // P
|
172 |
|
|
keyb_table['h154] = 'h48; // {
|
173 |
|
|
keyb_table['h15B] = 'h3A; // }, check
|
174 |
|
|
|
175 |
|
|
keyb_table['h11C] = 'h46; // A
|
176 |
|
|
keyb_table['h11B] = 'h59; // S
|
177 |
|
|
keyb_table['h123] = 'h57; // D
|
178 |
|
|
keyb_table['h12B] = 'h41; // F
|
179 |
|
|
keyb_table['h134] = 'h50; // G
|
180 |
|
|
keyb_table['h133] = 'h52; // H
|
181 |
|
|
keyb_table['h13B] = 'h4F; // J
|
182 |
|
|
keyb_table['h142] = 'h4C; // K
|
183 |
|
|
keyb_table['h14B] = 'h44; // L
|
184 |
|
|
keyb_table['h14C] = 'h56; // :
|
185 |
|
|
keyb_table['h152] = 'h5C; // "
|
186 |
|
|
keyb_table['h15D] = 'h2B; // | -> .
|
187 |
|
|
keyb_table['h15A] = 'h0D; // enter
|
188 |
|
|
|
189 |
|
|
keyb_table['h11A] = 'h51; // Z
|
190 |
|
|
keyb_table['h122] = 'h5E; // X
|
191 |
|
|
keyb_table['h121] = 'h53; // C
|
192 |
|
|
keyb_table['h12A] = 'h4D; // V
|
193 |
|
|
keyb_table['h132] = 'h49; // B
|
194 |
|
|
keyb_table['h131] = 'h54; // N
|
195 |
|
|
keyb_table['h13A] = 'h58; // M
|
196 |
|
|
keyb_table['h141] = 'h42; // <
|
197 |
|
|
keyb_table['h149] = 'h2C; // >
|
198 |
|
|
keyb_table['h14A] = 'h2F; // ?
|
199 |
|
|
|
200 |
|
|
keyb_table['h105] = 'h04; // F1
|
201 |
|
|
keyb_table['h106] = 'h05; // F2
|
202 |
|
|
keyb_table['h104] = 'h06; // F3
|
203 |
|
|
|
204 |
|
|
keyb_table['h175] = 'h99; // UP
|
205 |
|
|
keyb_table['h174] = 'h95; // RIGHT
|
206 |
|
|
keyb_table['h16B] = 'h88; // LEFT
|
207 |
|
|
keyb_table['h166] = 'h88; // BS
|
208 |
|
|
keyb_table['h172] = 'h9A; // DOWN
|
209 |
|
|
keyb_table['h176] = 'h9B; // ESC
|
210 |
|
|
keyb_table['h129] = 'h20; // SPACE
|
211 |
|
|
|
212 |
|
|
keyb_table['h10E] = 'h00; // `
|
213 |
|
|
keyb_table['h116] = 'h31; // 1
|
214 |
|
|
keyb_table['h11E] = 'h32; // 2
|
215 |
|
|
keyb_table['h126] = 'h33; // 3
|
216 |
|
|
keyb_table['h125] = 'h34; // 4
|
217 |
|
|
keyb_table['h12E] = 'h35; // 5
|
218 |
|
|
keyb_table['h136] = 'h36; // 6
|
219 |
|
|
keyb_table['h13D] = 'h37; // 7
|
220 |
|
|
keyb_table['h13E] = 'h38; // 8
|
221 |
|
|
keyb_table['h146] = 'h39; // 9
|
222 |
|
|
keyb_table['h145] = 'h30; // 0
|
223 |
|
|
keyb_table['h14E] = 'h2D; // -
|
224 |
|
|
keyb_table['h155] = 'h3B; // =
|
225 |
|
|
end
|
226 |
|
|
endmodule
|
227 |
|
|
|
228 |
|
|
module ag_keyb(clk, ps2_bus, keyb_reg, keyb_clear, keyb_rus, keyb_rst, keyb_pause);
|
229 |
|
|
input clk;
|
230 |
|
|
input wire[1:0] ps2_bus;
|
231 |
|
|
output wire[7:0] keyb_reg;
|
232 |
|
|
input wire keyb_clear;
|
233 |
|
|
output wire keyb_rus;
|
234 |
|
|
output wire keyb_rst;
|
235 |
|
|
output wire keyb_pause;
|
236 |
|
|
|
237 |
|
|
|
238 |
|
|
wire ps2_clk, ps2_data;
|
239 |
|
|
assign {ps2_clk, ps2_data} = ps2_bus;
|
240 |
|
|
|
241 |
|
|
reg[7:0] keyb_code;
|
242 |
|
|
reg clr = 0, got = 0;
|
243 |
|
|
reg lshift = 0, rshift = 0, ctrl = 0, alt = 0, rus = 0, rst = 0, pause = 0;
|
244 |
|
|
wire[7:0] ps2_code;
|
245 |
|
|
wire ps2_up, ps2_ext, ps2_event;
|
246 |
|
|
|
247 |
|
|
assign keyb_reg = clr?0:keyb_code;
|
248 |
|
|
assign keyb_rus = rus;
|
249 |
|
|
assign keyb_rst = rst;
|
250 |
|
|
assign keyb_pause = pause;
|
251 |
|
|
|
252 |
|
|
wire[6:0] dec_code;
|
253 |
|
|
|
254 |
|
|
ps2_keyb_driver kd(ps2_clk, ps2_data, ps2_code, ps2_up, ps2_ext, ps2_event);
|
255 |
|
|
ag_keyb_decoder dec(ps2_code, ps2_ext, lshift | rshift, ctrl, alt, rus, dec_code);
|
256 |
|
|
|
257 |
|
|
always @(posedge clk) begin
|
258 |
|
|
if (keyb_clear) clr <= 1;
|
259 |
|
|
if (ps2_event && !got) begin
|
260 |
|
|
if (!ps2_up) begin
|
261 |
|
|
if (ps2_code == 8'h12 && ctrl) rus <= 0;
|
262 |
|
|
else if (ps2_code == 8'h14 && lshift) rus <= 0;
|
263 |
|
|
else if (ps2_code == 8'h59 && ctrl) rus <= 1;
|
264 |
|
|
else if (ps2_code == 8'h14 && rshift) rus <= 1;
|
265 |
|
|
clr <= 0;
|
266 |
|
|
keyb_code <= {|dec_code, dec_code};
|
267 |
|
|
end
|
268 |
|
|
if (ps2_code == 8'h12) lshift <= ~ps2_up;
|
269 |
|
|
else if (ps2_code == 8'h59) rshift <= ~ps2_up;
|
270 |
|
|
else if (ps2_code == 8'h14 || ps2_code == 8'h0D) ctrl <= ~ps2_up; // ctrl or tab
|
271 |
|
|
else if (ps2_code == 8'h11) alt <= ~ps2_up;
|
272 |
|
|
else if (ps2_code == 8'h7E) pause <= ~ps2_up;
|
273 |
|
|
|
274 |
|
|
if (ps2_code == 8'h76 && ctrl) rst <= ~ps2_up;
|
275 |
|
|
got <= 1;
|
276 |
|
|
end
|
277 |
|
|
if (!ps2_event) got <= 0;
|
278 |
|
|
end
|
279 |
|
|
endmodule
|