QuadSPIm.v 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. module QuadSPIm(
  2. input Clk_i,
  3. input Rst_i,
  4. input Start_i,
  5. input CPHA_i,
  6. input [31:0] SPIdata,
  7. input SELST_i,
  8. input [1:0] WidthSel_i,
  9. input [1:0] LAG_i,
  10. input [1:0] LEAD_i,
  11. input EndianSel_i,
  12. input [1:0] Stop_i,
  13. input PulsePol_i,
  14. output reg Mosi0_i,
  15. output reg Mosi1_i,
  16. output reg Mosi2_i,
  17. output reg Mosi3_i,
  18. output reg Sck_o,
  19. output reg Val_o,
  20. output Ss_o
  21. );
  22. //================================================================================
  23. // REG/WIRE
  24. //================================================================================
  25. reg startFlag;
  26. reg [2:0] ssCnt;
  27. reg Ss;
  28. reg SSr;
  29. reg [6:0] mosiReg0;
  30. reg [6:0] mosiReg1;
  31. reg [6:0] mosiReg2;
  32. reg [6:0] mosiReg3;
  33. reg [3:0] ssNum;
  34. reg [2:0] delayCnt;
  35. reg stopFlag;
  36. wire SsPol = SELST_i ? Ss : ~Ss;
  37. //================================================================================
  38. // ASSIGNMENTS
  39. //================================================================================
  40. assign Ss_o = SsPol;
  41. //================================================================================
  42. // CODING
  43. //================================================================================
  44. always @(posedge Clk_i) begin
  45. if (Rst_i) begin
  46. delayCnt <= 1'b0;
  47. end
  48. else begin
  49. if (stopFlag &&delayCnt < Stop_i) begin
  50. delayCnt <= delayCnt + 1'b1;
  51. end
  52. else begin
  53. delayCnt <= 1'b0;
  54. end
  55. end
  56. end
  57. always @(posedge Clk_i) begin
  58. if (Rst_i) begin
  59. stopFlag <= 1'b0;
  60. end
  61. else begin
  62. if (SELST_i) begin
  63. if (Ss && !SSr) begin
  64. stopFlag <= 1'b1;
  65. end
  66. else if ( delayCnt == Stop_i) begin
  67. stopFlag <= 1'b0;
  68. end
  69. end
  70. else begin
  71. if (!Ss && SSr) begin
  72. stopFlag <= 1'b1;
  73. end
  74. else if (delayCnt == Stop_i) begin
  75. stopFlag <= 1'b0;
  76. end
  77. end
  78. end
  79. end
  80. always @(*) begin
  81. if (PulsePol_i) begin
  82. if (CPHA_i) begin
  83. if (LEAD_i == 0) begin
  84. if (!Ss && (ssCnt <= ssNum+LAG_i+LEAD_i && ssCnt > LAG_i) ) begin
  85. Sck_o = ~(~Clk_i);
  86. end
  87. else begin
  88. Sck_o = 1'b0;
  89. end
  90. end
  91. else begin
  92. if (!Ss && (ssCnt < ssNum+LAG_i+LEAD_i && ssCnt > LAG_i)) begin
  93. Sck_o = ~(~Clk_i);
  94. end
  95. else begin
  96. Sck_o = 1'b0;
  97. end
  98. end
  99. end
  100. else begin
  101. if (LEAD_i == 0) begin
  102. if (!Ss && (ssCnt <= ssNum+LAG_i+LEAD_i && ssCnt > LAG_i) ) begin
  103. Sck_o = ~(Clk_i);
  104. end
  105. else begin
  106. Sck_o = 1'b0;
  107. end
  108. end
  109. else begin
  110. if (!Ss && (ssCnt < ssNum + LAG_i + LEAD_i && ssCnt > LAG_i)) begin
  111. Sck_o = ~(Clk_i);
  112. end
  113. else begin
  114. Sck_o = 1'b0;
  115. end
  116. end
  117. end
  118. end
  119. else begin
  120. if (CPHA_i) begin
  121. if (LEAD_i == 0) begin
  122. if (!Ss && (ssCnt <= ssNum+LAG_i+LEAD_i && ssCnt > LAG_i) ) begin
  123. Sck_o = ~(Clk_i);
  124. end
  125. else begin
  126. Sck_o = 1'b0;
  127. end
  128. end
  129. else begin
  130. if (!Ss && (ssCnt <ssNum + LAG_i + LAG_i && ssCnt > LAG_i)) begin
  131. Sck_o = ~(Clk_i);
  132. end
  133. else begin
  134. Sck_o = 1'b0;
  135. end
  136. end
  137. end
  138. else begin
  139. if (LEAD_i == 0) begin
  140. if (!Ss && (ssCnt <= ssNum+LAG_i+LEAD_i && ssCnt > LAG_i) ) begin
  141. Sck_o = ~(~Clk_i);
  142. end
  143. else begin
  144. Sck_o = 1'b0;
  145. end
  146. end
  147. else begin
  148. if (!Ss && (ssCnt < ssNum + LAG_i + LEAD_i && ssCnt > LAG_i)) begin
  149. Sck_o = ~(~Clk_i);
  150. end
  151. else begin
  152. Sck_o = 1'b0;
  153. end
  154. end
  155. end
  156. end
  157. end
  158. always @(*) begin
  159. if (EndianSel_i) begin
  160. case (WidthSel_i)
  161. 0 : begin
  162. Mosi0_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i) ) ? (mosiReg3[1]):1'b0;
  163. Mosi1_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg2[1]):1'b0;
  164. Mosi2_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg1[1]):1'b0;
  165. Mosi3_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg0[1]):1'b0;
  166. end
  167. 1 : begin
  168. Mosi0_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg3[3]):1'b0;
  169. Mosi1_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg2[3]):1'b0;
  170. Mosi2_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg1[3]):1'b0;
  171. Mosi3_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg0[3]):1'b0;
  172. end
  173. 2 : begin
  174. Mosi0_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg3[5]):1'b0;
  175. Mosi1_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg2[5]):1'b0;
  176. Mosi2_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg1[5]):1'b0;
  177. Mosi3_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg0[5]):1'b0;
  178. end
  179. 3 : begin
  180. Mosi0_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg3[7]):1'b0;
  181. Mosi1_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg2[7]):1'b0;
  182. Mosi2_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg1[7]):1'b0;
  183. Mosi3_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg0[7]):1'b0;
  184. end
  185. endcase
  186. end
  187. else begin
  188. case (WidthSel_i)
  189. 0 : begin
  190. Mosi0_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg0[1]):1'b0;
  191. Mosi1_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg1[1]):1'b0;
  192. Mosi2_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg2[1]):1'b0;
  193. Mosi3_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg3[1]):1'b0;
  194. end
  195. 1 : begin
  196. Mosi0_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg0[3]):1'b0;
  197. Mosi1_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg1[3]):1'b0;
  198. Mosi2_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg2[3]):1'b0;
  199. Mosi3_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt >LAG_i))? (mosiReg3[3]):1'b0;
  200. end
  201. 2 : begin
  202. Mosi0_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg0[5]):1'b0;
  203. Mosi1_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg1[5]):1'b0;
  204. Mosi2_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg2[5]):1'b0;
  205. Mosi3_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg3[5]):1'b0;
  206. end
  207. 3 : begin
  208. Mosi0_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg0[7]):1'b0;
  209. Mosi1_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg1[7]):1'b0;
  210. Mosi2_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg2[7]):1'b0;
  211. Mosi3_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg3[7]):1'b0;
  212. end
  213. endcase
  214. end
  215. end
  216. always @(posedge Clk_i) begin
  217. if (Rst_i) begin
  218. SSr <=1'b0;
  219. end
  220. else begin
  221. SSr <= Ss;
  222. end
  223. end
  224. always @(*) begin
  225. if (SELST_i) begin
  226. if (Ss && !SSr) begin
  227. Val_o = 1'b1;
  228. end
  229. else begin
  230. Val_o = 1'b0;
  231. end
  232. end
  233. else begin
  234. if (!Ss&& SSr) begin
  235. Val_o = 1'b1;
  236. end
  237. else begin
  238. Val_o = 1'b0;
  239. end
  240. end
  241. end
  242. always @(*) begin
  243. if (Rst_i) begin
  244. startFlag = 1'b0;
  245. end
  246. else begin
  247. if (Start_i&& !stopFlag) begin
  248. startFlag = 1'b1;
  249. end
  250. else begin
  251. startFlag = 1'b0;
  252. end
  253. end
  254. end
  255. always @(*) begin
  256. if (Rst_i) begin
  257. ssNum = 1'b0;
  258. end
  259. else begin
  260. case (WidthSel_i)
  261. 0 : begin
  262. ssNum = 2;
  263. end
  264. 1 : begin
  265. ssNum = 4;
  266. end
  267. 2 : begin
  268. ssNum = 6;
  269. end
  270. 3 : begin
  271. ssNum = 8;
  272. end
  273. endcase
  274. end
  275. end
  276. always @(negedge Clk_i) begin
  277. if (Rst_i) begin
  278. ssCnt <= 1'b0;
  279. end
  280. else if (ssCnt < (ssNum+LAG_i+LEAD_i) && startFlag ) begin
  281. ssCnt <= ssCnt + 1'b1;
  282. end
  283. else begin
  284. if (ssCnt == ssNum-1 || !startFlag) begin
  285. ssCnt <= 1'b0;
  286. end
  287. end
  288. end
  289. always @(negedge Clk_i) begin
  290. if (Rst_i) begin
  291. Ss <= 1'b1;
  292. end
  293. else begin
  294. if (ssCnt < (ssNum+LAG_i+LEAD_i) && startFlag ) begin
  295. Ss <= 1'b0;
  296. end
  297. else begin
  298. Ss <= 1'b1;
  299. end
  300. end
  301. end
  302. always @(negedge Clk_i) begin
  303. if (Rst_i) begin
  304. mosiReg0 <= SPIdata[31:24];
  305. end
  306. else begin
  307. if (!SSr && (ssCnt > LAG_i && ssCnt < ssNum + LAG_i + LEAD_i)) begin
  308. mosiReg0 <= { mosiReg0[6:0],1'b0 };
  309. end
  310. else begin
  311. mosiReg0 <= SPIdata[31:24];
  312. end
  313. end
  314. end
  315. always @(negedge Clk_i) begin
  316. if (Rst_i) begin
  317. mosiReg1 <= SPIdata[23:16];
  318. end
  319. else begin
  320. if (!SSr&& (ssCnt > LAG_i && ssCnt < ssNum + LAG_i + LEAD_i)) begin
  321. mosiReg1 <= { mosiReg1[6:0],1'b0 };
  322. end
  323. else begin
  324. mosiReg1 <= SPIdata[23:16];
  325. end
  326. end
  327. end
  328. always @(negedge Clk_i) begin
  329. if (Rst_i) begin
  330. mosiReg2 <= SPIdata[15:8];
  331. end
  332. else begin
  333. if (!SSr&& (ssCnt > LAG_i && ssCnt < ssNum + LAG_i + LEAD_i)) begin
  334. mosiReg2 <= { mosiReg2[6:0],1'b0 };
  335. end
  336. else begin
  337. mosiReg2 <= SPIdata[15:8];
  338. end
  339. end
  340. end
  341. always @(negedge Clk_i) begin
  342. if (Rst_i) begin
  343. mosiReg3 <= SPIdata[7:0];
  344. end
  345. else begin
  346. if (!SSr&& (ssCnt > LAG_i && ssCnt < ssNum + LAG_i + LEAD_i)) begin
  347. mosiReg3 <= { mosiReg3[6:0],1'b0 };
  348. end
  349. else begin
  350. mosiReg3 <= SPIdata[7:0];
  351. end
  352. end
  353. end
  354. endmodule