SlaveSpi.v 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. `timescale 1ns / 1ps
  2. //////////////////////////////////////////////////////////////////////////////////
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 17.09.2020 14:18:14
  7. // Design Name:
  8. // Module Name: SlaveSpi
  9. // Project Name:
  10. // Target Devices:
  11. // Tool Versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //////////////////////////////////////////////////////////////////////////////////
  21. module SlaveSpi
  22. #(
  23. parameter CmdRegWidth = 32,
  24. parameter DataCntWidth = 6,
  25. parameter HeaderWidth = 7,
  26. parameter CmdDataRegWith = 24,
  27. parameter Adc0DirAccessAddr = 7'h13,
  28. parameter Adc1DirAccessAddr = 7'h14
  29. )
  30. (
  31. input Clk_i,
  32. input Rst_i,
  33. output reg [CmdRegWidth-1:0] Data_o,
  34. output reg Val_o,
  35. //-----------------------------------
  36. //input Spi lines from ext. Dsp
  37. input Mosi_i,
  38. input Sck_i,
  39. input Ss_i,
  40. //-----------------------------------
  41. //-----------------------------------
  42. output Mosi_o,
  43. output Sck_o,
  44. output Ss0_o,
  45. output Ss1_o,
  46. //-----------------------------------
  47. output [HeaderWidth-1:0] AnsAddr_o,
  48. input [CmdDataRegWith-1:0] AnsReg_i,
  49. input Miso_i,
  50. output Miso_o
  51. );
  52. //================================================================================
  53. // REG/WIRE
  54. //================================================================================
  55. reg [CmdRegWidth-1:0] dataCaptReg;
  56. reg [DataCntWidth-1:0] dataCnt;
  57. reg [HeaderWidth-1:0] ansAddr;
  58. reg spiMode;
  59. wire directTransit = (ansAddr == Adc0DirAccessAddr)|(ansAddr == Adc1DirAccessAddr);
  60. reg txWind;
  61. reg [4:0] txCnt;
  62. //================================================================================
  63. // ASSIGNMENTS
  64. //================================================================================
  65. assign Mosi_o = (!spiMode&directTransit)? Mosi_i:1'b1;
  66. assign Sck_o = (directTransit)? Sck_i:1'b0;
  67. assign Ss0_o = (directTransit&&(ansAddr==Adc0DirAccessAddr))? Ss_i:1'b1;
  68. assign Ss1_o = (directTransit&&(ansAddr==Adc1DirAccessAddr))? Ss_i:1'b1;
  69. assign AnsAddr_o = ansAddr;
  70. assign Miso_o = txWind? AnsReg_i[txCnt]:1'b0;
  71. //================================================================================
  72. // CODING
  73. //================================================================================
  74. always @(posedge Sck_i) begin
  75. if (~Ss_i) begin
  76. dataCaptReg <= {dataCaptReg[CmdRegWidth-2:0],Mosi_i};
  77. end else begin
  78. dataCaptReg <= dataCaptReg;
  79. end
  80. end
  81. always @(posedge Sck_i) begin
  82. if (~Rst_i) begin
  83. if (~Ss_i) begin
  84. dataCnt <= dataCnt + 5'd1;
  85. end
  86. end else begin
  87. dataCnt <= 0;
  88. end
  89. end
  90. always @(posedge Sck_i) begin
  91. if (~Rst_i) begin
  92. if (dataCnt == 5'd1) begin
  93. if (dataCaptReg[CmdRegWidth-CmdRegWidth]) begin
  94. spiMode <= 1'b1;
  95. end else begin
  96. spiMode <= 1'b0;
  97. end
  98. end
  99. end else begin
  100. spiMode <= 1'b0;
  101. end
  102. end
  103. always @(negedge Sck_i) begin
  104. if (~Rst_i) begin
  105. if (~Ss_i) begin
  106. if (dataCnt == 5'd8) begin
  107. ansAddr <= dataCaptReg[CmdRegWidth-26-:HeaderWidth];
  108. end else if (dataCnt == 5'd0) begin
  109. ansAddr <= 7'h7F;
  110. end
  111. end else begin
  112. ansAddr <= 7'h7F;
  113. end
  114. end else begin
  115. ansAddr <= 7'h7F;
  116. end
  117. end
  118. //================================================================================
  119. // Generating output signals
  120. //================================================================================
  121. reg ssReg;
  122. reg ssRegR;
  123. always @(posedge Clk_i) begin
  124. ssReg <= Ss_i;
  125. ssRegR <= ssReg;
  126. end
  127. reg ssPos;
  128. always @(posedge Clk_i) begin
  129. ssPos <= ssReg&!ssRegR;
  130. end
  131. always @(posedge Clk_i) begin
  132. if (!directTransit&!spiMode) begin
  133. if (ssReg&!ssRegR) begin
  134. Val_o <= 1'b1;
  135. end else begin
  136. Val_o <= 0;
  137. end
  138. end
  139. end
  140. always @(posedge Clk_i) begin
  141. if (((ansAddr != Adc0DirAccessAddr)|(ansAddr != Adc1DirAccessAddr))&!spiMode) begin
  142. if (ssReg&!ssRegR) begin
  143. Data_o <= dataCaptReg;
  144. end
  145. end
  146. end
  147. always @(*) begin
  148. if (spiMode & !Ss_i) begin
  149. if (dataCnt >=5'd8|dataCnt == 0) begin
  150. txWind = 1'b1;
  151. end else begin
  152. txWind = 1'b0;
  153. end
  154. end else begin
  155. txWind = 1'b0;
  156. end
  157. end
  158. always @(negedge Sck_i) begin
  159. if (txWind) begin
  160. if (~Ss_i & txWind & txCnt!= 0) begin
  161. txCnt <= txCnt - 5'd1;
  162. end else begin
  163. txCnt <= 5'd24;
  164. end
  165. end else begin
  166. txCnt <= 5'd24;
  167. end
  168. end
  169. endmodule