SPIm.v 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731
  1. //////////////////////////////////////////////////////////////////////////////////
  2. // Company: TAIR
  3. // Engineer:
  4. //
  5. // Create Date: 10/30/2023 11:24:31 AM
  6. // Design Name:
  7. // Module Name: SPIm
  8. // Project Name: S5443_V3_FPGA3
  9. // Target Devices: BOARD: BY5443v3. FPGA: xc7s25csga225-2
  10. // Tool Versions:
  11. // Description: This is module implements Spi Master protocol. For more info refer
  12. // to the techincal reference manual.
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 1.0 - File Created
  18. // Additional Comments:
  19. //
  20. //////////////////////////////////////////////////////////////////////////////////
  21. module SPIm
  22. (
  23. input Clk_i,
  24. input Rst_i,
  25. input Start_i,
  26. input EmptyFlag_i,
  27. input ClockPhase_i,
  28. input [31:0] SpiData_i,
  29. input SelSt_i,
  30. input [1:0] WidthSel_i,
  31. input Lag_i,
  32. input Lead_i,
  33. input EndianSel_i,
  34. input [5:0] Stop_i,
  35. input PulsePol_i,
  36. output reg Mosi0_o,
  37. output reg Sck_o,
  38. output Ss_o,
  39. output reg Val_o
  40. );
  41. //================================================================================
  42. // REG/WIRE
  43. //================================================================================
  44. reg startFlag;
  45. reg valReg;
  46. reg lineBusy;
  47. reg [5:0] ssCnt;
  48. reg ss;
  49. reg ssR;
  50. reg SSR;
  51. reg [31:0] mosiReg0;
  52. reg [5:0] ssNum;
  53. reg [2:0] delayCnt;
  54. reg stopFlag;
  55. (* dont_touch = "true" *) wire [31:0] txLenght = ssNum+Lag_i+Lead_i;
  56. //================================================================================
  57. // ASSIGNMENTS
  58. //================================================================================
  59. assign Ss_o = ss;
  60. //================================================================================
  61. // CODING
  62. //================================================================================
  63. always @(*) begin
  64. if (Start_i) begin
  65. Val_o = valReg;
  66. end
  67. else begin
  68. Val_o = 1'b0;
  69. end
  70. end
  71. always @(*) begin
  72. if (SelSt_i) begin
  73. if (!Ss_o) begin
  74. lineBusy = 1'b1;
  75. end
  76. else begin
  77. lineBusy = 1'b0;
  78. end
  79. end
  80. else begin
  81. if (Ss_o) begin
  82. lineBusy = 1'b1;
  83. end
  84. else begin
  85. lineBusy = 1'b0;
  86. end
  87. end
  88. end
  89. always @(negedge Clk_i) begin
  90. if (Rst_i) begin
  91. delayCnt <= 1'b0;
  92. end else begin
  93. if (stopFlag) begin
  94. delayCnt <= delayCnt + 1'b1;
  95. end else begin
  96. delayCnt <= 0;
  97. end
  98. end
  99. end
  100. always @(*) begin
  101. if (Rst_i) begin
  102. stopFlag = 1'b0;
  103. end
  104. else begin
  105. if (Stop_i != 0) begin
  106. if (SelSt_i) begin
  107. if (ss && !ssR) begin
  108. stopFlag = 1'b1;
  109. end
  110. else if (delayCnt == Stop_i-1) begin
  111. stopFlag = 1'b0;
  112. end
  113. end
  114. else begin
  115. if (!ss && ssR) begin
  116. stopFlag = 1'b1;
  117. end
  118. else if (delayCnt == Stop_i-1) begin
  119. stopFlag = 1'b0;
  120. end
  121. end
  122. end else begin
  123. stopFlag = 1'b0;
  124. end
  125. end
  126. end
  127. reg [2:0] clkCtrlReg;
  128. always @(*) begin
  129. if (Rst_i) begin
  130. clkCtrlReg = 0;
  131. end else begin
  132. clkCtrlReg = {SelSt_i,PulsePol_i,ClockPhase_i};
  133. end
  134. end
  135. always @(*) begin
  136. if (Rst_i) begin
  137. Sck_o = 0;
  138. end else begin
  139. if (Stop_i!=0) begin
  140. case (clkCtrlReg)
  141. 0: begin
  142. if (!Lag_i) begin
  143. if (!Lead_i) begin
  144. if (ss) begin
  145. Sck_o = Clk_i;
  146. end else begin
  147. Sck_o = 0;
  148. end
  149. end else begin
  150. if (ssCnt < txLenght-1) begin
  151. Sck_o = Clk_i;
  152. end else begin
  153. Sck_o = 0;
  154. end
  155. end
  156. end else begin
  157. if (!Lead_i) begin
  158. if (ssCnt > 0) begin
  159. Sck_o = Clk_i;
  160. end else begin
  161. Sck_o = 0;
  162. end
  163. end else begin
  164. if (ssCnt >0 && ssCnt < txLenght-1) begin
  165. Sck_o = Clk_i;
  166. end else begin
  167. Sck_o = 0;
  168. end
  169. end
  170. end
  171. end
  172. 1: begin
  173. if (!Lag_i) begin
  174. if (!Lead_i) begin
  175. if (ss) begin
  176. Sck_o = !Clk_i;
  177. end else begin
  178. Sck_o = 0;
  179. end
  180. end else begin
  181. if (ssCnt < txLenght-1) begin
  182. Sck_o = !Clk_i;
  183. end else begin
  184. Sck_o = 0;
  185. end
  186. end
  187. end else begin
  188. if (!Lead_i) begin
  189. if (ssCnt > 0) begin
  190. Sck_o = !Clk_i;
  191. end else begin
  192. Sck_o = 0;
  193. end
  194. end else begin
  195. if (ssCnt >0 && ssCnt < txLenght-1) begin
  196. Sck_o = !Clk_i;
  197. end else begin
  198. Sck_o = 0;
  199. end
  200. end
  201. end
  202. end
  203. 2: begin
  204. if (!Lag_i) begin
  205. if (!Lead_i) begin
  206. if (ss) begin
  207. Sck_o = !Clk_i;
  208. end else begin
  209. Sck_o = 0;
  210. end
  211. end else begin
  212. if (ssCnt < txLenght-1) begin
  213. Sck_o = !Clk_i;
  214. end else begin
  215. Sck_o = 0;
  216. end
  217. end
  218. end else begin
  219. if (!Lead_i) begin
  220. if (ssCnt > 0) begin
  221. Sck_o = !Clk_i;
  222. end else begin
  223. Sck_o = 0;
  224. end
  225. end else begin
  226. if (ssCnt >0 && ssCnt < txLenght-1) begin
  227. Sck_o = !Clk_i;
  228. end else begin
  229. Sck_o = 0;
  230. end
  231. end
  232. end
  233. end
  234. 3: begin
  235. if (!Lag_i) begin
  236. if (!Lead_i) begin
  237. if (ss) begin
  238. Sck_o = Clk_i;
  239. end else begin
  240. Sck_o = 0;
  241. end
  242. end else begin
  243. if (ssCnt < txLenght-1) begin
  244. Sck_o = Clk_i;
  245. end else begin
  246. Sck_o = 0;
  247. end
  248. end
  249. end else begin
  250. if (!Lead_i) begin
  251. if (ssCnt > 0) begin
  252. Sck_o = Clk_i;
  253. end else begin
  254. Sck_o = 0;
  255. end
  256. end else begin
  257. if (ssCnt >0 && ssCnt < txLenght-1) begin
  258. Sck_o = Clk_i;
  259. end else begin
  260. Sck_o = 0;
  261. end
  262. end
  263. end
  264. end
  265. 4: begin
  266. if (!Lag_i) begin
  267. if (!Lead_i) begin
  268. if (!ss) begin
  269. Sck_o = Clk_i;
  270. end else begin
  271. Sck_o = 0;
  272. end
  273. end else begin
  274. if (ssCnt < txLenght-1) begin
  275. Sck_o = Clk_i;
  276. end else begin
  277. Sck_o = 0;
  278. end
  279. end
  280. end else begin
  281. if (!Lead_i) begin
  282. if (ssCnt > 0) begin
  283. Sck_o = Clk_i;
  284. end else begin
  285. Sck_o = 0;
  286. end
  287. end else begin
  288. if (ssCnt >0 && ssCnt < txLenght-1) begin
  289. Sck_o = Clk_i;
  290. end else begin
  291. Sck_o = 0;
  292. end
  293. end
  294. end
  295. end
  296. 5: begin
  297. if (!Lag_i) begin
  298. if (!Lead_i) begin
  299. if (!ss) begin
  300. Sck_o = !Clk_i;
  301. end else begin
  302. Sck_o = 0;
  303. end
  304. end else begin
  305. if (ssCnt < txLenght-1) begin
  306. Sck_o = !Clk_i;
  307. end else begin
  308. Sck_o = 0;
  309. end
  310. end
  311. end else begin
  312. if (!Lead_i) begin
  313. if (ssCnt > 0) begin
  314. Sck_o = !Clk_i;
  315. end else begin
  316. Sck_o = 0;
  317. end
  318. end else begin
  319. if (ssCnt >0 && ssCnt < txLenght-1) begin
  320. Sck_o = !Clk_i;
  321. end else begin
  322. Sck_o = 0;
  323. end
  324. end
  325. end
  326. end
  327. 6: begin
  328. if (!Lag_i) begin
  329. if (!Lead_i) begin
  330. if (!ss) begin
  331. Sck_o = !Clk_i;
  332. end else begin
  333. Sck_o = 0;
  334. end
  335. end else begin
  336. if (ssCnt < txLenght-1) begin
  337. Sck_o = !Clk_i;
  338. end else begin
  339. Sck_o = 0;
  340. end
  341. end
  342. end else begin
  343. if (!Lead_i) begin
  344. if (ssCnt > 0) begin
  345. Sck_o = !Clk_i;
  346. end else begin
  347. Sck_o = 0;
  348. end
  349. end else begin
  350. if (ssCnt >0 && ssCnt < txLenght-1) begin
  351. Sck_o = !Clk_i;
  352. end else begin
  353. Sck_o = 0;
  354. end
  355. end
  356. end
  357. end
  358. 7: begin
  359. if (!Lag_i) begin
  360. if (!Lead_i) begin
  361. if (!ss) begin
  362. Sck_o = Clk_i;
  363. end else begin
  364. Sck_o = 0;
  365. end
  366. end else begin
  367. if (ssCnt < txLenght-1) begin
  368. Sck_o = Clk_i;
  369. end else begin
  370. Sck_o = 0;
  371. end
  372. end
  373. end else begin
  374. if (!Lead_i) begin
  375. if (ssCnt > 0) begin
  376. Sck_o = Clk_i;
  377. end else begin
  378. Sck_o = 0;
  379. end
  380. end else begin
  381. if (ssCnt >0 && ssCnt < txLenght-1) begin
  382. Sck_o = Clk_i;
  383. end else begin
  384. Sck_o = 0;
  385. end
  386. end
  387. end
  388. end
  389. endcase
  390. end else begin
  391. if (SelSt_i) begin
  392. if (!ss) begin
  393. if (PulsePol_i) begin
  394. if (ClockPhase_i) begin
  395. Sck_o = Clk_i;
  396. end
  397. else begin
  398. Sck_o = ~Clk_i;
  399. end
  400. end else begin
  401. if (ClockPhase_i) begin
  402. Sck_o = ~Clk_i;
  403. end
  404. else begin
  405. Sck_o = Clk_i;
  406. end
  407. end
  408. end else begin
  409. Sck_o = 1'b0;
  410. end
  411. end else begin
  412. if (ss) begin
  413. if (PulsePol_i) begin
  414. if (ClockPhase_i) begin
  415. Sck_o = Clk_i;
  416. end
  417. else begin
  418. Sck_o = ~Clk_i;
  419. end
  420. end else begin
  421. if (ClockPhase_i) begin
  422. Sck_o = ~Clk_i;
  423. end
  424. else begin
  425. Sck_o = Clk_i;
  426. end
  427. end
  428. end else begin
  429. Sck_o = 1'b0;
  430. end
  431. end
  432. end
  433. end
  434. end
  435. always @(*) begin
  436. if (Rst_i) begin
  437. Mosi0_o = 1'b0;
  438. end
  439. else begin
  440. if (SelSt_i) begin
  441. if (!EndianSel_i) begin
  442. case (WidthSel_i)
  443. 0 : begin
  444. Mosi0_o = (!ss)? mosiReg0[7]:1'b0;
  445. end
  446. 1 : begin
  447. Mosi0_o = (!ss)? (mosiReg0[15]):1'b0;
  448. end
  449. 2 : begin
  450. Mosi0_o = (!ss)? (mosiReg0[23]):1'b0;
  451. end
  452. 3 : begin
  453. Mosi0_o = (!ss)? (mosiReg0[31]):1'b0;
  454. end
  455. endcase
  456. end
  457. else begin
  458. case (WidthSel_i)
  459. 0 : begin
  460. Mosi0_o = (!ss)? mosiReg0[0]:1'b0;
  461. end
  462. 1 : begin
  463. Mosi0_o = (!ss)? (mosiReg0[0]):1'b0;
  464. end
  465. 2 : begin
  466. Mosi0_o = (!ss)? (mosiReg0[0]):1'b0;
  467. end
  468. 3 : begin
  469. Mosi0_o = (!ss)? (mosiReg0[0]):1'b0;
  470. end
  471. endcase
  472. end
  473. end
  474. else begin
  475. if (!EndianSel_i) begin
  476. case (WidthSel_i)
  477. 0 : begin
  478. Mosi0_o = (ss)? (mosiReg0[7]):1'b0;
  479. end
  480. 1 : begin
  481. Mosi0_o = (ss)? (mosiReg0[15]):1'b0;
  482. end
  483. 2 : begin
  484. Mosi0_o = (ss)? (mosiReg0[23]):1'b0;
  485. end
  486. 3 : begin
  487. Mosi0_o = (ss)? (mosiReg0[31]):1'b0;
  488. end
  489. endcase
  490. end
  491. else begin
  492. case (WidthSel_i)
  493. 0 : begin
  494. Mosi0_o = (ss)? (mosiReg0[0]):1'b0;
  495. end
  496. 1 : begin
  497. Mosi0_o = (ss)? (mosiReg0[0]):1'b0;
  498. end
  499. 2 : begin
  500. Mosi0_o = (ss)? (mosiReg0[0]):1'b0;
  501. end
  502. 3 : begin
  503. Mosi0_o = (ss)? (mosiReg0[0]):1'b0;
  504. end
  505. endcase
  506. end
  507. end
  508. end
  509. end
  510. always @(posedge Clk_i) begin
  511. ssR <= ss;
  512. end
  513. always @(*) begin
  514. if (Rst_i) begin
  515. startFlag = 1'b0;
  516. end
  517. else begin
  518. if (Start_i && !stopFlag && !EmptyFlag_i ) begin
  519. startFlag = 1'b1;
  520. end
  521. else begin
  522. startFlag = 1'b0;
  523. end
  524. end
  525. end
  526. always @(posedge Clk_i) begin
  527. if (Rst_i) begin
  528. valReg <= 0;
  529. end else begin
  530. if (ssCnt == txLenght-3) begin
  531. if (!valReg) begin
  532. valReg <= 1;
  533. end else begin
  534. valReg <= 0;
  535. end
  536. end else begin
  537. valReg <= 0;
  538. end
  539. end
  540. end
  541. always @(*) begin
  542. if (Rst_i) begin
  543. ssNum = 1'b0;
  544. end
  545. else begin
  546. case (WidthSel_i)
  547. 0 : begin
  548. ssNum = 8;
  549. end
  550. 1 : begin
  551. ssNum = 16;
  552. end
  553. 2 : begin
  554. ssNum = 24;
  555. end
  556. 3 : begin
  557. ssNum = 32;
  558. end
  559. endcase
  560. end
  561. end
  562. always @(negedge Clk_i) begin
  563. if (Rst_i) begin
  564. ssCnt <= 0;
  565. end
  566. else begin
  567. if (SelSt_i) begin
  568. if (!ss) begin
  569. if (ssCnt != txLenght-1) begin
  570. ssCnt <= ssCnt + 1;
  571. end else begin
  572. ssCnt <= 0;
  573. end
  574. end else begin
  575. ssCnt <= 0;
  576. end
  577. end else begin
  578. if (ss) begin
  579. if (ssCnt != txLenght-1) begin
  580. ssCnt <= ssCnt + 1;
  581. end else begin
  582. ssCnt <= 0;
  583. end
  584. end else begin
  585. ssCnt <= 0;
  586. end
  587. end
  588. end
  589. end
  590. always @(negedge Clk_i) begin
  591. if (Rst_i) begin
  592. ss <= 1'b1;
  593. end else begin
  594. if (Stop_i != 0) begin
  595. if (startFlag) begin
  596. if (SelSt_i) begin
  597. if (ssCnt != txLenght-1) begin
  598. ss <= 1'b0;
  599. end
  600. else begin
  601. ss <= 1'b1;
  602. end
  603. end else begin
  604. if (ssCnt != txLenght-1) begin
  605. ss <= 1'b1;
  606. end
  607. else begin
  608. ss <= 1'b0;
  609. end
  610. end
  611. end else begin
  612. if (SelSt_i) begin
  613. ss <= 1'b1;
  614. end else begin
  615. ss <= 1'b0;
  616. end
  617. end
  618. end else begin
  619. if (startFlag) begin
  620. if (SelSt_i) begin
  621. ss <= 1'b0;
  622. end else begin
  623. ss <= 1'b1;
  624. end
  625. end else begin
  626. if (SelSt_i) begin
  627. ss <= 1'b1;
  628. end else begin
  629. ss <= 1'b0;
  630. end
  631. end
  632. end
  633. end
  634. end
  635. always @(negedge Clk_i) begin
  636. if (Rst_i) begin
  637. mosiReg0 <= SpiData_i[31:0];
  638. end
  639. else begin
  640. if (SelSt_i) begin
  641. if (!EndianSel_i) begin
  642. if (Lag_i!=0) begin
  643. if (!ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin
  644. mosiReg0 <= mosiReg0 << 1;
  645. end else begin
  646. mosiReg0 <= SpiData_i[31:0];
  647. end
  648. end else begin
  649. if (!ss&& (ssCnt < txLenght-1)) begin
  650. mosiReg0 <= mosiReg0 << 1;
  651. end else begin
  652. mosiReg0 <= SpiData_i[31:0];
  653. end
  654. end
  655. end else begin
  656. if (Lag_i!=0) begin
  657. if (!ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin
  658. mosiReg0 <= mosiReg0 >> 1;
  659. end
  660. else begin
  661. mosiReg0 <= SpiData_i[31:0];
  662. end
  663. end else begin
  664. if (!ss&& (ssCnt < txLenght-1)) begin
  665. mosiReg0 <= mosiReg0 >> 1;
  666. end else begin
  667. mosiReg0 <= SpiData_i[31:0];
  668. end
  669. end
  670. end
  671. end else begin
  672. if (!EndianSel_i) begin
  673. if (Lag_i!=0) begin
  674. if (ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin
  675. mosiReg0 <= mosiReg0 << 1;
  676. end else begin
  677. mosiReg0 <= SpiData_i[31:0];
  678. end
  679. end else begin
  680. if (ss&& (ssCnt < txLenght-1)) begin
  681. mosiReg0 <= mosiReg0 << 1;
  682. end else begin
  683. mosiReg0 <= SpiData_i[31:0];
  684. end
  685. end
  686. end else begin
  687. if (Lag_i!=0) begin
  688. if (ss&& (ssCnt > 0 && ssCnt < txLenght-1)) begin
  689. mosiReg0 <= mosiReg0 >> 1;
  690. end
  691. else begin
  692. mosiReg0 <= SpiData_i[31:0];
  693. end
  694. end else begin
  695. if (ss&& (ssCnt < txLenght-1)) begin
  696. mosiReg0 <= mosiReg0 >> 1;
  697. end else begin
  698. mosiReg0 <= SpiData_i[31:0];
  699. end
  700. end
  701. end
  702. end
  703. end
  704. end
  705. endmodule