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.

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