SPIm.v 16 KB

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