OpenCores
URL https://opencores.org/ocsvn/i2c/i2c/trunk

Subversion Repositories i2c

[/] [i2c/] [trunk/] [rtl/] [verilog/] [i2c_master_bit_ctrl.v] - Blame information for rev 75

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 rherveille
/////////////////////////////////////////////////////////////////////
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
 
38
//  CVS Log
39 10 rherveille
//
40 63 rherveille
//  $Id: i2c_master_bit_ctrl.v,v 1.14 2009-01-20 10:25:29 rherveille Exp $
41 10 rherveille
//
42 63 rherveille
//  $Date: 2009-01-20 10:25:29 $
43
//  $Revision: 1.14 $
44 14 rherveille
//  $Author: rherveille $
45
//  $Locker:  $
46
//  $State: Exp $
47 10 rherveille
//
48 14 rherveille
// Change History:
49 74 rherveille
//               $Log: $
50
//               Revision 1.14  2009/01/20 10:25:29  rherveille
51
//               Added clock synchronization logic
52
//               Fixed slave_wait signal
53
//
54 63 rherveille
//               Revision 1.13  2009/01/19 20:29:26  rherveille
55
//               Fixed synopsys miss spell (synopsis)
56
//               Fixed cr[0] register width
57
//               Fixed ! usage instead of ~
58
//               Fixed bit controller parameter width to 18bits
59
//
60 62 rherveille
//               Revision 1.12  2006/09/04 09:08:13  rherveille
61
//               fixed short scl high pulse after clock stretch
62
//               fixed slave model not returning correct '(n)ack' signal
63
//
64 57 rherveille
//               Revision 1.11  2004/05/07 11:02:26  rherveille
65
//               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.
66
//
67 52 rherveille
//               Revision 1.10  2003/08/09 07:01:33  rherveille
68
//               Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
69
//               Fixed a potential bug in the byte controller's host-acknowledge generation.
70
//
71 38 rherveille
//               Revision 1.9  2003/03/10 14:26:37  rherveille
72
//               Fixed cmd_ack generation item (no bug).
73
//
74 36 rherveille
//               Revision 1.8  2003/02/05 00:06:10  rherveille
75
//               Fixed a bug where the core would trigger an erroneous 'arbitration lost' interrupt after being reset, when the reset pulse width < 3 clk cycles.
76
//
77 35 rherveille
//               Revision 1.7  2002/12/26 16:05:12  rherveille
78
//               Small code simplifications
79
//
80 30 rherveille
//               Revision 1.6  2002/12/26 15:02:32  rherveille
81
//               Core is now a Multimaster I2C controller
82
//
83 29 rherveille
//               Revision 1.5  2002/11/30 22:24:40  rherveille
84
//               Cleaned up code
85
//
86 27 rherveille
//               Revision 1.4  2002/10/30 18:10:07  rherveille
87
//               Fixed some reported minor start/stop generation timing issuess.
88
//
89 24 rherveille
//               Revision 1.3  2002/06/15 07:37:03  rherveille
90
//               Fixed a small timing bug in the bit controller.\nAdded verilog simulation environment.
91
//
92 22 rherveille
//               Revision 1.2  2001/11/05 11:59:25  rherveille
93
//               Fixed wb_ack_o generation bug.
94
//               Fixed bug in the byte_controller statemachine.
95
//               Added headers.
96
//
97 10 rherveille
 
98
//
99
/////////////////////////////////////
100
// Bit controller section
101
/////////////////////////////////////
102
//
103
// Translate simple commands into SCL/SDA transitions
104
// Each command has 5 states, A/B/C/D/idle
105
//
106
// start:       SCL     ~~~~~~~~~~\____
107
//      SDA     ~~~~~~~~\______
108
//               x | A | B | C | D | i
109
//
110
// repstart     SCL     ____/~~~~\___
111
//      SDA     __/~~~\______
112
//               x | A | B | C | D | i
113
//
114
// stop SCL     ____/~~~~~~~~
115
//      SDA     ==\____/~~~~~
116
//               x | A | B | C | D | i
117
//
118
//- write       SCL     ____/~~~~\____
119
//      SDA     ==X=========X=
120
//               x | A | B | C | D | i
121
//
122
//- read        SCL     ____/~~~~\____
123
//      SDA     XXXX=====XXXX
124
//               x | A | B | C | D | i
125
//
126
 
127 24 rherveille
// Timing:     Normal mode      Fast mode
128 10 rherveille
///////////////////////////////////////////////////////////////////////
129 24 rherveille
// Fscl        100KHz           400KHz
130
// Th_scl      4.0us            0.6us   High period of SCL
131
// Tl_scl      4.7us            1.3us   Low period of SCL
132
// Tsu:sta     4.7us            0.6us   setup time for a repeated start condition
133
// Tsu:sto     4.0us            0.6us   setup time for a stop conditon
134
// Tbuf        4.7us            1.3us   Bus free time between a stop and start condition
135 10 rherveille
//
136
 
137 29 rherveille
// synopsys translate_off
138 10 rherveille
`include "timescale.v"
139 29 rherveille
// synopsys translate_on
140
 
141 10 rherveille
`include "i2c_master_defines.v"
142
 
143 74 rherveille
module i2c_master_bit_ctrl (
144
    input             clk,      // system clock
145
    input             rst,      // synchronous active high reset
146
    input             nReset,   // asynchronous active low reset
147
    input             ena,      // core enable signal
148 10 rherveille
 
149 74 rherveille
    input      [15:0] clk_cnt,  // clock prescale value
150 10 rherveille
 
151 74 rherveille
    input      [ 3:0] cmd,      // command (from byte controller)
152
    output reg        cmd_ack,  // command complete acknowledge
153
    output reg        busy,     // i2c bus busy
154
    output reg        al,       // i2c bus arbitration lost
155 10 rherveille
 
156 74 rherveille
    input             din,
157
    output reg        dout,
158 10 rherveille
 
159 74 rherveille
    input             scl_i,    // i2c clock line input
160
    output            scl_o,    // i2c clock line output
161
    output reg        scl_oen,  // i2c clock line output enable (active low)
162
    input             sda_i,    // i2c data line input
163
    output            sda_o,    // i2c data line output
164
    output reg        sda_oen   // i2c data line output enable (active low)
165
);
166 10 rherveille
 
167
 
168 74 rherveille
    //
169
    // variable declarations
170
    //
171 10 rherveille
 
172 74 rherveille
    reg [ 1:0] cSCL, cSDA;      // capture SCL and SDA
173
    reg [ 2:0] fSCL, fSDA;      // SCL and SDA filter inputs
174
    reg        sSCL, sSDA;      // filtered and synchronized SCL and SDA inputs
175
    reg        dSCL, dSDA;      // delayed versions of sSCL and sSDA
176
    reg        dscl_oen;        // delayed scl_oen
177
    reg        sda_chk;         // check SDA output (Multi-master arbitration)
178
    reg        clk_en;          // clock generation signals
179
    reg        slave_wait;      // slave inserts wait states
180
    reg [15:0] cnt;             // clock divider counter (synthesis)
181
    reg [13:0] filter_cnt;      // clock divider for filter
182 10 rherveille
 
183
 
184 74 rherveille
    // state machine variable
185
    reg [17:0] c_state; // synopsys enum_state
186 52 rherveille
 
187 74 rherveille
    //
188
    // module body
189
    //
190 10 rherveille
 
191 74 rherveille
    // whenever the slave is not ready it can delay the cycle by pulling SCL low
192
    // delay scl_oen
193
    always @(posedge clk)
194
      dscl_oen <= #1 scl_oen;
195 22 rherveille
 
196 74 rherveille
    // slave_wait is asserted when master wants to drive SCL high, but the slave pulls it low
197
    // slave_wait remains asserted until the slave releases SCL
198
    always @(posedge clk or negedge nReset)
199
      if (!nReset) slave_wait <= 1'b0;
200
      else         slave_wait <= (scl_oen & ~dscl_oen & ~sSCL) | (slave_wait & ~sSCL);
201 10 rherveille
 
202 74 rherveille
    // master drives SCL high, but another master pulls it low
203
    // master start counting down its low cycle now (clock synchronization)
204
    wire scl_sync   = dSCL & ~sSCL & scl_oen;
205 29 rherveille
 
206 10 rherveille
 
207 74 rherveille
    // generate clk enable signal
208
    always @(posedge clk or negedge nReset)
209
      if (~nReset)
210
      begin
211
          cnt    <= #1 16'h0;
212
          clk_en <= #1 1'b1;
213
      end
214
      else if (rst || ~|cnt || !ena || scl_sync)
215
      begin
216
          cnt    <= #1 clk_cnt;
217
          clk_en <= #1 1'b1;
218
      end
219
      else if (slave_wait)
220
      begin
221
          cnt    <= #1 cnt;
222
          clk_en <= #1 1'b0;
223
      end
224
      else
225
      begin
226
          cnt    <= #1 cnt - 16'h1;
227
          clk_en <= #1 1'b0;
228
      end
229 10 rherveille
 
230
 
231 74 rherveille
    // generate bus status controller
232 29 rherveille
 
233 74 rherveille
    // capture SDA and SCL
234
    // reduce metastability risk
235
    always @(posedge clk or negedge nReset)
236
      if (!nReset)
237
      begin
238
          cSCL <= #1 2'b00;
239
          cSDA <= #1 2'b00;
240
      end
241
      else if (rst)
242
      begin
243
          cSCL <= #1 2'b00;
244
          cSDA <= #1 2'b00;
245
      end
246
      else
247
      begin
248
          cSCL <= {cSCL[0],scl_i};
249
          cSDA <= {cSDA[0],sda_i};
250
      end
251 29 rherveille
 
252 35 rherveille
 
253 74 rherveille
    // filter SCL and SDA signals; (attempt to) remove glitches
254
    always @(posedge clk or negedge nReset)
255
      if      (!nReset     ) filter_cnt <= 14'h0;
256
      else if (rst || !ena ) filter_cnt <= 14'h0;
257
      else if (~|filter_cnt) filter_cnt <= clk_cnt >> 2; //16x I2C bus frequency
258
      else                   filter_cnt <= filter_cnt -1;
259 35 rherveille
 
260 10 rherveille
 
261 74 rherveille
    always @(posedge clk or negedge nReset)
262
      if (!nReset)
263
      begin
264
          fSCL <= 3'b111;
265
          fSDA <= 3'b111;
266
      end
267
      else if (rst)
268
      begin
269
          fSCL <= 3'b111;
270
          fSDA <= 3'b111;
271
      end
272
      else if (~|filter_cnt)
273
      begin
274
          fSCL <= {fSCL[1:0],cSCL[1]};
275
          fSDA <= {fSDA[1:0],cSDA[1]};
276
      end
277 10 rherveille
 
278 38 rherveille
 
279 74 rherveille
    // generate filtered SCL and SDA signals
280
    always @(posedge clk or negedge nReset)
281
      if (~nReset)
282
      begin
283
          sSCL <= #1 1'b1;
284
          sSDA <= #1 1'b1;
285 10 rherveille
 
286 74 rherveille
          dSCL <= #1 1'b1;
287
          dSDA <= #1 1'b1;
288
      end
289
      else if (rst)
290
      begin
291
          sSCL <= #1 1'b1;
292
          sSDA <= #1 1'b1;
293 29 rherveille
 
294 74 rherveille
          dSCL <= #1 1'b1;
295
          dSDA <= #1 1'b1;
296
      end
297
      else
298
      begin
299
          sSCL <= #1 &fSCL[2:1] | &fSCL[1:0] | (fSCL[2] & fSCL[0]);
300
          sSDA <= #1 &fSDA[2:1] | &fSDA[1:0] | (fSDA[2] & fSDA[0]);
301 29 rherveille
 
302 74 rherveille
          dSCL <= #1 sSCL;
303
          dSDA <= #1 sSDA;
304
      end
305 10 rherveille
 
306 74 rherveille
    // detect start condition => detect falling edge on SDA while SCL is high
307
    // detect stop condition => detect rising edge on SDA while SCL is high
308
    reg sta_condition;
309
    reg sto_condition;
310
    always @(posedge clk or negedge nReset)
311
      if (~nReset)
312
      begin
313
          sta_condition <= #1 1'b0;
314
          sto_condition <= #1 1'b0;
315
      end
316
      else if (rst)
317
      begin
318
          sta_condition <= #1 1'b0;
319
          sto_condition <= #1 1'b0;
320
      end
321
      else
322
      begin
323
          sta_condition <= #1 ~sSDA &  dSDA & sSCL;
324
          sto_condition <= #1  sSDA & ~dSDA & sSCL;
325
      end
326 10 rherveille
 
327 27 rherveille
 
328 74 rherveille
    // generate i2c bus busy signal
329
    always @(posedge clk or negedge nReset)
330
      if      (!nReset) busy <= #1 1'b0;
331
      else if (rst    ) busy <= #1 1'b0;
332
      else              busy <= #1 (sta_condition | busy) & ~sto_condition;
333 10 rherveille
 
334
 
335 74 rherveille
    // generate arbitration lost signal
336
    // aribitration lost when:
337
    // 1) master drives SDA high, but the i2c bus is low
338
    // 2) stop detected while not requested
339
    reg cmd_stop;
340
    always @(posedge clk or negedge nReset)
341
      if (~nReset)
342
          cmd_stop <= #1 1'b0;
343
      else if (rst)
344
          cmd_stop <= #1 1'b0;
345
      else if (clk_en)
346
          cmd_stop <= #1 cmd == `I2C_CMD_STOP;
347 10 rherveille
 
348 74 rherveille
    always @(posedge clk or negedge nReset)
349
      if (~nReset)
350
          al <= #1 1'b0;
351
      else if (rst)
352
          al <= #1 1'b0;
353
      else
354
          al <= #1 (sda_chk & ~sSDA & sda_oen) | (|c_state & sto_condition & ~cmd_stop);
355 10 rherveille
 
356
 
357 74 rherveille
    // generate dout signal (store SDA on rising edge of SCL)
358
    always @(posedge clk)
359
      if (sSCL & ~dSCL) dout <= #1 sSDA;
360 10 rherveille
 
361
 
362 74 rherveille
    // generate statemachine
363 10 rherveille
 
364 74 rherveille
    // nxt_state decoder
365
    parameter [17:0] idle    = 18'b0_0000_0000_0000_0000;
366
    parameter [17:0] start_a = 18'b0_0000_0000_0000_0001;
367
    parameter [17:0] start_b = 18'b0_0000_0000_0000_0010;
368
    parameter [17:0] start_c = 18'b0_0000_0000_0000_0100;
369
    parameter [17:0] start_d = 18'b0_0000_0000_0000_1000;
370
    parameter [17:0] start_e = 18'b0_0000_0000_0001_0000;
371
    parameter [17:0] stop_a  = 18'b0_0000_0000_0010_0000;
372
    parameter [17:0] stop_b  = 18'b0_0000_0000_0100_0000;
373
    parameter [17:0] stop_c  = 18'b0_0000_0000_1000_0000;
374
    parameter [17:0] stop_d  = 18'b0_0000_0001_0000_0000;
375
    parameter [17:0] rd_a    = 18'b0_0000_0010_0000_0000;
376
    parameter [17:0] rd_b    = 18'b0_0000_0100_0000_0000;
377
    parameter [17:0] rd_c    = 18'b0_0000_1000_0000_0000;
378
    parameter [17:0] rd_d    = 18'b0_0001_0000_0000_0000;
379
    parameter [17:0] wr_a    = 18'b0_0010_0000_0000_0000;
380
    parameter [17:0] wr_b    = 18'b0_0100_0000_0000_0000;
381
    parameter [17:0] wr_c    = 18'b0_1000_0000_0000_0000;
382
    parameter [17:0] wr_d    = 18'b1_0000_0000_0000_0000;
383 10 rherveille
 
384 74 rherveille
    always @(posedge clk or negedge nReset)
385
      if (!nReset)
386
      begin
387
          c_state <= #1 idle;
388
          cmd_ack <= #1 1'b0;
389
          scl_oen <= #1 1'b1;
390
          sda_oen <= #1 1'b1;
391
          sda_chk <= #1 1'b0;
392
      end
393
      else if (rst | al)
394
      begin
395
          c_state <= #1 idle;
396
          cmd_ack <= #1 1'b0;
397
          scl_oen <= #1 1'b1;
398
          sda_oen <= #1 1'b1;
399
          sda_chk <= #1 1'b0;
400
      end
401
      else
402
      begin
403
          cmd_ack   <= #1 1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle
404 10 rherveille
 
405 74 rherveille
          if (clk_en)
406
              case (c_state) // synopsys full_case parallel_case
407
                    // idle state
408
                    idle:
409
                    begin
410
                        case (cmd) // synopsys full_case parallel_case
411
                             `I2C_CMD_START: c_state <= #1 start_a;
412
                             `I2C_CMD_STOP:  c_state <= #1 stop_a;
413
                             `I2C_CMD_WRITE: c_state <= #1 wr_a;
414
                             `I2C_CMD_READ:  c_state <= #1 rd_a;
415
                             default:        c_state <= #1 idle;
416
                        endcase
417 10 rherveille
 
418 74 rherveille
                        scl_oen <= #1 scl_oen; // keep SCL in same state
419
                        sda_oen <= #1 sda_oen; // keep SDA in same state
420
                        sda_chk <= #1 1'b0;    // don't check SDA output
421
                    end
422 10 rherveille
 
423 74 rherveille
                    // start
424
                    start_a:
425
                    begin
426
                        c_state <= #1 start_b;
427
                        scl_oen <= #1 scl_oen; // keep SCL in same state
428
                        sda_oen <= #1 1'b1;    // set SDA high
429
                        sda_chk <= #1 1'b0;    // don't check SDA output
430
                    end
431 10 rherveille
 
432 74 rherveille
                    start_b:
433
                    begin
434
                        c_state <= #1 start_c;
435
                        scl_oen <= #1 1'b1; // set SCL high
436
                        sda_oen <= #1 1'b1; // keep SDA high
437
                        sda_chk <= #1 1'b0; // don't check SDA output
438
                    end
439 10 rherveille
 
440 74 rherveille
                    start_c:
441
                    begin
442
                        c_state <= #1 start_d;
443
                        scl_oen <= #1 1'b1; // keep SCL high
444
                        sda_oen <= #1 1'b0; // set SDA low
445
                        sda_chk <= #1 1'b0; // don't check SDA output
446
                    end
447 10 rherveille
 
448 74 rherveille
                    start_d:
449
                    begin
450
                        c_state <= #1 start_e;
451
                        scl_oen <= #1 1'b1; // keep SCL high
452
                        sda_oen <= #1 1'b0; // keep SDA low
453
                        sda_chk <= #1 1'b0; // don't check SDA output
454
                    end
455 10 rherveille
 
456 74 rherveille
                    start_e:
457
                    begin
458
                        c_state <= #1 idle;
459
                        cmd_ack <= #1 1'b1;
460
                        scl_oen <= #1 1'b0; // set SCL low
461
                        sda_oen <= #1 1'b0; // keep SDA low
462
                        sda_chk <= #1 1'b0; // don't check SDA output
463
                    end
464 10 rherveille
 
465 74 rherveille
                    // stop
466
                    stop_a:
467
                    begin
468
                        c_state <= #1 stop_b;
469
                        scl_oen <= #1 1'b0; // keep SCL low
470
                        sda_oen <= #1 1'b0; // set SDA low
471
                        sda_chk <= #1 1'b0; // don't check SDA output
472
                    end
473 10 rherveille
 
474 74 rherveille
                    stop_b:
475
                    begin
476
                        c_state <= #1 stop_c;
477
                        scl_oen <= #1 1'b1; // set SCL high
478
                        sda_oen <= #1 1'b0; // keep SDA low
479
                        sda_chk <= #1 1'b0; // don't check SDA output
480
                    end
481 10 rherveille
 
482 74 rherveille
                    stop_c:
483
                    begin
484
                        c_state <= #1 stop_d;
485
                        scl_oen <= #1 1'b1; // keep SCL high
486
                        sda_oen <= #1 1'b0; // keep SDA low
487
                        sda_chk <= #1 1'b0; // don't check SDA output
488
                    end
489 10 rherveille
 
490 74 rherveille
                    stop_d:
491
                    begin
492
                        c_state <= #1 idle;
493
                        cmd_ack <= #1 1'b1;
494
                        scl_oen <= #1 1'b1; // keep SCL high
495
                        sda_oen <= #1 1'b1; // set SDA high
496
                        sda_chk <= #1 1'b0; // don't check SDA output
497
                    end
498 10 rherveille
 
499 74 rherveille
                    // read
500
                    rd_a:
501
                    begin
502
                        c_state <= #1 rd_b;
503
                        scl_oen <= #1 1'b0; // keep SCL low
504
                        sda_oen <= #1 1'b1; // tri-state SDA
505
                        sda_chk <= #1 1'b0; // don't check SDA output
506
                    end
507 24 rherveille
 
508 74 rherveille
                    rd_b:
509
                    begin
510
                        c_state <= #1 rd_c;
511
                        scl_oen <= #1 1'b1; // set SCL high
512
                        sda_oen <= #1 1'b1; // keep SDA tri-stated
513
                        sda_chk <= #1 1'b0; // don't check SDA output
514
                    end
515 24 rherveille
 
516 74 rherveille
                    rd_c:
517
                    begin
518
                        c_state <= #1 rd_d;
519
                        scl_oen <= #1 1'b1; // keep SCL high
520
                        sda_oen <= #1 1'b1; // keep SDA tri-stated
521
                        sda_chk <= #1 1'b0; // don't check SDA output
522
                    end
523 24 rherveille
 
524 74 rherveille
                    rd_d:
525
                    begin
526
                        c_state <= #1 idle;
527
                        cmd_ack <= #1 1'b1;
528
                        scl_oen <= #1 1'b0; // set SCL low
529
                        sda_oen <= #1 1'b1; // keep SDA tri-stated
530
                        sda_chk <= #1 1'b0; // don't check SDA output
531
                    end
532 27 rherveille
 
533 74 rherveille
                    // write
534
                    wr_a:
535
                    begin
536
                        c_state <= #1 wr_b;
537
                        scl_oen <= #1 1'b0; // keep SCL low
538
                        sda_oen <= #1 din;  // set SDA
539
                        sda_chk <= #1 1'b0; // don't check SDA output (SCL low)
540
                    end
541 27 rherveille
 
542 74 rherveille
                    wr_b:
543
                    begin
544
                        c_state <= #1 wr_c;
545
                        scl_oen <= #1 1'b1; // set SCL high
546
                        sda_oen <= #1 din;  // keep SDA
547
                        sda_chk <= #1 1'b0; // don't check SDA output yet
548
                                            // allow some time for SDA and SCL to settle
549
                    end
550
 
551
                    wr_c:
552
                    begin
553
                        c_state <= #1 wr_d;
554
                        scl_oen <= #1 1'b1; // keep SCL high
555
                        sda_oen <= #1 din;
556
                        sda_chk <= #1 1'b1; // check SDA output
557
                    end
558
 
559
                    wr_d:
560
                    begin
561
                        c_state <= #1 idle;
562
                        cmd_ack <= #1 1'b1;
563
                        scl_oen <= #1 1'b0; // set SCL low
564
                        sda_oen <= #1 din;
565
                        sda_chk <= #1 1'b0; // don't check SDA output (SCL low)
566
                    end
567
 
568
              endcase
569
      end
570
 
571
 
572
    // assign scl and sda output (always gnd)
573
    assign scl_o = 1'b0;
574
    assign sda_o = 1'b0;
575
 
576 10 rherveille
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.