SPIm.v 17 KB

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