PeriphSpiInit.v 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. //////////////////////////////////////////////////////////////////////////////////
  2. // Company : NPK TAIR
  3. // Engineer : Yuri Donskoy
  4. //
  5. // Create Date (dd/mm/yyyy) : 16.05.2019
  6. // Design Name :
  7. // Module Name :
  8. // Project Name :
  9. // Target Devices :
  10. // Tool versions :
  11. // Description :
  12. //
  13. // Dependencies :
  14. //
  15. // Revision : 0.01 - File Created
  16. // Additional Comments :
  17. //
  18. //////////////////////////////////////////////////////////////////////////////////
  19. module PeriphSpiInit (
  20. clk_i,
  21. rst_i,
  22. enable_i,
  23. mosi_o,
  24. sck_o,
  25. ss_o,
  26. done_o
  27. );
  28. //================================================================================
  29. //
  30. // FUNCTIONS
  31. //
  32. //================================================================================
  33. function integer bit_num;
  34. input integer value;
  35. begin
  36. bit_num = 0;
  37. while (value > 0) begin
  38. value = value >> 1;
  39. bit_num = bit_num + 1;
  40. end
  41. end
  42. endfunction
  43. //================================================================================
  44. //
  45. // PARAMETER/LOCALPARAM
  46. //
  47. //================================================================================
  48. parameter DATA_WIDTH = 24;
  49. parameter DATA_NUM = 26;
  50. parameter ROM_INIT_FILE = "./initFiles/AdcInitData.txt";
  51. parameter FILE_DATA_BASE = "HEX";
  52. parameter SPI_CLK_DIVISOR_POWER = 4;
  53. parameter SPI_CPOL = 0;
  54. parameter SPI_CPHA = 0;
  55. parameter SPI_DATA_DIRECTION = "MSB"; // MSB or LSB
  56. parameter SPI_EN_START_DELAY = "NO"; // YES or NO
  57. localparam ROM_ADDR_WIDTH = bit_num(DATA_NUM);
  58. //================================================================================
  59. //
  60. // STATE MACHINE STATES
  61. //
  62. //================================================================================
  63. localparam [7:0] SM_RST_S = 8'd0;
  64. localparam [7:0] SM_SEND_DATA_S = 8'd2;
  65. localparam [7:0] SM_READ_DATA_S = 8'd3;
  66. localparam [7:0] SM_WAIT_SPI_S = 8'd4;
  67. localparam [7:0] SM_DONE_S = 8'd5;
  68. //================================================================================
  69. //
  70. // PORTS
  71. //
  72. //================================================================================
  73. input clk_i;
  74. input rst_i;
  75. input enable_i;
  76. output mosi_o;
  77. output sck_o;
  78. output ss_o;
  79. output done_o;
  80. //================================================================================
  81. //
  82. // REG/WIRE
  83. //
  84. //================================================================================
  85. reg [ROM_ADDR_WIDTH-1:0] rom_addr;
  86. reg rom_valid;
  87. wire [DATA_WIDTH-1:0] rom_data;
  88. reg [ROM_ADDR_WIDTH-1:0] rom_addr_next;
  89. wire spi_ready;
  90. reg [7:0] sm_curr_state;
  91. reg [7:0] sm_next_state;
  92. wire data_end_flag;
  93. //================================================================================
  94. //
  95. // INTEGER/GENVAR
  96. //
  97. //================================================================================
  98. //================================================================================
  99. //
  100. // ASSIGN
  101. //
  102. //================================================================================
  103. assign data_end_flag = (rom_addr == DATA_NUM);
  104. assign done_o = sm_curr_state == SM_DONE_S;
  105. //================================================================================
  106. //
  107. // CODING
  108. //
  109. //================================================================================
  110. SpiMaster #(
  111. .CLK_DIVISOR_POWER (SPI_CLK_DIVISOR_POWER),
  112. .DATA_WIDTH (DATA_WIDTH),
  113. .CPOL (SPI_CPOL),
  114. .CPHA (SPI_CPHA),
  115. .DATA_DIRECTION (SPI_DATA_DIRECTION),
  116. .EN_START_DELAY (SPI_EN_START_DELAY)
  117. ) SpiMaster (
  118. .clk_i (clk_i),
  119. .rst_i (rst_i),
  120. .data_i (rom_data),
  121. .valid_i (rom_valid),
  122. .ready_o (spi_ready),
  123. .mosi_o (mosi_o),
  124. .sck_o (sck_o),
  125. .ss_o (ss_o)
  126. );
  127. SinglePortRom #(
  128. .DATA_WIDTH (DATA_WIDTH),
  129. .ADDR_WIDTH (ROM_ADDR_WIDTH),
  130. .INIT_FILE_NAME (ROM_INIT_FILE),
  131. .DATA_BASE (FILE_DATA_BASE)
  132. ) Rom (
  133. .clk_i (clk_i),
  134. .addr_i (rom_addr),
  135. .q_o (rom_data)
  136. );
  137. always @(posedge clk_i or posedge rst_i) begin
  138. if (rst_i) begin
  139. sm_curr_state <= 0;
  140. rom_addr <= SM_RST_S;
  141. end else begin
  142. sm_curr_state <= sm_next_state;
  143. rom_addr <= rom_addr_next;
  144. end
  145. end
  146. always @(*) begin
  147. sm_next_state = 0;
  148. rom_addr_next = rom_addr;
  149. rom_valid = 1'b0;
  150. case(sm_curr_state)
  151. SM_RST_S : begin
  152. if (enable_i) begin
  153. sm_next_state = SM_SEND_DATA_S;
  154. end else begin
  155. sm_next_state = SM_RST_S;
  156. end
  157. end
  158. SM_SEND_DATA_S : begin
  159. rom_valid = 1'b1;
  160. sm_next_state = SM_SEND_DATA_S;
  161. if (spi_ready) begin
  162. rom_addr_next = rom_addr + {{(ROM_ADDR_WIDTH-1){1'b0}}, 1'b1};
  163. sm_next_state = SM_READ_DATA_S;
  164. end
  165. end
  166. SM_READ_DATA_S : begin
  167. if (data_end_flag) begin
  168. sm_next_state = SM_WAIT_SPI_S;
  169. end else begin
  170. sm_next_state = SM_SEND_DATA_S;
  171. end
  172. end
  173. SM_WAIT_SPI_S : begin
  174. if (spi_ready) begin
  175. sm_next_state = SM_DONE_S;
  176. end else begin
  177. sm_next_state = SM_WAIT_SPI_S;
  178. end
  179. end
  180. SM_DONE_S : begin
  181. sm_next_state = SM_DONE_S;
  182. end
  183. endcase
  184. end
  185. endmodule