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

Subversion Repositories ps2

[/] [ps2/] [trunk/] [rtl/] [verilog/] [ps2_keyboard.v] - Diff between revs 2 and 13

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 2 Rev 13
Line 113... Line 113...
// synopsys translate_off
// synopsys translate_off
`resetall
`resetall
`include "timescale.v"
`include "timescale.v"
// synopsys translate_on
// synopsys translate_on
`define TOTAL_BITS   11
`define TOTAL_BITS   11
`define EXTEND_CODE  16'hE0
 
`define RELEASE_CODE 16'hF0
`define RELEASE_CODE 16'hF0
`define LEFT_SHIFT   16'h12
 
`define RIGHT_SHIFT  16'h59
 
 
 
 
 
module ps2_keyboard (
module ps2_keyboard (
  clk,
  clk,
  reset,
  reset,
  ps2_clk_en_o_,
  ps2_clk_en_o_,
  ps2_data_en_o_,
  ps2_data_en_o_,
  ps2_clk_i,
  ps2_clk_i,
  ps2_data_i,
  ps2_data_i,
  rx_extended,
 
  rx_released,
  rx_released,
  rx_shift_key_on,
 
  rx_scan_code,
  rx_scan_code,
  rx_ascii,
 
  rx_data_ready,       // rx_read_o
  rx_data_ready,       // rx_read_o
  rx_read,             // rx_read_ack_i
  rx_read,             // rx_read_ack_i
  tx_data,
  tx_data,
  tx_write,
  tx_write,
  tx_write_ack_o,
  tx_write_ack_o,
Line 147... Line 140...
// The timer value can be up to (2^bits) inclusive.
// The timer value can be up to (2^bits) inclusive.
parameter TIMER_60USEC_VALUE_PP = 2950; // Number of sys_clks for 60usec.
parameter TIMER_60USEC_VALUE_PP = 2950; // Number of sys_clks for 60usec.
parameter TIMER_60USEC_BITS_PP  = 12;   // Number of bits needed for timer
parameter TIMER_60USEC_BITS_PP  = 12;   // Number of bits needed for timer
parameter TIMER_5USEC_VALUE_PP = 186;   // Number of sys_clks for debounce
parameter TIMER_5USEC_VALUE_PP = 186;   // Number of sys_clks for debounce
parameter TIMER_5USEC_BITS_PP  = 8;     // Number of bits needed for timer
parameter TIMER_5USEC_BITS_PP  = 8;     // Number of bits needed for timer
parameter TRAP_SHIFT_KEYS_PP = 0;       // Default: No shift key trap.
 
 
 
// State encodings, provided as parameters
// State encodings, provided as parameters
// for flexibility to the one instantiating the module.
// for flexibility to the one instantiating the module.
// In general, the default values need not be changed.
// In general, the default values need not be changed.
 
 
Line 188... Line 180...
input reset;
input reset;
output ps2_clk_en_o_ ;
output ps2_clk_en_o_ ;
output ps2_data_en_o_ ;
output ps2_data_en_o_ ;
input  ps2_clk_i ;
input  ps2_clk_i ;
input  ps2_data_i ;
input  ps2_data_i ;
output rx_extended;
 
output rx_released;
output rx_released;
output rx_shift_key_on;
 
output [7:0] rx_scan_code;
output [7:0] rx_scan_code;
output [7:0] rx_ascii;
 
output rx_data_ready;
output rx_data_ready;
input rx_read;
input rx_read;
input [7:0] tx_data;
input [7:0] tx_data;
input tx_write;
input tx_write;
output tx_write_ack_o;
output tx_write_ack_o;
output tx_error_no_keyboard_ack;
output tx_error_no_keyboard_ack;
input  translate ;
input  translate ;
 
 
reg rx_extended;
 
reg rx_released;
reg rx_released;
reg [7:0] rx_scan_code;
reg [7:0] rx_scan_code;
reg [7:0] rx_ascii;
 
reg rx_data_ready;
reg rx_data_ready;
reg tx_error_no_keyboard_ack;
reg tx_error_no_keyboard_ack;
 
 
// Internal signal declarations
// Internal signal declarations
wire timer_60usec_done;
wire timer_60usec_done;
wire timer_5usec_done;
wire timer_5usec_done;
wire extended;
 
wire released;
wire released;
wire shift_key_on;
 
 
 
                         // NOTE: These two signals used to be one.  They
                         // NOTE: These two signals used to be one.  They
                         //       were split into two signals because of
                         //       were split into two signals because of
                         //       shift key trapping.  With shift key
                         //       shift key trapping.  With shift key
                         //       trapping, no event is generated externally,
                         //       trapping, no event is generated externally,
Line 228... Line 213...
wire rx_output_strobe;   // Used to produce the actual output.
wire rx_output_strobe;   // Used to produce the actual output.
 
 
wire tx_parity_bit;
wire tx_parity_bit;
wire rx_shifting_done;
wire rx_shifting_done;
wire tx_shifting_done;
wire tx_shifting_done;
wire [11:0] shift_key_plus_code;
 
 
 
reg [`TOTAL_BITS-1:0] q;
reg [`TOTAL_BITS-1:0] q;
reg [3:0] m1_state;
reg [3:0] m1_state;
reg [3:0] m1_next_state;
reg [3:0] m1_next_state;
reg m2_state;
reg m2_state;
Line 240... Line 224...
reg [3:0] bit_count;
reg [3:0] bit_count;
reg enable_timer_60usec;
reg enable_timer_60usec;
reg enable_timer_5usec;
reg enable_timer_5usec;
reg [TIMER_60USEC_BITS_PP-1:0] timer_60usec_count;
reg [TIMER_60USEC_BITS_PP-1:0] timer_60usec_count;
reg [TIMER_5USEC_BITS_PP-1:0] timer_5usec_count;
reg [TIMER_5USEC_BITS_PP-1:0] timer_5usec_count;
reg [7:0] ascii;      // "REG" type only because a case statement is used.
 
reg left_shift_key;
 
reg right_shift_key;
 
reg hold_extended;    // Holds prior value, cleared at rx_output_strobe
 
reg hold_released;    // Holds prior value, cleared at rx_output_strobe
reg hold_released;    // Holds prior value, cleared at rx_output_strobe
reg ps2_clk_s;        // Synchronous version of this input
reg ps2_clk_s;        // Synchronous version of this input
reg ps2_data_s;       // Synchronous version of this input
reg ps2_data_s;       // Synchronous version of this input
reg ps2_clk_hi_z;     // Without keyboard, high Z equals 1 due to pullups.
reg ps2_clk_hi_z;     // Without keyboard, high Z equals 1 due to pullups.
reg ps2_data_hi_z;    // Without keyboard, high Z equals 1 due to pullups.
reg ps2_data_hi_z;    // Without keyboard, high Z equals 1 due to pullups.
Line 500... Line 480...
assign timer_5usec_done = (timer_5usec_count == TIMER_5USEC_VALUE_PP - 1);
assign timer_5usec_done = (timer_5usec_count == TIMER_5USEC_VALUE_PP - 1);
 
 
 
 
// Create the signals which indicate special scan codes received.
// Create the signals which indicate special scan codes received.
// These are the "unlatched versions."
// These are the "unlatched versions."
`ifdef PS2_TRAP_EXTENDED
 
assign extended = (q[8:1] == `EXTEND_CODE) && rx_shifting_done && translate ;
 
`else
 
assign extended = 1'b0 ;
 
`endif
 
assign released = (q[8:1] == `RELEASE_CODE) && rx_shifting_done && translate ;
assign released = (q[8:1] == `RELEASE_CODE) && rx_shifting_done && translate ;
 
 
// Store the special scan code status bits
// Store the special scan code status bits
// Not the final output, but an intermediate storage place,
// Not the final output, but an intermediate storage place,
// until the entire set of output data can be assembled.
// until the entire set of output data can be assembled.
always @(posedge clk)
always @(posedge clk)
begin
begin
  if (reset || rx_output_event)
  if (reset || rx_output_event)
  begin
  begin
    hold_extended <= 0;
 
    hold_released <= 0;
    hold_released <= 0;
  end
  end
  else
  else
  begin
  begin
    if (rx_shifting_done && extended) hold_extended <= 1;
 
    if (rx_shifting_done && released) hold_released <= 1;
    if (rx_shifting_done && released) hold_released <= 1;
  end
  end
end
end
 
 
 
 
// These bits contain the status of the two shift keys
 
always @(posedge clk)
 
begin
 
  if (reset) left_shift_key <= 0;
 
  else if ((q[8:1] == `LEFT_SHIFT) && rx_shifting_done && ~hold_released)
 
    left_shift_key <= 1;
 
  else if ((q[8:1] == `LEFT_SHIFT) && rx_shifting_done && hold_released)
 
    left_shift_key <= 0;
 
end
 
 
 
always @(posedge clk)
 
begin
 
  if (reset) right_shift_key <= 0;
 
  else if ((q[8:1] == `RIGHT_SHIFT) && rx_shifting_done && ~hold_released)
 
    right_shift_key <= 1;
 
  else if ((q[8:1] == `RIGHT_SHIFT) && rx_shifting_done && hold_released)
 
    right_shift_key <= 0;
 
end
 
 
 
assign rx_shift_key_on = left_shift_key || right_shift_key;
 
 
 
// Output the special scan code flags, the scan code and the ascii
// Output the special scan code flags, the scan code and the ascii
always @(posedge clk)
always @(posedge clk)
begin
begin
  if (reset)
  if (reset)
  begin
  begin
    rx_extended <= 0;
 
    rx_released <= 0;
    rx_released <= 0;
    rx_scan_code <= 0;
    rx_scan_code <= 0;
    rx_ascii <= 0;
 
  end
  end
  else if (rx_output_strobe)
  else if (rx_output_strobe)
  begin
  begin
    rx_extended <= hold_extended;
 
    rx_released <= hold_released;
    rx_released <= hold_released;
    rx_scan_code <= q[8:1];
    rx_scan_code <= q[8:1];
    rx_ascii <= ascii;
 
  end
  end
end
end
 
 
// Store the final rx output data only when all extend and release codes
// Store the final rx output data only when all extend and release codes
// are received and the next (actual key) scan code is also ready.
// are received and the next (actual key) scan code is also ready.
// (the presence of rx_extended or rx_released refers to the
// (the presence of rx_extended or rx_released refers to the
// the current latest scan code received, not the previously latched flags.)
// the current latest scan code received, not the previously latched flags.)
assign rx_output_event  = (rx_shifting_done
assign rx_output_event  = (rx_shifting_done
                          && ~extended
 
                          && ~released
                          && ~released
                          );
                          );
 
 
assign rx_output_strobe = (rx_shifting_done
assign rx_output_strobe = (rx_shifting_done
                          && ~extended
 
                          && ~released
                          && ~released
                          && ( (TRAP_SHIFT_KEYS_PP == 0)
 
                               || ( (q[8:1] != `RIGHT_SHIFT)
 
                                    &&(q[8:1] != `LEFT_SHIFT)
 
                                  )
 
                             )
 
                          );
                          );
 
 
// This part translates the scan code into an ASCII value...
 
// Only the ASCII codes which I considered important have been included.
 
// if you want more, just add the appropriate case statement lines...
 
// (You will need to know the keyboard scan codes you wish to assign.)
 
// The entries are listed in ascending order of ASCII value.
 
assign shift_key_plus_code = {3'b0,rx_shift_key_on,q[8:1]};
 
always @(shift_key_plus_code)
 
begin
 
  casez (shift_key_plus_code)
 
    12'h?66 : ascii <= 8'h08;  // Backspace ("backspace" key)
 
    12'h?0d : ascii <= 8'h09;  // Horizontal Tab
 
    12'h?5a : ascii <= 8'h0d;  // Carriage return ("enter" key)
 
    12'h?76 : ascii <= 8'h1b;  // Escape ("esc" key)
 
    12'h?29 : ascii <= 8'h20;  // Space
 
    12'h116 : ascii <= 8'h21;  // !
 
    12'h152 : ascii <= 8'h22;  // "
 
    12'h126 : ascii <= 8'h23;  // #
 
    12'h125 : ascii <= 8'h24;  // $
 
    12'h12e : ascii <= 8'h25;  // %
 
    12'h13d : ascii <= 8'h26;  // &
 
    12'h052 : ascii <= 8'h27;  // '
 
    12'h146 : ascii <= 8'h28;  // (
 
    12'h145 : ascii <= 8'h29;  // )
 
    12'h13e : ascii <= 8'h2a;  // *
 
    12'h155 : ascii <= 8'h2b;  // +
 
    12'h041 : ascii <= 8'h2c;  // ,
 
    12'h04e : ascii <= 8'h2d;  // -
 
    12'h049 : ascii <= 8'h2e;  // .
 
    12'h04a : ascii <= 8'h2f;  // /
 
    12'h045 : ascii <= 8'h30;  // 0
 
    12'h016 : ascii <= 8'h31;  // 1
 
    12'h01e : ascii <= 8'h32;  // 2
 
    12'h026 : ascii <= 8'h33;  // 3
 
    12'h025 : ascii <= 8'h34;  // 4
 
    12'h02e : ascii <= 8'h35;  // 5
 
    12'h036 : ascii <= 8'h36;  // 6
 
    12'h03d : ascii <= 8'h37;  // 7
 
    12'h03e : ascii <= 8'h38;  // 8
 
    12'h046 : ascii <= 8'h39;  // 9
 
    12'h14c : ascii <= 8'h3a;  // :
 
    12'h04c : ascii <= 8'h3b;  // ;
 
    12'h141 : ascii <= 8'h3c;  // <
 
    12'h055 : ascii <= 8'h3d;  // =
 
    12'h149 : ascii <= 8'h3e;  // >
 
    12'h14a : ascii <= 8'h3f;  // ?
 
    12'h11e : ascii <= 8'h40;  // @
 
    12'h11c : ascii <= 8'h41;  // A
 
    12'h132 : ascii <= 8'h42;  // B
 
    12'h121 : ascii <= 8'h43;  // C
 
    12'h123 : ascii <= 8'h44;  // D
 
    12'h124 : ascii <= 8'h45;  // E
 
    12'h12b : ascii <= 8'h46;  // F
 
    12'h134 : ascii <= 8'h47;  // G
 
    12'h133 : ascii <= 8'h48;  // H
 
    12'h143 : ascii <= 8'h49;  // I
 
    12'h13b : ascii <= 8'h4a;  // J
 
    12'h142 : ascii <= 8'h4b;  // K
 
    12'h14b : ascii <= 8'h4c;  // L
 
    12'h13a : ascii <= 8'h4d;  // M
 
    12'h131 : ascii <= 8'h4e;  // N
 
    12'h144 : ascii <= 8'h4f;  // O
 
    12'h14d : ascii <= 8'h50;  // P
 
    12'h115 : ascii <= 8'h51;  // Q
 
    12'h12d : ascii <= 8'h52;  // R
 
    12'h11b : ascii <= 8'h53;  // S
 
    12'h12c : ascii <= 8'h54;  // T
 
    12'h13c : ascii <= 8'h55;  // U
 
    12'h12a : ascii <= 8'h56;  // V
 
    12'h11d : ascii <= 8'h57;  // W
 
    12'h122 : ascii <= 8'h58;  // X
 
    12'h135 : ascii <= 8'h59;  // Y
 
    12'h11a : ascii <= 8'h5a;  // Z
 
    12'h054 : ascii <= 8'h5b;  // [
 
    12'h05d : ascii <= 8'h5c;  // \
 
    12'h05b : ascii <= 8'h5d;  // ]
 
    12'h136 : ascii <= 8'h5e;  // ^
 
    12'h14e : ascii <= 8'h5f;  // _    
 
    12'h00e : ascii <= 8'h60;  // `
 
    12'h01c : ascii <= 8'h61;  // a
 
    12'h032 : ascii <= 8'h62;  // b
 
    12'h021 : ascii <= 8'h63;  // c
 
    12'h023 : ascii <= 8'h64;  // d
 
    12'h024 : ascii <= 8'h65;  // e
 
    12'h02b : ascii <= 8'h66;  // f
 
    12'h034 : ascii <= 8'h67;  // g
 
    12'h033 : ascii <= 8'h68;  // h
 
    12'h043 : ascii <= 8'h69;  // i
 
    12'h03b : ascii <= 8'h6a;  // j
 
    12'h042 : ascii <= 8'h6b;  // k
 
    12'h04b : ascii <= 8'h6c;  // l
 
    12'h03a : ascii <= 8'h6d;  // m
 
    12'h031 : ascii <= 8'h6e;  // n
 
    12'h044 : ascii <= 8'h6f;  // o
 
    12'h04d : ascii <= 8'h70;  // p
 
    12'h015 : ascii <= 8'h71;  // q
 
    12'h02d : ascii <= 8'h72;  // r
 
    12'h01b : ascii <= 8'h73;  // s
 
    12'h02c : ascii <= 8'h74;  // t
 
    12'h03c : ascii <= 8'h75;  // u
 
    12'h02a : ascii <= 8'h76;  // v
 
    12'h01d : ascii <= 8'h77;  // w
 
    12'h022 : ascii <= 8'h78;  // x
 
    12'h035 : ascii <= 8'h79;  // y
 
    12'h01a : ascii <= 8'h7a;  // z
 
    12'h154 : ascii <= 8'h7b;  // {
 
    12'h15d : ascii <= 8'h7c;  // |
 
    12'h15b : ascii <= 8'h7d;  // }
 
    12'h10e : ascii <= 8'h7e;  // ~
 
    12'h?71 : ascii <= 8'h7f;  // (Delete OR DEL on numeric keypad)
 
    default : ascii <= 8'h2e;  // '.' used for unlisted characters.
 
  endcase
 
end
 
 
 
 
 
endmodule
endmodule
 
 
//`undefine TOTAL_BITS
//`undefine TOTAL_BITS
//`undefine EXTEND_CODE
//`undefine EXTEND_CODE
//`undefine RELEASE_CODE
//`undefine RELEASE_CODE

powered by: WebSVN 2.1.0

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