URL
https://opencores.org/ocsvn/ag_6502/ag_6502/trunk
Subversion Repositories ag_6502
[/] [ag_6502/] [trunk/] [juke-box/] [ag_keyb.v] - Rev 4
Compare with Previous | Blame | View Log
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: BMSTU // Engineer: Oleg Odintsov // // Create Date: 00:26:47 02/26/2012 // Design Name: // Module Name: ag_keyb // Project Name: Agat Hardware Project // Target Devices: // Tool versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module signal_filter(input clk, input in, output reg out); always @(posedge clk) begin out <= in; end endmodule module ps2_keyb_driver(ps2_clk, ps2_data, ps2_code, ps2_up, ps2_ext, ps2_event); input wire ps2_clk, ps2_data; output reg[7:0] ps2_code = 0; output reg ps2_up = 0, ps2_ext = 0, ps2_event = 0; reg[10:0] shreg = 11'b11111111111; wire[10:0] shnew = {ps2_data, shreg[10:1]}; wire start = shnew[0], stop = shnew[10], parity = shnew[9]; wire[7:0] data = shnew[8:1]; always @(negedge ps2_clk) begin if (!start && stop && (parity == ~^data)) begin if (data == 8'hE0) begin ps2_ext <= 1; end else if (data == 8'hF0) begin ps2_up <= 1; end else begin ps2_code <= data; ps2_event <= 1; end shreg <= 11'b11111111111; end else begin if (ps2_event) begin ps2_up <= 0; ps2_ext <= 0; ps2_event <= 0; end shreg <= shnew; end end endmodule module ag_reg_decoder(keyb_in, shift, ctrl, keyb_out); input wire[6:0] keyb_in; input wire shift, ctrl; output wire[6:0] keyb_out; wire is_alpha = keyb_in[6] && !keyb_in[5]; wire is_digit = !keyb_in[6] && keyb_in[5] && keyb_in[3:0]; assign keyb_out = is_alpha? (shift?{1'b1,1'b1,keyb_in[4:0]}: ctrl?{1'b0,1'b0,keyb_in[4:0]}: keyb_in): is_digit? (shift?{1'b0,1'b1,~keyb_in[4],keyb_in[3:0]}: keyb_in): keyb_in; endmodule module ag_keyb_decoder(ps2_code, ps2_ext, shift, ctrl, alt, rus, keyb_code); input wire[7:0] ps2_code; input wire ps2_ext, shift, ctrl, alt, rus; output wire[6:0] keyb_code; reg[6:0] keyb_table[0:511]; // eng + rus integer i; wire[6:0] keyb_in; assign keyb_in = keyb_table[{rus,ps2_code}]; ag_reg_decoder rd(keyb_in, shift, ctrl, keyb_code); initial begin for (i = 0; i < 512; i = i + 1) keyb_table[i] = 0; // eng table keyb_table['h15] = 'h51; // Q keyb_table['h1D] = 'h57; // W keyb_table['h24] = 'h45; // E keyb_table['h2D] = 'h52; // R keyb_table['h2C] = 'h54; // T keyb_table['h35] = 'h59; // Y keyb_table['h3C] = 'h55; // U keyb_table['h43] = 'h49; // I keyb_table['h44] = 'h4F; // O keyb_table['h4D] = 'h50; // P keyb_table['h54] = 'h5B; // { keyb_table['h5B] = 'h5D; // } keyb_table['h1C] = 'h41; // A keyb_table['h1B] = 'h53; // S keyb_table['h23] = 'h44; // D keyb_table['h2B] = 'h46; // F keyb_table['h34] = 'h47; // G keyb_table['h33] = 'h48; // H keyb_table['h3B] = 'h4A; // J keyb_table['h42] = 'h4B; // K keyb_table['h4B] = 'h4C; // L keyb_table['h4C] = 'h2A; // : keyb_table['h52] = 'h22; // " keyb_table['h5D] = 'h5C; // \ keyb_table['h5A] = 'h0D; // enter keyb_table['h1A] = 'h5A; // Z keyb_table['h22] = 'h58; // X keyb_table['h21] = 'h43; // C keyb_table['h2A] = 'h56; // V keyb_table['h32] = 'h42; // B keyb_table['h31] = 'h4E; // N keyb_table['h3A] = 'h4D; // M keyb_table['h41] = 'h2C; // < keyb_table['h49] = 'h2E; // > keyb_table['h4A] = 'h2F; // ? keyb_table['h05] = 'h04; // F1 keyb_table['h06] = 'h05; // F2 keyb_table['h04] = 'h06; // F3 keyb_table['h75] = 'h99; // UP keyb_table['h74] = 'h95; // RIGHT keyb_table['h6B] = 'h88; // LEFT keyb_table['h66] = 'h88; // BS keyb_table['h72] = 'h9A; // DOWN keyb_table['h76] = 'h9B; // ESC keyb_table['h29] = 'h20; // SPACE keyb_table['h0E] = 'h00; // ` keyb_table['h16] = 'h31; // 1 keyb_table['h1E] = 'h32; // 2 keyb_table['h26] = 'h33; // 3 keyb_table['h25] = 'h34; // 4 keyb_table['h2E] = 'h35; // 5 keyb_table['h36] = 'h36; // 6 keyb_table['h3D] = 'h37; // 7 keyb_table['h3E] = 'h38; // 8 keyb_table['h46] = 'h39; // 9 keyb_table['h45] = 'h30; // 0 keyb_table['h4E] = 'h2D; // - keyb_table['h55] = 'h3B; // = // rus table + 100h keyb_table['h115] = 'h4A; // Q keyb_table['h11D] = 'h43; // W keyb_table['h124] = 'h55; // E keyb_table['h12D] = 'h4B; // R keyb_table['h12C] = 'h45; // T keyb_table['h135] = 'h4E; // Y keyb_table['h13C] = 'h47; // U keyb_table['h143] = 'h5B; // I keyb_table['h144] = 'h5D; // O keyb_table['h14D] = 'h5A; // P keyb_table['h154] = 'h48; // { keyb_table['h15B] = 'h3A; // }, check keyb_table['h11C] = 'h46; // A keyb_table['h11B] = 'h59; // S keyb_table['h123] = 'h57; // D keyb_table['h12B] = 'h41; // F keyb_table['h134] = 'h50; // G keyb_table['h133] = 'h52; // H keyb_table['h13B] = 'h4F; // J keyb_table['h142] = 'h4C; // K keyb_table['h14B] = 'h44; // L keyb_table['h14C] = 'h56; // : keyb_table['h152] = 'h5C; // " keyb_table['h15D] = 'h2B; // | -> . keyb_table['h15A] = 'h0D; // enter keyb_table['h11A] = 'h51; // Z keyb_table['h122] = 'h5E; // X keyb_table['h121] = 'h53; // C keyb_table['h12A] = 'h4D; // V keyb_table['h132] = 'h49; // B keyb_table['h131] = 'h54; // N keyb_table['h13A] = 'h58; // M keyb_table['h141] = 'h42; // < keyb_table['h149] = 'h2C; // > keyb_table['h14A] = 'h2F; // ? keyb_table['h105] = 'h04; // F1 keyb_table['h106] = 'h05; // F2 keyb_table['h104] = 'h06; // F3 keyb_table['h175] = 'h99; // UP keyb_table['h174] = 'h95; // RIGHT keyb_table['h16B] = 'h88; // LEFT keyb_table['h166] = 'h88; // BS keyb_table['h172] = 'h9A; // DOWN keyb_table['h176] = 'h9B; // ESC keyb_table['h129] = 'h20; // SPACE keyb_table['h10E] = 'h00; // ` keyb_table['h116] = 'h31; // 1 keyb_table['h11E] = 'h32; // 2 keyb_table['h126] = 'h33; // 3 keyb_table['h125] = 'h34; // 4 keyb_table['h12E] = 'h35; // 5 keyb_table['h136] = 'h36; // 6 keyb_table['h13D] = 'h37; // 7 keyb_table['h13E] = 'h38; // 8 keyb_table['h146] = 'h39; // 9 keyb_table['h145] = 'h30; // 0 keyb_table['h14E] = 'h2D; // - keyb_table['h155] = 'h3B; // = end endmodule module ag_keyb(clk, ps2_bus, keyb_reg, keyb_clear, keyb_rus, keyb_rst, keyb_pause); input clk; input wire[1:0] ps2_bus; output wire[7:0] keyb_reg; input wire keyb_clear; output wire keyb_rus; output wire keyb_rst; output wire keyb_pause; wire ps2_clk, ps2_data; assign {ps2_clk, ps2_data} = ps2_bus; reg[7:0] keyb_code; reg clr = 0, got = 0; reg lshift = 0, rshift = 0, ctrl = 0, alt = 0, rus = 0, rst = 0, pause = 0; wire[7:0] ps2_code; wire ps2_up, ps2_ext, ps2_event; assign keyb_reg = clr?0:keyb_code; assign keyb_rus = rus; assign keyb_rst = rst; assign keyb_pause = pause; wire[6:0] dec_code; ps2_keyb_driver kd(ps2_clk, ps2_data, ps2_code, ps2_up, ps2_ext, ps2_event); ag_keyb_decoder dec(ps2_code, ps2_ext, lshift | rshift, ctrl, alt, rus, dec_code); always @(posedge clk) begin if (keyb_clear) clr <= 1; if (ps2_event && !got) begin if (!ps2_up) begin if (ps2_code == 8'h12 && ctrl) rus <= 0; else if (ps2_code == 8'h14 && lshift) rus <= 0; else if (ps2_code == 8'h59 && ctrl) rus <= 1; else if (ps2_code == 8'h14 && rshift) rus <= 1; clr <= 0; keyb_code <= {|dec_code, dec_code}; end if (ps2_code == 8'h12) lshift <= ~ps2_up; else if (ps2_code == 8'h59) rshift <= ~ps2_up; else if (ps2_code == 8'h14 || ps2_code == 8'h0D) ctrl <= ~ps2_up; // ctrl or tab else if (ps2_code == 8'h11) alt <= ~ps2_up; else if (ps2_code == 8'h7E) pause <= ~ps2_up; if (ps2_code == 8'h76 && ctrl) rst <= ~ps2_up; got <= 1; end if (!ps2_event) got <= 0; end endmodule