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.

258 lines
7.8 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
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
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 [31:0] addr,
  6. output [31:0] wr_data,
  7. output 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 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. reg [31:0] addr = 0;
  23. reg [31:0] wr_data = 0;
  24. reg wr_en = 0;
  25. reg spi_tx_pin = 0;
  26. zutils_signal_filter #(
  27. .FILTER_COUNT(5)
  28. ) cs_filter (
  29. .clk(clk),
  30. .rst_n(rst_n),
  31. .in(spi_cs_pin),
  32. .out(spi_cs_pin_after_filter)
  33. );
  34. zutils_signal_filter #(
  35. .FILTER_COUNT(2)
  36. ) clk_filter (
  37. .clk(clk),
  38. .rst_n(rst_n),
  39. .in(spi_clk_pin),
  40. .out(spi_clk_pin_after_filter)
  41. );
  42. zutils_signal_filter #(
  43. .FILTER_COUNT(2)
  44. ) spi_rx_filter (
  45. .clk(clk),
  46. .rst_n(rst_n),
  47. .in(spi_rx_pin),
  48. .out(spi_rx_pin_after_filter)
  49. );
  50. //
  51. // 捕获SPI_CS的下降沿 SPI_CLK的上升沿
  52. // detect:
  53. // spi_cs_negedge_tri
  54. // spi_clk_posedge_tri
  55. //
  56. zutils_edge_detecter cs_edge_detecter (
  57. .clk(clk),
  58. .rst_n(rst_n),
  59. .in_signal(spi_cs_pin_after_filter),
  60. .in_signal_falling_edge(spi_cs_negedge_tri)
  61. );
  62. zutils_edge_detecter clk_edge_detecter (
  63. .clk(clk),
  64. .rst_n(rst_n),
  65. .in_signal(spi_clk_pin_after_filter),
  66. .in_signal_rising_edge(spi_clk_posedge_tri),
  67. .in_signal_falling_edge(spi_clk_negedge_tri)
  68. );
  69. /*******************************************************************************
  70. * SPI数据解析及其部分状态更新 *
  71. *******************************************************************************/
  72. //
  73. //
  74. //
  75. // cs : ----______________________________________________
  76. // clk : ----------____----____----____----____----____----
  77. // bitcnt : 0 1 2 ... 7 0
  78. // rx : . . . . .
  79. // tx : <======><======><======><======><======>
  80. // valid : .
  81. // byte_cnt: 0 1
  82. //
  83. wire [31:0] spi_clk_cnt;
  84. wire [31:0] spi_byte_cnt;
  85. wire [ 7:0] bit_cnt;
  86. zutils_clk_parser clk_parser (
  87. .clk (clk),
  88. .rst_n(rst_n),
  89. .cs_signal_in (spi_cs_pin_after_filter),
  90. .clk_signal_in(spi_clk_pin_after_filter),
  91. .clk_start_signal(spi_clk_start_signal),
  92. .clk_mid_signal(spi_clk_mid_signal),
  93. .clk_end_signal(spi_clk_end_signal),
  94. .clk_cnt(spi_clk_cnt), //[31:0]
  95. .byte_cnt(spi_byte_cnt), //[31:0]
  96. .clk_bit_cnt(bit_cnt) //[7:0]
  97. );
  98. //
  99. // spi_tx_1byte_data 发送
  100. //
  101. reg [7:0] spi_tx_1byte_data = 0;
  102. always @(*) begin
  103. spi_tx_pin <= spi_tx_1byte_data[bit_cnt];
  104. end
  105. //
  106. // spi_rx_1byte_data
  107. // spi_rx_1byte_data_valid
  108. //
  109. // 上升沿触发时,接收1bit数据
  110. // bit_cnt == 7时 接收完一byte数据
  111. //
  112. reg [7:0] spi_rx_1byte_data = 0;
  113. reg spi_rx_1byte_data_valid = 0;
  114. always @(posedge clk or negedge rst_n) begin
  115. if (!rst_n || spi_cs_pin_after_filter) begin
  116. spi_rx_1byte_data <= 0;
  117. spi_rx_1byte_data_valid <= 0;
  118. end else begin
  119. if (spi_clk_mid_signal) begin
  120. spi_rx_1byte_data[bit_cnt] <= spi_rx_pin_after_filter;
  121. if (bit_cnt == 7) spi_rx_1byte_data_valid <= 1;
  122. end else begin
  123. spi_rx_1byte_data_valid <= 0;
  124. end
  125. end
  126. end
  127. /*******************************************************************************
  128. * 缓存接收到的数据 *
  129. *******************************************************************************/
  130. reg [7:0] spi_rx_data_cache[0:7] = 0;
  131. genvar i;
  132. always @(posedge clk or negedge rst_n) begin
  133. if (!rst_n || spi_cs_pin_after_filter) begin
  134. spi_rx_data_cache[0] <= 0;
  135. spi_rx_data_cache[1] <= 0;
  136. spi_rx_data_cache[2] <= 0;
  137. spi_rx_data_cache[3] <= 0;
  138. spi_rx_data_cache[4] <= 0;
  139. spi_rx_data_cache[5] <= 0;
  140. spi_rx_data_cache[6] <= 0;
  141. spi_rx_data_cache[7] <= 0;
  142. end else begin
  143. // 选中状态
  144. if (spi_rx_1byte_data_valid && spi_byte_cnt <= 7) begin
  145. spi_rx_data_cache[spi_byte_cnt] <= spi_rx_1byte_data;
  146. end
  147. end
  148. end
  149. /*******************************************************************************
  150. * 自动设置SPI需要发送的数据 spi_tx_1byte_data *
  151. *******************************************************************************/
  152. always @(*) begin
  153. case (spi_byte_cnt)
  154. ADDRESS_WIDTH_BYTE_NUM + 0: spi_tx_1byte_data <= rd_data[7:0];
  155. ADDRESS_WIDTH_BYTE_NUM + 1: spi_tx_1byte_data <= rd_data[15:8];
  156. ADDRESS_WIDTH_BYTE_NUM + 2: spi_tx_1byte_data <= rd_data[23:16];
  157. ADDRESS_WIDTH_BYTE_NUM + 3: spi_tx_1byte_data <= rd_data[31:24];
  158. default: spi_tx_1byte_data <= 0;
  159. endcase
  160. end
  161. /*******************************************************************************
  162. * 自动设置addr数值 *
  163. *******************************************************************************/
  164. always @(*) begin
  165. case (ADDRESS_WIDTH_BYTE_NUM)
  166. 0: begin
  167. addr[7:0] <= 0;
  168. addr[15:8] <= 0;
  169. addr[23:16] <= 0;
  170. addr[31:24] <= 0;
  171. end
  172. 1: begin
  173. addr[7:0] <= {1'b0, spi_rx_data_cache[0][6:0]};
  174. addr[15:8] <= 0;
  175. addr[23:16] <= 0;
  176. addr[31:24] <= 0;
  177. end
  178. 2: begin
  179. addr[7:0] <= spi_rx_data_cache[0][7:0];
  180. addr[15:8] <= {1'b0, spi_rx_data_cache[1][6:0]};
  181. addr[23:16] <= 0;
  182. addr[31:24] <= 0;
  183. end
  184. 3: begin
  185. addr[7:0] <= spi_rx_data_cache[0][7:0];
  186. addr[15:8] <= spi_rx_data_cache[1][7:0];
  187. addr[23:16] <= {1'b0, spi_rx_data_cache[2][6:0]};
  188. addr[31:24] <= 0;
  189. end
  190. 4: begin
  191. addr[7:0] <= spi_rx_data_cache[0][7:0];
  192. addr[15:8] <= spi_rx_data_cache[1][7:0];
  193. addr[23:16] <= spi_rx_data_cache[2][7:0];
  194. addr[31:24] <= {1'b0, spi_rx_data_cache[3][6:0]};
  195. end
  196. endcase
  197. end
  198. /*******************************************************************************
  199. * wr_data *
  200. *******************************************************************************/
  201. always @(*) begin
  202. wr_data[7:0] <= spi_rx_data_cache[ADDRESS_WIDTH_BYTE_NUM];
  203. wr_data[15:8] <= spi_rx_data_cache[ADDRESS_WIDTH_BYTE_NUM+1];
  204. wr_data[23:16] <= spi_rx_data_cache[ADDRESS_WIDTH_BYTE_NUM+2];
  205. wr_data[31:24] <= spi_rx_data_cache[ADDRESS_WIDTH_BYTE_NUM+3];
  206. end
  207. /*******************************************************************************
  208. * wr_en *
  209. *******************************************************************************/
  210. reg has_trigger_wr_en = 0;
  211. always @(posedge clk or negedge rst_n) begin
  212. if (!rst_n || spi_cs_pin_after_filter) begin
  213. wr_en <= 0;
  214. has_trigger_wr_en <= 0;
  215. end else begin
  216. if (!has_trigger_wr_en && //
  217. spi_byte_cnt == ADDRESS_WIDTH_BYTE_NUM + 4 && //
  218. spi_rx_data_cache[ADDRESS_WIDTH_BYTE_NUM-1][7]) begin
  219. wr_en <= 1;
  220. has_trigger_wr_en <= 1;
  221. end else begin
  222. wr_en <= 0;
  223. end
  224. end
  225. end
  226. endmodule