SPIreader.v 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /*
  2. * Reads SPI flash module
  3. * Enables quad spi mode with coninous mode on
  4. * Reads instructions of 32 bits
  5. */
  6. module SPIreader (
  7. input clk, reset,
  8. output cs,
  9. input [23:0] address,
  10. output [31:0] instr,
  11. input start,
  12. output reg initDone = 1'b0,
  13. output reg recvDone = 1'b0,
  14. output write,
  15. output spi_clk,
  16. output io0_out, io1_out, io2_out, io3_out, //d, q wp, hold
  17. input io0_in, io1_in, io2_in, io3_in //d, q wp, hold
  18. );
  19. wire [23:0] a = {address, 2'b0};
  20. reg clkDiv = 1'b0;
  21. reg [7:0] b0 = 8'd0;
  22. reg [7:0] b1 = 8'd0;
  23. reg [7:0] b2 = 8'd0;
  24. reg [7:0] b3 = 8'd0;
  25. reg [6:0] counter = 7'd0;
  26. reg [2:0] phase = 3'd0;
  27. wire rising = clkDiv == 1'b1;
  28. wire falling = clkDiv == 1'b0;
  29. assign spi_clk = rising;
  30. /*
  31. 0 = initial wait (goto 5)
  32. 1 = send quad fast read opcode (goto 3)
  33. 2 = idle - ready to read
  34. 3 = send address, continuous mode bits and dummy bits
  35. 4 = receive 32 bits (goto 2)
  36. 5 = reset continuous mode
  37. 6 = wait after reset (goto 1)
  38. */
  39. //COMMANDS
  40. wire [7:0] opcode = 8'hEB;
  41. wire [11:0] addr_io0 = {a[20], a[16], a[12], a[8], a[4], a[0], 2'b00, 4'b0000};
  42. wire [11:0] addr_io1 = {a[21], a[17], a[13], a[9], a[5], a[1], 2'b10, 4'b0000};
  43. wire [11:0] addr_io2 = {a[22], a[18], a[14], a[10], a[6], a[2], 2'b00, 4'b0000};
  44. wire [11:0] addr_io3 = {a[23], a[19], a[15], a[11], a[7], a[3], 2'b00, 4'b0000};
  45. assign write = (phase == 5) ? 1'b1 :
  46. (phase == 1) ? 1'b1 :
  47. (phase == 3) ? 1'b1 :
  48. 1'b0;
  49. assign cs = (phase == 1) ? 1'b0 :
  50. (phase == 3) ? 1'b0 :
  51. (phase == 4) ? 1'b0 :
  52. (phase == 5) ? 1'b0 :
  53. 1'b1;
  54. //d
  55. assign io0_out = (phase == 5) ? 1'b1 :
  56. (phase == 1) ? opcode[7-counter] :
  57. (phase == 3) ? addr_io0[11-counter] :
  58. 1'b0;
  59. //q
  60. assign io1_out = (phase == 1) ? 1'b1 :
  61. (phase == 3) ? addr_io1[11-counter] :
  62. 1'b0;
  63. //wp
  64. assign io2_out = (phase == 1) ? 1'b1 :
  65. (phase == 3) ? addr_io2[11-counter] :
  66. 1'b0;
  67. //hold
  68. assign io3_out = (phase == 1) ? 1'b1 :
  69. (phase == 3) ? addr_io3[11-counter] :
  70. 1'b0;
  71. //mapping read data to instruction
  72. assign instr = {
  73. b3[7], b2[7], b1[7], b0[7], b3[6], b2[6], b1[6], b0[6],
  74. b3[5], b2[5], b1[5], b0[5], b3[4], b2[4], b1[4], b0[4],
  75. b3[3], b2[3], b1[3], b0[3], b3[2], b2[2], b1[2], b0[2],
  76. b3[1], b2[1], b1[1], b0[1], b3[0], b2[0], b1[0], b0[0]
  77. };
  78. always @(posedge clk)
  79. begin
  80. if (reset)
  81. begin
  82. phase <= 3'd0;
  83. counter <= 7'd0;
  84. initDone <= 1'd0;
  85. clkDiv <= 1'b0;
  86. b0 <= 8'd0;
  87. b1 <= 8'd0;
  88. b2 <= 8'd0;
  89. b3 <= 8'd0;
  90. recvDone <= 1'b0;
  91. end
  92. else
  93. begin
  94. clkDiv <= clkDiv + 1'b1;
  95. if (rising)
  96. begin
  97. case (phase)
  98. //initial state,
  99. 3'd0:
  100. begin
  101. if (counter == 7'd3)
  102. begin
  103. counter <= 7'd0;
  104. phase <= 5;
  105. end
  106. else begin
  107. counter <= counter + 1'b1;
  108. end
  109. end
  110. //send quad fast read opcode
  111. 3'd1:
  112. begin
  113. if (counter == 7'd7)
  114. begin
  115. counter <= 7'd0;
  116. phase <= 3;
  117. end
  118. else begin
  119. counter <= counter + 1'b1;
  120. end
  121. end
  122. //idle - ready to read when triggered (after some instruction delay)
  123. 3'd2:
  124. begin
  125. recvDone <= 1'b0;
  126. if (counter == 7'd4) //could be 3, but one extra cycle delay to wait for start from MU to go low
  127. begin
  128. initDone <= 1'b1;
  129. if (start)
  130. begin
  131. counter <= 7'd0;
  132. phase <= 3'd3;
  133. end
  134. end
  135. else begin
  136. counter <= counter + 1'b1;
  137. end
  138. end
  139. //send address, continuous mode bits and dummy bits
  140. 3'd3:
  141. begin
  142. if (counter == 7'd11)
  143. begin
  144. counter <= 7'd0;
  145. phase <= 3'd4;
  146. end
  147. else begin
  148. counter <= counter + 1'b1;
  149. end
  150. end
  151. //receive 32 bits
  152. 3'd4:
  153. begin
  154. if (counter == 7'd7)
  155. begin
  156. counter <= 7'd0;
  157. phase <= 3'd7;
  158. end
  159. else begin
  160. counter <= counter + 1'b1;
  161. end
  162. end
  163. //reset
  164. 3'd5:
  165. begin
  166. if (counter == 7)
  167. begin
  168. counter <= 7'd0;
  169. phase <= 3'd6;
  170. end
  171. else begin
  172. counter <= counter + 1'b1;
  173. end
  174. end
  175. //wait after reset
  176. 3'd6:
  177. begin
  178. if (counter == 7'd3)
  179. begin
  180. counter <= 7'd0;
  181. phase <= 3'd1;
  182. end
  183. else begin
  184. counter <= counter + 1'b1;
  185. end
  186. end
  187. // recvDone
  188. 3'd7:
  189. begin
  190. recvDone <= 1'b1;
  191. phase <= 3'd2;
  192. end
  193. default:
  194. begin
  195. phase <= 3'd0;
  196. end
  197. endcase
  198. end
  199. if (falling)
  200. begin
  201. if (phase == 3'd4)
  202. begin
  203. b0[7-counter] <= io0_in;
  204. b1[7-counter] <= io1_in;
  205. b2[7-counter] <= io2_in;
  206. b3[7-counter] <= io3_in;
  207. end
  208. end
  209. end
  210. end
  211. endmodule