You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

312 lines
9.2 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. module spi_reg_reader (
  2. input clk, //clock input
  3. input rst_n, //asynchronous reset input, low active
  4. //regbus interface
  5. output reg [31:0] addr,
  6. output reg [31:0] wr_data,
  7. output reg wr_en,
  8. input wire [31:0] rd_data, //received serial data
  9. //
  10. input wire spi_cs_pin, //
  11. input wire spi_clk_pin, //
  12. input wire spi_rx_pin, //
  13. output reg spi_tx_pin
  14. );
  15. parameter STATE_IDLE = 0;
  16. parameter STATE_RECEIVE_ADD = 1;
  17. parameter STATE_READ_REG = 2;
  18. parameter STATE_TRANSMIT_DATA = 3;
  19. parameter STATE_RECEIVE_DATA = 4;
  20. parameter STATE_WRITE_REG = 5;
  21. parameter ADDRESS_WIDTH_BYTE_NUM = 2;
  22. zutils_signal_filter #(.FILTER_COUNT(2)) cs_filter (
  23. .clk(clk),
  24. .rst_n(rst_n),
  25. .in(spi_cs_pin),
  26. .out(spi_cs_pin_after_filter)
  27. );
  28. zutils_signal_filter #(.FILTER_COUNT(2)) clk_filter (
  29. .clk(clk),
  30. .rst_n(rst_n),
  31. .in(spi_clk_pin),
  32. .out(spi_clk_pin_after_filter)
  33. );
  34. zutils_signal_filter #(.FILTER_COUNT(2)) spi_rx_filter (
  35. .clk(clk),
  36. .rst_n(rst_n),
  37. .in(spi_rx_pin),
  38. .out(spi_rx_pin_after_filter)
  39. );
  40. //
  41. // 捕获SPI_CS的下降沿 SPI_CLK的上升沿
  42. // detect:
  43. // spi_cs_negedge_tri
  44. // spi_clk_posedge_tri
  45. //
  46. reg spi_cs_last_state = 0;
  47. reg spi_clk_last_state = 0;
  48. assign spi_clk_posedge_tri = spi_clk_pin_after_filter & ~spi_clk_last_state;
  49. assign spi_clk_negedge_tri = ~spi_clk_pin_after_filter & spi_clk_last_state;
  50. always @(posedge clk or negedge rst_n) begin
  51. if (!rst_n) begin
  52. spi_cs_last_state <= 1;
  53. spi_clk_last_state <= 1;
  54. end else begin
  55. spi_cs_last_state <= spi_cs_pin_after_filter;
  56. spi_clk_last_state <= spi_clk_pin_after_filter;
  57. end
  58. end
  59. /*******************************************************************************
  60. * SPI数据解析及其部分状态更新 *
  61. *******************************************************************************/
  62. //
  63. //
  64. //
  65. // cs : ----______________________________________________
  66. // clk : ----------____----____----____----____----____----
  67. // bitcnt : 0 1 2 ... 7 0
  68. // rx : . . . . .
  69. // tx : <======><======><======><======><======>
  70. // valid : .
  71. // byte_cnt: 0 1
  72. //
  73. reg [7:0] bit_cnt = 0;
  74. reg first_edge = 1;
  75. // first_edge 状态更新
  76. // 1:在spi_cs下降沿时候更新为0
  77. // 2:复位时候更新为1
  78. // bit_cnt 状态更新
  79. // 1:在spi_clk下降沿时候更新
  80. // 2:first_edge == 1时候更新
  81. //
  82. always @(posedge clk or negedge rst_n) begin
  83. if (!rst_n) begin
  84. bit_cnt <= 0;
  85. first_edge <= 1;
  86. end else begin
  87. if (spi_cs_pin_after_filter) begin
  88. bit_cnt <= 0;
  89. first_edge <= 1;
  90. end else begin
  91. if (spi_clk_negedge_tri) begin
  92. if (first_edge) begin
  93. bit_cnt <= 0;
  94. first_edge <= 0;
  95. end else begin
  96. if (bit_cnt == 7) bit_cnt <= 0;
  97. else bit_cnt <= bit_cnt + 1;
  98. end
  99. end
  100. end
  101. end
  102. end
  103. //
  104. // byte_cnt
  105. // 1:在spi_clk下降沿时候更新
  106. // 2:在bit_cnt == 7时候更新
  107. //
  108. reg [7:0] spi_byte_cnt = 0; //byte_cnt
  109. always @(posedge clk or negedge rst_n) begin
  110. if (!rst_n) begin
  111. spi_byte_cnt <= 0;
  112. end else begin
  113. if (spi_cs_pin_after_filter) begin
  114. spi_byte_cnt <= 0;
  115. end else begin
  116. if (spi_clk_negedge_tri && bit_cnt == 7) begin
  117. spi_byte_cnt <= spi_byte_cnt + 1;
  118. end
  119. end
  120. end
  121. end
  122. //
  123. // spi_tx_1byte_data 发送
  124. //
  125. reg [7:0] spi_tx_1byte_data = 0;
  126. always @(*) begin
  127. spi_tx_pin <= spi_tx_1byte_data[bit_cnt];
  128. end
  129. //
  130. // spi_rx_1byte_data
  131. // spi_rx_1byte_data_valid
  132. //
  133. reg [7:0] spi_rx_1byte_data = 0;
  134. reg spi_rx_1byte_data_valid = 0;
  135. always @(posedge clk or negedge rst_n) begin
  136. if (!rst_n) begin
  137. spi_rx_1byte_data <= 0;
  138. spi_rx_1byte_data_valid <= 0;
  139. end else begin
  140. if (spi_cs_pin_after_filter) begin
  141. spi_rx_1byte_data <= 0;
  142. spi_rx_1byte_data_valid <= 0;
  143. end else begin
  144. if (spi_clk_posedge_tri) begin
  145. spi_rx_1byte_data[bit_cnt] <= spi_rx_pin_after_filter;
  146. end
  147. if (spi_clk_negedge_tri && bit_cnt == 7) spi_rx_1byte_data_valid <= 1;
  148. else spi_rx_1byte_data_valid <= 0;
  149. end
  150. end
  151. end
  152. /*******************************************************************************
  153. * 缓存接收到的数据 *
  154. *******************************************************************************/
  155. reg [7:0] spi_rx_data_cache [0:4+4-1];
  156. reg [7:0] rx_byte_count = 0;
  157. genvar i;
  158. always @(posedge clk or negedge rst_n) begin
  159. if (!rst_n) begin
  160. rx_byte_count <= 0;
  161. spi_rx_data_cache[0] <= 0;
  162. spi_rx_data_cache[1] <= 0;
  163. spi_rx_data_cache[2] <= 0;
  164. spi_rx_data_cache[3] <= 0;
  165. spi_rx_data_cache[4] <= 0;
  166. spi_rx_data_cache[5] <= 0;
  167. spi_rx_data_cache[6] <= 0;
  168. spi_rx_data_cache[7] <= 0;
  169. end else begin
  170. if (spi_cs_pin_after_filter) begin
  171. // 失能状态
  172. rx_byte_count <= 0;
  173. spi_rx_data_cache[0] <= 0;
  174. spi_rx_data_cache[1] <= 0;
  175. spi_rx_data_cache[2] <= 0;
  176. spi_rx_data_cache[3] <= 0;
  177. spi_rx_data_cache[4] <= 0;
  178. spi_rx_data_cache[5] <= 0;
  179. spi_rx_data_cache[6] <= 0;
  180. spi_rx_data_cache[7] <= 0;
  181. end else begin
  182. // 选中状态
  183. if (spi_rx_1byte_data_valid) begin
  184. rx_byte_count <= rx_byte_count + 1;
  185. if (rx_byte_count < ADDRESS_WIDTH_BYTE_NUM + 4) begin
  186. spi_rx_data_cache[rx_byte_count] <= spi_rx_1byte_data;
  187. end
  188. end
  189. end
  190. end
  191. end
  192. /*******************************************************************************
  193. * 自动设置SPI需要发送的数据 spi_tx_1byte_data *
  194. *******************************************************************************/
  195. always @(*) begin
  196. case (spi_byte_cnt)
  197. ADDRESS_WIDTH_BYTE_NUM + 0: spi_tx_1byte_data <= rd_data[7:0];
  198. ADDRESS_WIDTH_BYTE_NUM + 1: spi_tx_1byte_data <= rd_data[15:8];
  199. ADDRESS_WIDTH_BYTE_NUM + 2: spi_tx_1byte_data <= rd_data[23:16];
  200. ADDRESS_WIDTH_BYTE_NUM + 3: spi_tx_1byte_data <= rd_data[31:24];
  201. default: spi_tx_1byte_data <= 0;
  202. endcase
  203. end
  204. /*******************************************************************************
  205. * 自动设置addr数值 *
  206. *******************************************************************************/
  207. always @(*) begin
  208. case (ADDRESS_WIDTH_BYTE_NUM)
  209. 0: begin
  210. addr[7:0] <= 0;
  211. addr[15:8] <= 0;
  212. addr[23:16] <= 0;
  213. addr[31:24] <= 0;
  214. end
  215. 1: begin
  216. addr[7:0] <= {1'b0, spi_rx_data_cache[0][6:0]};
  217. addr[15:8] <= 0;
  218. addr[23:16] <= 0;
  219. addr[31:24] <= 0;
  220. end
  221. 2: begin
  222. addr[7:0] <= spi_rx_data_cache[0][7:0];
  223. addr[15:8] <= {1'b0, spi_rx_data_cache[1][6:0]};
  224. addr[23:16] <= 0;
  225. addr[31:24] <= 0;
  226. end
  227. 3: begin
  228. addr[7:0] <= spi_rx_data_cache[0][7:0];
  229. addr[15:8] <= spi_rx_data_cache[1][7:0];
  230. addr[23:16] <= {1'b0, spi_rx_data_cache[2][6:0]};
  231. addr[31:24] <= 0;
  232. end
  233. 4: begin
  234. addr[7:0] <= spi_rx_data_cache[0][7:0];
  235. addr[15:8] <= spi_rx_data_cache[1][7:0];
  236. addr[23:16] <= spi_rx_data_cache[2][7:0];
  237. addr[31:24] <= {1'b0, spi_rx_data_cache[3][6:0]};
  238. end
  239. endcase
  240. end
  241. /*******************************************************************************
  242. * wr_data *
  243. *******************************************************************************/
  244. always @(*) begin
  245. wr_data[7:0] <= spi_rx_data_cache[ADDRESS_WIDTH_BYTE_NUM];
  246. wr_data[15:8] <= spi_rx_data_cache[ADDRESS_WIDTH_BYTE_NUM+1];
  247. wr_data[23:16] <= spi_rx_data_cache[ADDRESS_WIDTH_BYTE_NUM+2];
  248. wr_data[31:24] <= spi_rx_data_cache[ADDRESS_WIDTH_BYTE_NUM+3];
  249. end
  250. /*******************************************************************************
  251. * wr_en *
  252. *******************************************************************************/
  253. reg has_trigger_wr_en = 0;
  254. always @(posedge clk or negedge rst_n) begin
  255. if (!rst_n) begin
  256. wr_en <= 0;
  257. has_trigger_wr_en <= 0;
  258. end else begin
  259. if (spi_cs_pin_after_filter) begin
  260. wr_en <= 0;
  261. has_trigger_wr_en <= 0;
  262. end else if (!spi_cs_pin_after_filter && //
  263. !has_trigger_wr_en && //
  264. spi_byte_cnt == ADDRESS_WIDTH_BYTE_NUM + 4 && //
  265. spi_rx_data_cache[ADDRESS_WIDTH_BYTE_NUM-1][7]) begin
  266. wr_en <= 1;
  267. has_trigger_wr_en <= 1;
  268. end else begin
  269. wr_en <= 0;
  270. end
  271. end
  272. end
  273. endmodule