Verwendeter Programmcode in Studienarbeit für ESY1B zum Thema "Verifikation mit SystemVerilog und Python"
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

i2c_master_bit_ctrl.v 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. /////////////////////////////////////////////////////////////////////
  2. //// ////
  3. //// WISHBONE rev.B2 compliant I2C Master bit-controller ////
  4. //// ////
  5. //// ////
  6. //// Author: Richard Herveille ////
  7. //// richard@asics.ws ////
  8. //// www.asics.ws ////
  9. //// ////
  10. //// Downloaded from: http://www.opencores.org/projects/i2c/ ////
  11. //// ////
  12. /////////////////////////////////////////////////////////////////////
  13. //// ////
  14. //// Copyright (C) 2001 Richard Herveille ////
  15. //// richard@asics.ws ////
  16. //// ////
  17. //// This source file may be used and distributed without ////
  18. //// restriction provided that this copyright statement is not ////
  19. //// removed from the file and that any derivative work contains ////
  20. //// the original copyright notice and the associated disclaimer.////
  21. //// ////
  22. //// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
  23. //// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
  24. //// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
  25. //// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
  26. //// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
  27. //// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
  28. //// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
  29. //// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
  30. //// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
  31. //// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
  32. //// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
  33. //// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
  34. //// POSSIBILITY OF SUCH DAMAGE. ////
  35. //// ////
  36. /////////////////////////////////////////////////////////////////////
  37. // CVS Log
  38. //
  39. // $Id: i2c_master_bit_ctrl.v,v 1.1 2008-11-08 13:15:10 sfielding Exp $
  40. //
  41. // $Date: 2008-11-08 13:15:10 $
  42. // $Revision: 1.1 $
  43. // $Author: sfielding $
  44. // $Locker: $
  45. // $State: Exp $
  46. //
  47. // Change History:
  48. // $Log: not supported by cvs2svn $
  49. // Revision 1.12 2006/09/04 09:08:13 rherveille
  50. // fixed short scl high pulse after clock stretch
  51. // fixed slave model not returning correct '(n)ack' signal
  52. //
  53. // Revision 1.11 2004/05/07 11:02:26 rherveille
  54. // Fixed a bug where the core would signal an arbitration lost (AL bit set), when another master controls the bus and the other master generates a STOP bit.
  55. //
  56. // Revision 1.10 2003/08/09 07:01:33 rherveille
  57. // Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
  58. // Fixed a potential bug in the byte controller's host-acknowledge generation.
  59. //
  60. // Revision 1.9 2003/03/10 14:26:37 rherveille
  61. // Fixed cmd_ack generation item (no bug).
  62. //
  63. // Revision 1.8 2003/02/05 00:06:10 rherveille
  64. // Fixed a bug where the core would trigger an erroneous 'arbitration lost' interrupt after being reset, when the reset pulse width < 3 clk cycles.
  65. //
  66. // Revision 1.7 2002/12/26 16:05:12 rherveille
  67. // Small code simplifications
  68. //
  69. // Revision 1.6 2002/12/26 15:02:32 rherveille
  70. // Core is now a Multimaster I2C controller
  71. //
  72. // Revision 1.5 2002/11/30 22:24:40 rherveille
  73. // Cleaned up code
  74. //
  75. // Revision 1.4 2002/10/30 18:10:07 rherveille
  76. // Fixed some reported minor start/stop generation timing issuess.
  77. //
  78. // Revision 1.3 2002/06/15 07:37:03 rherveille
  79. // Fixed a small timing bug in the bit controller.\nAdded verilog simulation environment.
  80. //
  81. // Revision 1.2 2001/11/05 11:59:25 rherveille
  82. // Fixed wb_ack_o generation bug.
  83. // Fixed bug in the byte_controller statemachine.
  84. // Added headers.
  85. //
  86. //
  87. /////////////////////////////////////
  88. // Bit controller section
  89. /////////////////////////////////////
  90. //
  91. // Translate simple commands into SCL/SDA transitions
  92. // Each command has 5 states, A/B/C/D/idle
  93. //
  94. // start: SCL ~~~~~~~~~~\____
  95. // SDA ~~~~~~~~\______
  96. // x | A | B | C | D | i
  97. //
  98. // repstart SCL ____/~~~~\___
  99. // SDA __/~~~\______
  100. // x | A | B | C | D | i
  101. //
  102. // stop SCL ____/~~~~~~~~
  103. // SDA ==\____/~~~~~
  104. // x | A | B | C | D | i
  105. //
  106. //- write SCL ____/~~~~\____
  107. // SDA ==X=========X=
  108. // x | A | B | C | D | i
  109. //
  110. //- read SCL ____/~~~~\____
  111. // SDA XXXX=====XXXX
  112. // x | A | B | C | D | i
  113. //
  114. // Timing: Normal mode Fast mode
  115. ///////////////////////////////////////////////////////////////////////
  116. // Fscl 100KHz 400KHz
  117. // Th_scl 4.0us 0.6us High period of SCL
  118. // Tl_scl 4.7us 1.3us Low period of SCL
  119. // Tsu:sta 4.7us 0.6us setup time for a repeated start condition
  120. // Tsu:sto 4.0us 0.6us setup time for a stop conditon
  121. // Tbuf 4.7us 1.3us Bus free time between a stop and start condition
  122. //
  123. // synopsys translate_off
  124. `include "timescale.v"
  125. // synopsys translate_on
  126. `include "i2c_master_defines.v"
  127. module i2c_master_bit_ctrl(
  128. clk, rst, nReset,
  129. clk_cnt, ena, cmd, cmd_ack, busy, al, din, dout,
  130. scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen
  131. );
  132. //
  133. // inputs & outputs
  134. //
  135. input clk;
  136. input rst;
  137. input nReset;
  138. input ena; // core enable signal
  139. input [15:0] clk_cnt; // clock prescale value
  140. input [3:0] cmd;
  141. output cmd_ack; // command complete acknowledge
  142. reg cmd_ack;
  143. output busy; // i2c bus busy
  144. reg busy;
  145. output al; // i2c bus arbitration lost
  146. reg al;
  147. input din;
  148. output dout;
  149. reg dout;
  150. // I2C lines
  151. input scl_i; // i2c clock line input
  152. output scl_o; // i2c clock line output
  153. output scl_oen; // i2c clock line output enable (active low)
  154. reg scl_oen;
  155. input sda_i; // i2c data line input
  156. output sda_o; // i2c data line output
  157. output sda_oen; // i2c data line output enable (active low)
  158. reg sda_oen;
  159. //
  160. // variable declarations
  161. //
  162. reg sSCL, sSDA; // synchronized SCL and SDA inputs
  163. reg dscl_oen; // delayed scl_oen
  164. reg sda_chk; // check SDA output (Multi-master arbitration)
  165. reg clk_en; // clock generation signals
  166. wire slave_wait;
  167. // reg [15:0] cnt = clk_cnt; // clock divider counter (simulation)
  168. reg [15:0] cnt; // clock divider counter (synthesis)
  169. // state machine variable
  170. reg [16:0] c_state; // synopsys enum_state
  171. //
  172. // module body
  173. //
  174. // whenever the slave is not ready it can delay the cycle by pulling SCL low
  175. // delay scl_oen
  176. always @(posedge clk)
  177. dscl_oen <= #1 scl_oen;
  178. assign slave_wait = dscl_oen && !sSCL;
  179. // generate clk enable signal
  180. always @(posedge clk or negedge nReset)
  181. if(~nReset)
  182. begin
  183. cnt <= #1 16'h0;
  184. clk_en <= #1 1'b1;
  185. end
  186. else if (rst)
  187. begin
  188. cnt <= #1 16'h0;
  189. clk_en <= #1 1'b1;
  190. end
  191. else if ( ~|cnt || !ena)
  192. begin
  193. cnt <= #1 clk_cnt;
  194. clk_en <= #1 1'b1;
  195. end
  196. else if (slave_wait)
  197. begin
  198. cnt <= #1 cnt;
  199. clk_en <= #1 1'b0;
  200. end
  201. else
  202. begin
  203. cnt <= #1 cnt - 16'h1;
  204. clk_en <= #1 1'b0;
  205. end
  206. // generate bus status controller
  207. reg dSCL, dSDA;
  208. reg sta_condition;
  209. reg sto_condition;
  210. // synchronize SCL and SDA inputs
  211. // reduce metastability risc
  212. always @(posedge clk or negedge nReset)
  213. if (~nReset)
  214. begin
  215. sSCL <= #1 1'b1;
  216. sSDA <= #1 1'b1;
  217. dSCL <= #1 1'b1;
  218. dSDA <= #1 1'b1;
  219. end
  220. else if (rst)
  221. begin
  222. sSCL <= #1 1'b1;
  223. sSDA <= #1 1'b1;
  224. dSCL <= #1 1'b1;
  225. dSDA <= #1 1'b1;
  226. end
  227. else
  228. begin
  229. sSCL <= #1 scl_i;
  230. sSDA <= #1 sda_i;
  231. dSCL <= #1 sSCL;
  232. dSDA <= #1 sSDA;
  233. end
  234. // detect start condition => detect falling edge on SDA while SCL is high
  235. // detect stop condition => detect rising edge on SDA while SCL is high
  236. always @(posedge clk or negedge nReset)
  237. if (~nReset)
  238. begin
  239. sta_condition <= #1 1'b0;
  240. sto_condition <= #1 1'b0;
  241. end
  242. else if (rst)
  243. begin
  244. sta_condition <= #1 1'b0;
  245. sto_condition <= #1 1'b0;
  246. end
  247. else
  248. begin
  249. sta_condition <= #1 ~sSDA & dSDA & sSCL;
  250. sto_condition <= #1 sSDA & ~dSDA & sSCL;
  251. end
  252. // generate i2c bus busy signal
  253. always @(posedge clk or negedge nReset)
  254. if(!nReset)
  255. busy <= #1 1'b0;
  256. else if (rst)
  257. busy <= #1 1'b0;
  258. else
  259. busy <= #1 (sta_condition | busy) & ~sto_condition;
  260. // generate arbitration lost signal
  261. // aribitration lost when:
  262. // 1) master drives SDA high, but the i2c bus is low
  263. // 2) stop detected while not requested
  264. reg cmd_stop;
  265. always @(posedge clk or negedge nReset)
  266. if (~nReset)
  267. cmd_stop <= #1 1'b0;
  268. else if (rst)
  269. cmd_stop <= #1 1'b0;
  270. else if (clk_en)
  271. cmd_stop <= #1 cmd == `I2C_CMD_STOP;
  272. always @(posedge clk or negedge nReset)
  273. if (~nReset)
  274. al <= #1 1'b0;
  275. else if (rst)
  276. al <= #1 1'b0;
  277. else
  278. al <= #1 (sda_chk & ~sSDA & sda_oen) | (|c_state & sto_condition & ~cmd_stop);
  279. // generate dout signal (store SDA on rising edge of SCL)
  280. always @(posedge clk)
  281. if(sSCL & ~dSCL)
  282. dout <= #1 sSDA;
  283. // generate statemachine
  284. // nxt_state decoder
  285. parameter [16:0] idle = 17'b0_0000_0000_0000_0000;
  286. parameter [16:0] start_a = 17'b0_0000_0000_0000_0001;
  287. parameter [16:0] start_b = 17'b0_0000_0000_0000_0010;
  288. parameter [16:0] start_c = 17'b0_0000_0000_0000_0100;
  289. parameter [16:0] start_d = 17'b0_0000_0000_0000_1000;
  290. parameter [16:0] start_e = 17'b0_0000_0000_0001_0000;
  291. parameter [16:0] stop_a = 17'b0_0000_0000_0010_0000;
  292. parameter [16:0] stop_b = 17'b0_0000_0000_0100_0000;
  293. parameter [16:0] stop_c = 17'b0_0000_0000_1000_0000;
  294. parameter [16:0] stop_d = 17'b0_0000_0001_0000_0000;
  295. parameter [16:0] rd_a = 17'b0_0000_0010_0000_0000;
  296. parameter [16:0] rd_b = 17'b0_0000_0100_0000_0000;
  297. parameter [16:0] rd_c = 17'b0_0000_1000_0000_0000;
  298. parameter [16:0] rd_d = 17'b0_0001_0000_0000_0000;
  299. parameter [16:0] wr_a = 17'b0_0010_0000_0000_0000;
  300. parameter [16:0] wr_b = 17'b0_0100_0000_0000_0000;
  301. parameter [16:0] wr_c = 17'b0_1000_0000_0000_0000;
  302. parameter [16:0] wr_d = 17'b1_0000_0000_0000_0000;
  303. always @(posedge clk or negedge nReset)
  304. if (!nReset)
  305. begin
  306. c_state <= #1 idle;
  307. cmd_ack <= #1 1'b0;
  308. scl_oen <= #1 1'b1;
  309. sda_oen <= #1 1'b1;
  310. sda_chk <= #1 1'b0;
  311. end
  312. else if (rst | al)
  313. begin
  314. c_state <= #1 idle;
  315. cmd_ack <= #1 1'b0;
  316. scl_oen <= #1 1'b1;
  317. sda_oen <= #1 1'b1;
  318. sda_chk <= #1 1'b0;
  319. end
  320. else
  321. begin
  322. cmd_ack <= #1 1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle
  323. if (clk_en)
  324. case (c_state) // synopsys full_case parallel_case
  325. // idle state
  326. idle:
  327. begin
  328. case (cmd) // synopsys full_case parallel_case
  329. `I2C_CMD_START:
  330. c_state <= #1 start_a;
  331. `I2C_CMD_STOP:
  332. c_state <= #1 stop_a;
  333. `I2C_CMD_WRITE:
  334. c_state <= #1 wr_a;
  335. `I2C_CMD_READ:
  336. c_state <= #1 rd_a;
  337. default:
  338. c_state <= #1 idle;
  339. endcase
  340. scl_oen <= #1 scl_oen; // keep SCL in same state
  341. sda_oen <= #1 sda_oen; // keep SDA in same state
  342. sda_chk <= #1 1'b0; // don't check SDA output
  343. end
  344. // start
  345. start_a:
  346. begin
  347. c_state <= #1 start_b;
  348. scl_oen <= #1 scl_oen; // keep SCL in same state
  349. sda_oen <= #1 1'b1; // set SDA high
  350. sda_chk <= #1 1'b0; // don't check SDA output
  351. end
  352. start_b:
  353. begin
  354. c_state <= #1 start_c;
  355. scl_oen <= #1 1'b1; // set SCL high
  356. sda_oen <= #1 1'b1; // keep SDA high
  357. sda_chk <= #1 1'b0; // don't check SDA output
  358. end
  359. start_c:
  360. begin
  361. c_state <= #1 start_d;
  362. scl_oen <= #1 1'b1; // keep SCL high
  363. sda_oen <= #1 1'b0; // set SDA low
  364. sda_chk <= #1 1'b0; // don't check SDA output
  365. end
  366. start_d:
  367. begin
  368. c_state <= #1 start_e;
  369. scl_oen <= #1 1'b1; // keep SCL high
  370. sda_oen <= #1 1'b0; // keep SDA low
  371. sda_chk <= #1 1'b0; // don't check SDA output
  372. end
  373. start_e:
  374. begin
  375. c_state <= #1 idle;
  376. cmd_ack <= #1 1'b1;
  377. scl_oen <= #1 1'b0; // set SCL low
  378. sda_oen <= #1 1'b0; // keep SDA low
  379. sda_chk <= #1 1'b0; // don't check SDA output
  380. end
  381. // stop
  382. stop_a:
  383. begin
  384. c_state <= #1 stop_b;
  385. scl_oen <= #1 1'b0; // keep SCL low
  386. sda_oen <= #1 1'b0; // set SDA low
  387. sda_chk <= #1 1'b0; // don't check SDA output
  388. end
  389. stop_b:
  390. begin
  391. c_state <= #1 stop_c;
  392. scl_oen <= #1 1'b1; // set SCL high
  393. sda_oen <= #1 1'b0; // keep SDA low
  394. sda_chk <= #1 1'b0; // don't check SDA output
  395. end
  396. stop_c:
  397. begin
  398. c_state <= #1 stop_d;
  399. scl_oen <= #1 1'b1; // keep SCL high
  400. sda_oen <= #1 1'b0; // keep SDA low
  401. sda_chk <= #1 1'b0; // don't check SDA output
  402. end
  403. stop_d:
  404. begin
  405. c_state <= #1 idle;
  406. cmd_ack <= #1 1'b1;
  407. scl_oen <= #1 1'b1; // keep SCL high
  408. sda_oen <= #1 1'b1; // set SDA high
  409. sda_chk <= #1 1'b0; // don't check SDA output
  410. end
  411. // read
  412. rd_a:
  413. begin
  414. c_state <= #1 rd_b;
  415. scl_oen <= #1 1'b0; // keep SCL low
  416. sda_oen <= #1 1'b1; // tri-state SDA
  417. sda_chk <= #1 1'b0; // don't check SDA output
  418. end
  419. rd_b:
  420. begin
  421. c_state <= #1 rd_c;
  422. scl_oen <= #1 1'b1; // set SCL high
  423. sda_oen <= #1 1'b1; // keep SDA tri-stated
  424. sda_chk <= #1 1'b0; // don't check SDA output
  425. end
  426. rd_c:
  427. begin
  428. c_state <= #1 rd_d;
  429. scl_oen <= #1 1'b1; // keep SCL high
  430. sda_oen <= #1 1'b1; // keep SDA tri-stated
  431. sda_chk <= #1 1'b0; // don't check SDA output
  432. end
  433. rd_d:
  434. begin
  435. c_state <= #1 idle;
  436. cmd_ack <= #1 1'b1;
  437. scl_oen <= #1 1'b0; // set SCL low
  438. sda_oen <= #1 1'b1; // keep SDA tri-stated
  439. sda_chk <= #1 1'b0; // don't check SDA output
  440. end
  441. // write
  442. wr_a:
  443. begin
  444. c_state <= #1 wr_b;
  445. scl_oen <= #1 1'b0; // keep SCL low
  446. sda_oen <= #1 din; // set SDA
  447. sda_chk <= #1 1'b0; // don't check SDA output (SCL low)
  448. end
  449. wr_b:
  450. begin
  451. c_state <= #1 wr_c;
  452. scl_oen <= #1 1'b1; // set SCL high
  453. sda_oen <= #1 din; // keep SDA
  454. sda_chk <= #1 1'b1; // check SDA output
  455. end
  456. wr_c:
  457. begin
  458. c_state <= #1 wr_d;
  459. scl_oen <= #1 1'b1; // keep SCL high
  460. sda_oen <= #1 din;
  461. sda_chk <= #1 1'b1; // check SDA output
  462. end
  463. wr_d:
  464. begin
  465. c_state <= #1 idle;
  466. cmd_ack <= #1 1'b1;
  467. scl_oen <= #1 1'b0; // set SCL low
  468. sda_oen <= #1 din;
  469. sda_chk <= #1 1'b0; // don't check SDA output (SCL low)
  470. end
  471. endcase
  472. end
  473. // assign scl and sda output (always gnd)
  474. assign scl_o = 1'b0;
  475. assign sda_o = 1'b0;
  476. endmodule