SPIm.v 16 KB

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