Projektdaten für das ESY1B Praktikum im Sommersemester 2022
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.

SPI_Master_Control.sv 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //Source: https://github.com/nandland/spi-master/tree/master/Verilog/source
  3. // Description: SPI (Serial Peripheral Interface) Master
  4. // Creates master based on input configuration.
  5. // Sends a byte one bit at a time on MOSI
  6. // Will also receive byte data one bit at a time on MISO.
  7. // Any data on input byte will be shipped out on MOSI.
  8. //
  9. // To kick-off transaction, user must pulse i_TX_DV.
  10. // This module supports multi-byte transmissions by pulsing
  11. // i_TX_DV and loading up i_TX_Byte when o_TX_Ready is high.
  12. //
  13. // This module is only responsible for controlling Clk, MOSI,
  14. // and MISO. If the SPI peripheral requires a chip-select,
  15. // this must be done at a higher level.
  16. //
  17. // Note: i_Clk must be at least 2x faster than i_SPI_Clk
  18. //
  19. // Parameters: SPI_MODE, can be 0, 1, 2, or 3. See above.
  20. // Can be configured in one of 4 modes:
  21. // Mode | Clock Polarity (CPOL/CKP) | Clock Phase (CPHA)
  22. // 0 | 0 | 0
  23. // 1 | 0 | 1
  24. // 2 | 1 | 0
  25. // 3 | 1 | 1
  26. // More: https://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus#Mode_numbers
  27. // CLKS_PER_HALF_BIT - Sets frequency of o_SPI_Clk. o_SPI_Clk is
  28. // derived from i_Clk. Set to integer number of clocks for each
  29. // half-bit of SPI data. E.g. 100 MHz i_Clk, CLKS_PER_HALF_BIT = 2
  30. // would create o_SPI_CLK of 25 MHz. Must be >= 2
  31. //
  32. ///////////////////////////////////////////////////////////////////////////////
  33. module SPI_Master
  34. #(parameter SPI_MODE = 0,
  35. parameter CLKS_PER_HALF_BIT = 2)
  36. (
  37. // Control/Data Signals,
  38. input i_Rst_L, // FPGA Reset
  39. input i_Clk, // FPGA Clock
  40. // TX (MOSI) Signals
  41. input [7:0] i_TX_Byte, // Byte to transmit on MOSI
  42. input i_TX_DV, // Data Valid Pulse with i_TX_Byte
  43. output reg o_TX_Ready, // Transmit Ready for next byte
  44. // RX (MISO) Signals
  45. output reg o_RX_DV, // Data Valid pulse (1 clock cycle)
  46. output reg [7:0] o_RX_Byte, // Byte received on MISO
  47. // SPI Interface
  48. output reg o_SPI_Clk,
  49. input i_SPI_MISO,
  50. output reg o_SPI_MOSI
  51. );
  52. // SPI Interface (All Runs at SPI Clock Domain)
  53. wire w_CPOL; // Clock polarity
  54. wire w_CPHA; // Clock phase
  55. reg [$clog2(CLKS_PER_HALF_BIT*2)-1:0] r_SPI_Clk_Count;
  56. reg r_SPI_Clk;
  57. reg [4:0] r_SPI_Clk_Edges;
  58. reg r_Leading_Edge;
  59. reg r_Trailing_Edge;
  60. reg r_TX_DV;
  61. reg [7:0] r_TX_Byte;
  62. reg [2:0] r_RX_Bit_Count;
  63. reg [2:0] r_TX_Bit_Count;
  64. // CPOL: Clock Polarity
  65. // CPOL=0 means clock idles at 0, leading edge is rising edge.
  66. // CPOL=1 means clock idles at 1, leading edge is falling edge.
  67. assign w_CPOL = (SPI_MODE == 2) | (SPI_MODE == 3);
  68. // CPHA: Clock Phase
  69. // CPHA=0 means the "out" side changes the data on trailing edge of clock
  70. // the "in" side captures data on leading edge of clock
  71. // CPHA=1 means the "out" side changes the data on leading edge of clock
  72. // the "in" side captures data on the trailing edge of clock
  73. assign w_CPHA = (SPI_MODE == 1) | (SPI_MODE == 3);
  74. // Purpose: Generate SPI Clock correct number of times when DV pulse comes
  75. always @(posedge i_Clk or negedge i_Rst_L)
  76. begin
  77. if (~i_Rst_L)
  78. begin
  79. o_TX_Ready <= 1'b0;
  80. r_SPI_Clk_Edges <= 0;
  81. r_Leading_Edge <= 1'b0;
  82. r_Trailing_Edge <= 1'b0;
  83. r_SPI_Clk <= w_CPOL; // assign default state to idle state
  84. r_SPI_Clk_Count <= 0;
  85. end
  86. else
  87. begin
  88. // Default assignments
  89. r_Leading_Edge <= 1'b0;
  90. r_Trailing_Edge <= 1'b0;
  91. if (i_TX_DV)
  92. begin
  93. o_TX_Ready <= 1'b0;
  94. r_SPI_Clk_Edges <= 16; // Total # edges in one byte ALWAYS 16
  95. end
  96. else if (r_SPI_Clk_Edges > 0)
  97. begin
  98. o_TX_Ready <= 1'b0;
  99. if (r_SPI_Clk_Count == CLKS_PER_HALF_BIT*2-1)
  100. begin
  101. r_SPI_Clk_Edges <= r_SPI_Clk_Edges - 1;
  102. r_Trailing_Edge <= 1'b1;
  103. r_SPI_Clk_Count <= 0;
  104. r_SPI_Clk <= ~r_SPI_Clk;
  105. end
  106. else if (r_SPI_Clk_Count == CLKS_PER_HALF_BIT-1)
  107. begin
  108. r_SPI_Clk_Edges <= r_SPI_Clk_Edges - 1;
  109. r_Leading_Edge <= 1'b1;
  110. r_SPI_Clk_Count <= r_SPI_Clk_Count + 1;
  111. r_SPI_Clk <= ~r_SPI_Clk;
  112. end
  113. else
  114. begin
  115. r_SPI_Clk_Count <= r_SPI_Clk_Count + 1;
  116. end
  117. end
  118. else
  119. begin
  120. o_TX_Ready <= 1'b1;
  121. end
  122. end // else: !if(~i_Rst_L)
  123. end // always @ (posedge i_Clk or negedge i_Rst_L)
  124. // Purpose: Register i_TX_Byte when Data Valid is pulsed.
  125. // Keeps local storage of byte in case higher level module changes the data
  126. always @(posedge i_Clk or negedge i_Rst_L)
  127. begin
  128. if (~i_Rst_L)
  129. begin
  130. r_TX_Byte <= 8'h00;
  131. r_TX_DV <= 1'b0;
  132. end
  133. else
  134. begin
  135. r_TX_DV <= i_TX_DV; // 1 clock cycle delay
  136. if (i_TX_DV)
  137. begin
  138. r_TX_Byte <= i_TX_Byte;
  139. end
  140. end // else: !if(~i_Rst_L)
  141. end // always @ (posedge i_Clk or negedge i_Rst_L)
  142. // Purpose: Generate MOSI data
  143. // Works with both CPHA=0 and CPHA=1
  144. always @(posedge i_Clk or negedge i_Rst_L)
  145. begin
  146. if (~i_Rst_L)
  147. begin
  148. o_SPI_MOSI <= 1'b0;
  149. r_TX_Bit_Count <= 3'b111; // send MSb first
  150. end
  151. else
  152. begin
  153. // If ready is high, reset bit counts to default
  154. if (o_TX_Ready)
  155. begin
  156. r_TX_Bit_Count <= 3'b111;
  157. end
  158. // Catch the case where we start transaction and CPHA = 0
  159. else if (r_TX_DV & ~w_CPHA)
  160. begin
  161. o_SPI_MOSI <= r_TX_Byte[3'b111];
  162. r_TX_Bit_Count <= 3'b110;
  163. end
  164. else if ((r_Leading_Edge & w_CPHA) | (r_Trailing_Edge & ~w_CPHA))
  165. begin
  166. r_TX_Bit_Count <= r_TX_Bit_Count - 1;
  167. o_SPI_MOSI <= r_TX_Byte[r_TX_Bit_Count];
  168. end
  169. end
  170. end
  171. // Purpose: Read in MISO data.
  172. always @(posedge i_Clk or negedge i_Rst_L)
  173. begin
  174. if (~i_Rst_L)
  175. begin
  176. o_RX_Byte <= 8'h00;
  177. o_RX_DV <= 1'b0;
  178. r_RX_Bit_Count <= 3'b111;
  179. end
  180. else
  181. begin
  182. // Default Assignments
  183. o_RX_DV <= 1'b0;
  184. if (o_TX_Ready) // Check if ready is high, if so reset bit count to default
  185. begin
  186. r_RX_Bit_Count <= 3'b111;
  187. end
  188. else if ((r_Leading_Edge & ~w_CPHA) | (r_Trailing_Edge & w_CPHA))
  189. begin
  190. o_RX_Byte[r_RX_Bit_Count] <= i_SPI_MISO; // Sample data
  191. r_RX_Bit_Count <= r_RX_Bit_Count - 1;
  192. if (r_RX_Bit_Count == 3'b000)
  193. begin
  194. o_RX_DV <= 1'b1; // Byte done, pulse Data Valid
  195. end
  196. end
  197. end
  198. end
  199. // Purpose: Add clock delay to signals for alignment.
  200. always @(posedge i_Clk or negedge i_Rst_L)
  201. begin
  202. if (~i_Rst_L)
  203. begin
  204. o_SPI_Clk <= w_CPOL;
  205. end
  206. else
  207. begin
  208. o_SPI_Clk <= r_SPI_Clk;
  209. end // else: !if(~i_Rst_L)
  210. end // always @ (posedge i_Clk or negedge i_Rst_L)
  211. endmodule // SPI_Master