Keyboard.v 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*
  2. * Reads PS/2 keyboard keycodes sends interrupt when one is received for one tick
  3. * Code is practically copied from "https://embeddedthoughts.com/2016/07/05/fpga-keyboard-interface/"
  4. */
  5. module Keyboard
  6. (
  7. input wire clk, reset,
  8. input wire ps2d, ps2c, // ps2 data and clock inputs
  9. output reg rx_done_tick, // ps2 receive done tick
  10. output wire [7:0] rx_data // data received
  11. );
  12. // FSMD state declaration
  13. localparam
  14. idle = 1'b0,
  15. rx = 1'b1;
  16. // internal signal declaration
  17. reg state_reg, state_next; // FSMD state register
  18. reg [7:0] filter_reg; // shift register filter for ps2c
  19. wire [7:0] filter_next; // next state value of ps2c filter register
  20. reg f_val_reg; // reg for ps2c filter value, either 1 or 0
  21. wire f_val_next; // next state for ps2c filter value
  22. reg [3:0] n_reg, n_next; // register to keep track of bit number
  23. reg [10:0] d_reg, d_next; // register to shift in rx data
  24. wire neg_edge; // negative edge of ps2c clock filter value
  25. // register for ps2c filter register and filter value
  26. always @(posedge clk)
  27. if (reset)
  28. begin
  29. filter_reg <= 8'd0;
  30. f_val_reg <= 1'b0;
  31. end
  32. else
  33. begin
  34. filter_reg <= filter_next;
  35. f_val_reg <= f_val_next;
  36. end
  37. // next state value of ps2c filter: right shift in current ps2c value to register
  38. assign filter_next = {ps2c, filter_reg[7:1]};
  39. // filter value next state, 1 if all bits are 1, 0 if all bits are 0, else no change
  40. assign f_val_next = (filter_reg == 8'b11111111) ? 1'b1 :
  41. (filter_reg == 8'b00000000) ? 1'b0 :
  42. f_val_reg;
  43. // negative edge of filter value: if current value is 1, and next state value is 0
  44. assign neg_edge = f_val_reg & ~f_val_next;
  45. // FSMD state, bit number, and data registers
  46. always @(posedge clk)
  47. if (reset)
  48. begin
  49. state_reg <= idle;
  50. n_reg <= 4'd0;
  51. d_reg <= 11'd0;
  52. end
  53. else
  54. begin
  55. state_reg <= state_next;
  56. n_reg <= n_next;
  57. d_reg <= d_next;
  58. end
  59. // FSMD next state logic
  60. always @*
  61. begin
  62. // defaults
  63. state_next = state_reg;
  64. rx_done_tick = 1'b0;
  65. n_next = n_reg;
  66. d_next = d_reg;
  67. case (state_reg)
  68. idle:
  69. if (neg_edge) // start bit received
  70. begin
  71. n_next = 4'b1010; // set bit count down to 10
  72. state_next = rx; // go to rx state
  73. end
  74. rx: // shift in 8 data, 1 parity, and 1 stop bit
  75. begin
  76. if (neg_edge) // if ps2c negative edge...
  77. begin
  78. d_next = {ps2d, d_reg[10:1]}; // sample ps2d, right shift into data register
  79. n_next = n_reg - 1'b1; // decrement bit count
  80. end
  81. if (n_reg == 4'd0) // after 10 bits shifted in, go to done state
  82. begin
  83. rx_done_tick = 1'b1; // assert dat received done tick
  84. state_next = idle; // go back to idle
  85. end
  86. end
  87. endcase
  88. end
  89. assign rx_data = d_reg[8:1]; // output data bits
  90. endmodule