1
0

NESpadReader.v 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * Communicates with SNES (and probably also NES) controller
  3. * Based on https://opencores.org/projects/nescontroller by Yvo Zoer
  4. * with modifications to make it work for a single SNES controller
  5. * and to make the interface work nicer with the MU
  6. */
  7. module NESpadReader (
  8. input clk,
  9. input reset,
  10. input frame, //start
  11. output reg nesl = 1'b0,
  12. output reg nesc = 1'b0,
  13. input nesd,
  14. output reg [15:0] nesState = 16'd0,
  15. output done
  16. );
  17. // states for state-machine
  18. parameter STATE_IDLE = 3'd0;
  19. parameter STATE_LATCH_HI = 3'd1;
  20. parameter STATE_LATCH_LO = 3'd2;
  21. parameter STATE_CLOCK_LO = 3'd3;
  22. parameter STATE_CLOCK_HI = 3'd4;
  23. parameter STATE_DONE = 3'd5;
  24. assign done = (state == STATE_DONE);
  25. // start bit to catch single clock frame event
  26. reg start = 1'b0;
  27. always @(posedge clk)
  28. if (reset)
  29. start <= 1'b0;
  30. else if ( frame )
  31. start <= 1'b1;
  32. else if ( state != STATE_IDLE )
  33. start <= 1'b0;
  34. // clock divider / enable -- clock needs to be around 1.5mhz or lower
  35. reg [5:0] clkdiv = 6'd0;
  36. always @(posedge clk)
  37. if (reset)
  38. clkdiv <= 6'd0;
  39. else
  40. clkdiv <= clkdiv + 1'd1;
  41. wire enable = &clkdiv;
  42. // main state machine
  43. reg [2:0] state = 3'd0;
  44. reg [2:0] next_state = 3'd0;
  45. always @(*)
  46. case (state)
  47. STATE_IDLE : begin
  48. if ( start )
  49. next_state = STATE_LATCH_HI;
  50. else
  51. next_state = STATE_IDLE;
  52. end
  53. STATE_LATCH_HI : next_state = STATE_LATCH_LO;
  54. STATE_LATCH_LO : next_state = STATE_CLOCK_LO;
  55. STATE_CLOCK_LO : next_state = STATE_CLOCK_HI;
  56. STATE_CLOCK_HI : begin
  57. if ( &count )
  58. begin
  59. next_state = STATE_DONE;
  60. end
  61. else
  62. next_state = STATE_CLOCK_LO;
  63. end
  64. STATE_DONE : begin
  65. next_state = STATE_IDLE;
  66. end
  67. default : begin
  68. next_state = STATE_IDLE;
  69. end
  70. endcase
  71. always @(posedge clk)
  72. if (reset)
  73. nesl <= 1'b0;
  74. else
  75. nesl <= (state == STATE_LATCH_HI);
  76. always @(posedge clk)
  77. if (reset)
  78. nesc <= 1'b1;
  79. else
  80. nesc = (state == STATE_CLOCK_LO ) ? 1'b0 : 1'b1;
  81. reg [3:0] count = 4'd0;
  82. reg [3:0] next_count = 4'd0;
  83. always @(*)
  84. if ( state == STATE_CLOCK_HI )
  85. next_count = count + 4'd1;
  86. else
  87. next_count = count;
  88. reg [15:0] next_nesState = 16'd0;
  89. always @(*)
  90. if ( state == STATE_CLOCK_LO )
  91. begin
  92. next_nesState = { nesState[14:0], nesd };
  93. end
  94. else
  95. begin
  96. next_nesState = nesState;
  97. end
  98. always @(posedge clk)
  99. if (reset)
  100. begin
  101. state <= STATE_IDLE;
  102. count <= 4'd0;
  103. nesState <= 16'd0;
  104. end
  105. else if ( enable )
  106. begin
  107. state <= next_state;
  108. count <= next_count;
  109. nesState <= next_nesState;
  110. end
  111. endmodule