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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [rtl/] [verilog/] [i2c_master_slave/] [i2c_master_bit_ctrl.v] - Blame information for rev 807

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

Line No. Rev Author Line
1 408 julius
/////////////////////////////////////////////////////////////////////
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
//
40
//  $Id: i2c_master_bit_ctrl.v,v 1.14 2009-01-20 10:25:29 rherveille Exp $
41
//
42
//  $Date: 2009-01-20 10:25:29 $
43
//  $Revision: 1.14 $
44
//  $Author: rherveille $
45
//  $Locker:  $
46
//  $State: Exp $
47
//
48
// Change History:
49
//               $Log: $
50
//               Revision 1.14  2009/01/20 10:25:29  rherveille
51
//               Added clock synchronization logic
52
//               Fixed slave_wait signal
53
//
54
//               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
//               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
//               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
//               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
//               Revision 1.9  2003/03/10 14:26:37  rherveille
72
//               Fixed cmd_ack generation item (no bug).
73
//
74
//               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
//               Revision 1.7  2002/12/26 16:05:12  rherveille
78
//               Small code simplifications
79
//
80
//               Revision 1.6  2002/12/26 15:02:32  rherveille
81
//               Core is now a Multimaster I2C controller
82
//
83
//               Revision 1.5  2002/11/30 22:24:40  rherveille
84
//               Cleaned up code
85
//
86
//               Revision 1.4  2002/10/30 18:10:07  rherveille
87
//               Fixed some reported minor start/stop generation timing issuess.
88
//
89
//               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
//               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
 
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
// Timing:     Normal mode      Fast mode
128
///////////////////////////////////////////////////////////////////////
129
// 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
//
136
 
137
// synopsys translate_off
138
`include "timescale.v"
139
// synopsys translate_on
140
 
141
`include "i2c_master_slave_defines.v"
142
 
143
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
 
149
    input [15:0]      clk_cnt,  // clock prescale value
150
 
151
    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
 
156
    input             din,
157
    output reg        dout,
158
 
159
    input             scl_i,    // i2c clock line input
160
    output            scl_o,    // i2c clock line output
161
    output            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            sda_oen,  // i2c data line output enable (active low)
165
 
166
    output reg        slave_adr_received,
167
    output reg [7:0]  slave_adr,
168
    input             master_mode,
169
    output reg        cmd_slave_ack,
170
    input [1:0]       slave_cmd ,
171
    input             sl_wait,
172
    output            slave_reset
173
 
174
                            );
175
 
176
 
177
   //
178
   // variable declarations
179
   //
180
 
181
   reg [ 1:0]          cSCL, cSDA;      // capture SCL and SDA
182
   reg [ 2:0]          fSCL, fSDA;      // SCL and SDA filter inputs
183
   reg                sSCL, sSDA;      // filtered and synchronized SCL and SDA inputs
184
   reg                dSCL, dSDA;      // delayed versions of sSCL and sSDA
185
   reg                dscl_oen;        // delayed scl_oen
186
   reg                sda_chk;         // check SDA output (Multi-master arbitration)
187
   reg                clk_en;          // clock generation signals
188
   reg                slave_wait;      // slave inserts wait states
189
   reg [15:0]          cnt;             // clock divider counter (synthesis)
190
   reg [13:0]          filter_cnt;      // clock divider for filter
191
 
192
 
193
   // state machine variable
194
   reg [17:0]          c_state; // synopsys enum_state
195
   reg [4:0]           slave_state;
196
   //
197
   // module body
198
   //
199
 
200
   // whenever the slave is not ready it can delay the cycle by pulling SCL low
201
   // delay scl_oen
202
   always @(posedge clk)
203
     dscl_oen <=  scl_oen;
204
 
205 545 julius
   // slave_wait is asserted when master wants to drive SCL high, but the slave pulls it low
206 408 julius
   // slave_wait remains asserted until the slave releases SCL
207
   always @(posedge clk or negedge nReset)
208 545 julius
     if (!nReset) slave_wait <= 1'b0;
209
     else         slave_wait <= (scl_oen & ~dscl_oen & ~sSCL) | (slave_wait & ~sSCL);
210 408 julius
 
211
   // master drives SCL high, but another master pulls it low
212
   // master start counting down its low cycle now (clock synchronization)
213
   wire               scl_sync   = dSCL & ~sSCL & scl_oen;
214
 
215
 
216
   // generate clk enable signal
217
   always @(posedge clk or negedge nReset)
218
     if (~nReset)
219
       begin
220
          cnt    <=  16'h0;
221
          clk_en <=  1'b1;
222
       end
223
     else if (rst || ~|cnt || !ena || scl_sync)
224
       begin
225
          cnt    <=  clk_cnt;
226
          clk_en <=  1'b1;
227
       end
228
     else if (slave_wait)
229
       begin
230
          cnt    <=  cnt;
231
          clk_en <=  1'b0;
232
       end
233
     else
234
       begin
235
          cnt    <=  cnt - 16'h1;
236
          clk_en <=  1'b0;
237
       end
238
 
239 545 julius
 
240 408 julius
   // generate bus status controller
241
 
242
   // capture SDA and SCL
243
   // reduce metastability risk
244
   always @(posedge clk or negedge nReset)
245
     if (!nReset)
246
       begin
247
          cSCL <=  2'b00;
248
          cSDA <=  2'b00;
249
       end
250
     else if (rst)
251
       begin
252
          cSCL <=  2'b00;
253
          cSDA <=  2'b00;
254
       end
255
     else
256
       begin
257
          cSCL <= {cSCL[0],scl_i};
258
          cSDA <= {cSDA[0],sda_i};
259
       end
260
 
261
 
262
   // filter SCL and SDA signals; (attempt to) remove glitches
263
   always @(posedge clk or negedge nReset)
264
     if      (!nReset     ) filter_cnt <= 14'h0;
265
     else if (rst || !ena ) filter_cnt <= 14'h0;
266
     else if (~|filter_cnt) filter_cnt <= clk_cnt >> 2; //16x I2C bus frequency
267
     else                   filter_cnt <= filter_cnt -1;
268
 
269
 
270
   always @(posedge clk or negedge nReset)
271
     if (!nReset)
272
       begin
273
          fSCL <= 3'b111;
274
          fSDA <= 3'b111;
275
       end
276
     else if (rst)
277
       begin
278
          fSCL <= 3'b111;
279
          fSDA <= 3'b111;
280
       end
281
     else if (~|filter_cnt)
282
       begin
283
          fSCL <= {fSCL[1:0],cSCL[1]};
284
          fSDA <= {fSDA[1:0],cSDA[1]};
285
       end
286
 
287
 
288
   // generate filtered SCL and SDA signals
289
   always @(posedge clk or negedge nReset)
290
     if (~nReset)
291
       begin
292
          sSCL <=  1'b1;
293
          sSDA <=  1'b1;
294
 
295
          dSCL <=  1'b1;
296
          dSDA <=  1'b1;
297
       end
298
     else if (rst)
299
       begin
300
          sSCL <=  1'b1;
301
          sSDA <=  1'b1;
302
 
303
          dSCL <=  1'b1;
304
          dSDA <=  1'b1;
305
       end
306
     else
307
       begin
308
          sSCL <=  &fSCL[2:1] | &fSCL[1:0] | (fSCL[2] & fSCL[0]);
309
          sSDA <=  &fSDA[2:1] | &fSDA[1:0] | (fSDA[2] & fSDA[0]);
310
 
311
          dSCL <=  sSCL;
312
          dSDA <=  sSDA;
313
       end
314
 
315
   // detect start condition => detect falling edge on SDA while SCL is high
316
   // detect stop condition => detect rising edge on SDA while SCL is high
317
   reg sta_condition;
318
   reg sto_condition;
319
 
320
 
321
 
322
 
323
   always @(posedge clk or negedge nReset)
324
     if (~nReset)
325
       begin
326
          sta_condition <=  1'b0;
327
          sto_condition <=  1'b0;
328
       end
329
     else if (rst)
330
       begin
331
          sta_condition <=  1'b0;
332
          sto_condition <=  1'b0;
333
       end
334
     else
335
       begin
336
          sta_condition  <=  ~sSDA &  dSDA & sSCL;
337
          sto_condition  <=   sSDA & ~dSDA & sSCL;
338
       end
339
 
340
 
341
   // generate i2c bus busy signal
342
   always @(posedge clk or negedge nReset)
343
     if      (!nReset) busy <=  1'b0;
344
     else if (rst    ) busy <=  1'b0;
345
     else              busy <=  (sta_condition | busy) & ~sto_condition;
346
 
347
   //
348
   // generate arbitration lost signal
349
   // aribitration lost when:
350
   // 1) master drives SDA high, but the i2c bus is low
351
   // 2) stop detected while not requested
352
   reg cmd_stop;
353
   always @(posedge clk or negedge nReset)
354
     if (~nReset)
355
       cmd_stop <=  1'b0;
356
     else if (rst)
357
       cmd_stop <=  1'b0;
358
     else if (clk_en)
359
       cmd_stop <=  cmd == `I2C_CMD_STOP;
360
 
361
   always @(posedge clk or negedge nReset)
362
     if (~nReset)
363
       al <=  1'b0;
364
     else if (rst)
365
       al <=  1'b0;
366
     else
367
       al <=  (sda_chk & ~sSDA & sda_oen) | (|c_state & sto_condition & ~cmd_stop);
368
 
369
 
370
   // generate dout signal (store SDA on rising edge of SCL)
371
   always @(posedge clk)
372
     if (sSCL & ~dSCL) dout <=  sSDA;
373
 
374
 
375
   // generate statemachine
376
 
377
   // nxt_state decoder
378
   parameter [17:0] idle    = 18'b0_0000_0000_0000_0000;
379
   parameter [17:0] start_a = 18'b0_0000_0000_0000_0001;
380
   parameter [17:0] start_b = 18'b0_0000_0000_0000_0010;
381
   parameter [17:0] start_c = 18'b0_0000_0000_0000_0100;
382
   parameter [17:0] start_d = 18'b0_0000_0000_0000_1000;
383
   parameter [17:0] start_e = 18'b0_0000_0000_0001_0000;
384
   parameter [17:0] stop_a  = 18'b0_0000_0000_0010_0000;
385
   parameter [17:0] stop_b  = 18'b0_0000_0000_0100_0000;
386
   parameter [17:0] stop_c  = 18'b0_0000_0000_1000_0000;
387
   parameter [17:0] stop_d  = 18'b0_0000_0001_0000_0000;
388
   parameter [17:0] rd_a    = 18'b0_0000_0010_0000_0000;
389
   parameter [17:0] rd_b    = 18'b0_0000_0100_0000_0000;
390
   parameter [17:0] rd_c    = 18'b0_0000_1000_0000_0000;
391
   parameter [17:0] rd_d    = 18'b0_0001_0000_0000_0000;
392
   parameter [17:0] wr_a    = 18'b0_0010_0000_0000_0000;
393
   parameter [17:0] wr_b    = 18'b0_0100_0000_0000_0000;
394
   parameter [17:0] wr_c    = 18'b0_1000_0000_0000_0000;
395
   parameter [17:0] wr_d    = 18'b1_0000_0000_0000_0000;
396
   reg scl_oen_master ;
397
   reg sda_oen_master ;
398
   reg sda_oen_slave;
399
   reg scl_oen_slave;
400
 
401
   always @(posedge clk or negedge nReset)
402
     if (!nReset)
403
       begin
404
          c_state <=  idle;
405
          cmd_ack <=  1'b0;
406
          scl_oen_master <=  1'b1;
407
          sda_oen_master <=  1'b1;
408
          sda_chk <=  1'b0;
409
       end
410
     else if (rst | al)
411
       begin
412
          c_state <=  idle;
413
          cmd_ack <=  1'b0;
414
          scl_oen_master <=  1'b1;
415
          sda_oen_master <=  1'b1;
416
          sda_chk <=  1'b0;
417
       end
418
     else
419
       begin
420
          cmd_ack   <=  1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle
421
 
422
          if (clk_en )
423
            case (c_state) // synopsys full_case parallel_case
424
              // idle state
425
              idle:
426
                begin
427
                   case (cmd) // synopsys full_case parallel_case
428
                     `I2C_CMD_START: c_state <=  start_a;
429
                     `I2C_CMD_STOP:  c_state <=  stop_a;
430
                     `I2C_CMD_WRITE: c_state <=  wr_a;
431
                     `I2C_CMD_READ:  c_state <=  rd_a;
432
                     default:        c_state <=  idle;
433
                   endcase
434
 
435
                   scl_oen_master <=  scl_oen_master; // keep SCL in same state
436
                   sda_oen_master <=  sda_oen_master; // keep SDA in same state
437
                   sda_chk <=  1'b0;    // don't check SDA output
438
                end
439
 
440
              // start
441
              start_a:
442
                begin
443
                   c_state <=  start_b;
444
                   scl_oen_master <=  scl_oen_master; // keep SCL in same state
445
                   sda_oen_master <=  1'b1;    // set SDA high
446
                   sda_chk <=  1'b0;    // don't check SDA output
447
                end
448
 
449
              start_b:
450
                begin
451
                   c_state <=  start_c;
452
                   scl_oen_master <=  1'b1; // set SCL high
453
                   sda_oen_master <=  1'b1; // keep SDA high
454
                   sda_chk <=  1'b0; // don't check SDA output
455
                end
456
 
457
              start_c:
458
                begin
459
                   c_state <=  start_d;
460
                   scl_oen_master <=  1'b1; // keep SCL high
461
                   sda_oen_master <=  1'b0; // set SDA low
462
                   sda_chk <=  1'b0; // don't check SDA output
463
                end
464
 
465
              start_d:
466
                begin
467
                   c_state <=  start_e;
468
                   scl_oen_master <=  1'b1; // keep SCL high
469
                   sda_oen_master <=  1'b0; // keep SDA low
470
                   sda_chk <=  1'b0; // don't check SDA output
471
                end
472
 
473
              start_e:
474
                begin
475
                   c_state <=  idle;
476
                   cmd_ack <=  1'b1;
477
                   scl_oen_master <=  1'b0; // set SCL low
478
                   sda_oen_master <=  1'b0; // keep SDA low
479
                   sda_chk <=  1'b0; // don't check SDA output
480
                end
481
 
482
              // stop
483
              stop_a:
484
                begin
485
                   c_state <=  stop_b;
486
                   scl_oen_master <=  1'b0; // keep SCL low
487
                   sda_oen_master <=  1'b0; // set SDA low
488
                   sda_chk <=  1'b0; // don't check SDA output
489
                end
490
 
491
              stop_b:
492
                begin
493
                   c_state <=  stop_c;
494
                   scl_oen_master <=  1'b1; // set SCL high
495
                   sda_oen_master <=  1'b0; // keep SDA low
496
                   sda_chk <=  1'b0; // don't check SDA output
497
                end
498
 
499
              stop_c:
500
                begin
501
                   c_state <=  stop_d;
502
                   scl_oen_master <=  1'b1; // keep SCL high
503
                   sda_oen_master <=  1'b0; // keep SDA low
504
                   sda_chk <=  1'b0; // don't check SDA output
505
                end
506
 
507
              stop_d:
508
                begin
509
                   c_state <=  idle;
510
                   cmd_ack <=  1'b1;
511
                   scl_oen_master <=  1'b1; // keep SCL high
512
                   sda_oen_master <=  1'b1; // set SDA high
513
                   sda_chk <=  1'b0; // don't check SDA output
514
                end
515
 
516
              // read
517
              rd_a:
518
                begin
519
                   c_state <=  rd_b;
520
                   scl_oen_master <=  1'b0; // keep SCL low
521
                   sda_oen_master <=  1'b1; // tri-state SDA
522
                   sda_chk <=  1'b0; // don't check SDA output
523
                end
524
 
525
              rd_b:
526
                begin
527
                   c_state <=  rd_c;
528
                   scl_oen_master <=  1'b1; // set SCL high
529
                   sda_oen_master <=  1'b1; // keep SDA tri-stated
530
                   sda_chk <=  1'b0; // don't check SDA output
531
                end
532
 
533
              rd_c:
534
                begin
535
                   c_state <=  rd_d;
536
                   scl_oen_master <=  1'b1; // keep SCL high
537
                   sda_oen_master <=  1'b1; // keep SDA tri-stated
538
                   sda_chk <=  1'b0; // don't check SDA output
539
                end
540
 
541
              rd_d:
542
                begin
543
                   c_state <=  idle;
544
                   cmd_ack <=  1'b1;
545
                   scl_oen_master <=  1'b0; // set SCL low
546
                   sda_oen_master <=  1'b1; // keep SDA tri-stated
547
                   sda_chk <=  1'b0; // don't check SDA output
548
                end
549
 
550
              // write
551
              wr_a:
552
                begin
553
                   c_state <=  wr_b;
554
                   scl_oen_master <=  1'b0; // keep SCL low
555
                   sda_oen_master <=  din;  // set SDA
556
                   sda_chk <=  1'b0; // don't check SDA output (SCL low)
557
                end
558
 
559
              wr_b:
560
                begin
561
                   c_state <=  wr_c;
562
                   scl_oen_master <=  1'b1; // set SCL high
563
                   sda_oen_master <=  din;  // keep SDA
564
                   sda_chk <=  1'b0; // don't check SDA output yet
565
                   // allow some time for SDA and SCL to settle
566
                end
567
 
568
              wr_c:
569
                begin
570
                   c_state <=  wr_d;
571
                   scl_oen_master <=  1'b1; // keep SCL high
572
                   sda_oen_master <=  din;
573
                   sda_chk <=  1'b1; // check SDA output
574
                end
575
 
576
              wr_d:
577
                begin
578
                   c_state <=  idle;
579
                   cmd_ack <=  1'b1;
580
                   scl_oen_master <=  1'b0; // set SCL low
581
                   sda_oen_master <=  din;
582
                   sda_chk <=  1'b0; // don't check SDA output (SCL low)
583
                end
584
 
585
            endcase
586
 
587
 
588
 
589
       end
590
 
591
   //----------Addition for slave mode...
592
   reg [3:0] slave_cnt;
593
 
594
   //The SCL can only be driven when Master mode
595
 
596
   assign sda_oen = master_mode ? sda_oen_master : sda_oen_slave ;
597
   assign scl_oen = master_mode ? scl_oen_master : scl_oen_slave ;
598
   reg       slave_act;
599
   reg       slave_adr_received_d;
600
 
601
   //A 1 cycle pulse slave_adr_recived is generated when a slave adress is recvied after a startcommand.
602
 
603
   always @(posedge clk or negedge nReset)
604
     if (!nReset) begin
605
        slave_adr <=  8'h0;
606
        slave_cnt <=  4'h8;
607
        slave_adr_received <=  1'b0;
608
        slave_act <=  1'b0;
609
     end
610
     else begin
611
        slave_adr_received <=  1'b0;
612
 
613
        if ((sSCL & ~dSCL) && slave_cnt != 4'h0 && slave_act)    begin
614
           slave_adr <=  {slave_adr[6:0], sSDA};
615
           slave_cnt <=  slave_cnt -1;
616
        end
617
        else if (slave_cnt == 4'h0 && !sta_condition && slave_act) begin
618
           slave_adr_received <=  1'b1;
619
           slave_act <=  1'b0;
620
        end
621
 
622
        if (sta_condition) begin
623
           slave_cnt <=  4'h8;
624
           slave_adr <=  8'h0;
625
           slave_adr_received <=  1'b0;
626
           slave_act <=  1'b1;
627
        end
628
        if(sto_condition) begin
629
           slave_adr_received <=  1'b0;
630
           slave_act <=  1'b0;
631
        end
632
     end
633 545 julius
 
634
 
635
 
636 408 julius
   parameter [4:0] slave_idle    = 5'b0_0000;
637
   parameter [4:0] slave_wr      = 5'b0_0001;
638
   parameter [4:0] slave_wr_a    = 5'b0_0010;
639
   parameter [4:0] slave_rd      = 5'b0_0100;
640
   parameter [4:0] slave_rd_a    = 5'b0_1000;
641
   parameter [4:0] slave_wait_next_cmd_1   = 5'b1_0000;
642
   parameter [4:0] slave_wait_next_cmd_2   = 5'b1_0001;
643
 
644
   always @(posedge clk or negedge nReset)
645
     if (!nReset)
646
       begin
647
          slave_state <=  slave_idle;
648
          cmd_slave_ack   <=  1'b0;
649
          sda_oen_slave   <=  1'b1;
650
          scl_oen_slave   <=  1'b1;
651
       end
652
     else if (rst | sta_condition || !ena)
653
       begin
654
          slave_state <=  slave_idle;
655
          cmd_slave_ack   <=  1'b0;
656
          sda_oen_slave   <=  1'b1;
657
          scl_oen_slave   <=  1'b1;
658
       end
659
     else
660
       begin
661
          cmd_slave_ack   <=  1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle
662
 
663
          if (sl_wait)
664
            scl_oen_slave   <=  1'b0;
665
          else
666
            scl_oen_slave   <=  1'b1;
667
 
668
          case (slave_state)
669
            slave_idle:
670
 
671
              begin
672
 
673
                 case (slave_cmd) // synopsys full_case parallel_case                             
674
                   `I2C_SLAVE_CMD_WRITE: slave_state <=  slave_wr;
675 545 julius
                   `I2C_SLAVE_CMD_READ:
676
                     begin
677
                        slave_state <=  slave_rd;
678
                        // Restore SDA high here in case we're got it low
679
                        sda_oen_slave <=  1'b1;
680
                     end
681 408 julius
                   default:
682
                     begin
683
                        slave_state <=  slave_idle;
684
                        sda_oen_slave <=  1'b1; // Moved this here, JB
685
                     end
686
                 endcase
687
              end
688
 
689
            slave_wr:
690
              begin
691 545 julius
                 if (~sSCL & ~dSCL)  begin //SCL == LOW                         
692 408 julius
                    slave_state <=  slave_wr_a;
693
                    sda_oen_slave <=  din;
694
                 end
695
              end
696
 
697
            slave_wr_a:
698
              begin
699
                 if (~sSCL & dSCL)  begin //SCL FALLING EDGE
700
                    cmd_slave_ack <=  1'b1;
701
                    slave_state <=  slave_wait_next_cmd_1;
702
                 end
703
              end
704
 
705
            slave_wait_next_cmd_1:
706
              slave_state <=  slave_wait_next_cmd_2;
707
 
708
            slave_wait_next_cmd_2:
709
              slave_state <=  slave_idle;
710
 
711
 
712
            slave_rd:
713
              begin
714 545 julius
                 if (sSCL & ~dSCL)  begin   // SCL Rising edge             
715 408 julius
                    slave_state <=  slave_rd_a;
716
                 end
717
              end
718
 
719
            slave_rd_a:
720
              begin
721 545 julius
                 if (~sSCL & dSCL)  begin       // SCL falling edge                  
722 408 julius
                    cmd_slave_ack <=  1'b1;
723
                    slave_state <=  slave_wait_next_cmd_1;
724
                 end
725
              end
726
          endcase // case (slave_state)
727
       end
728
 
729
   assign slave_reset = sta_condition | sto_condition;
730
 
731
   // assign scl and sda output (always gnd)
732
   assign scl_o = 1'b0;
733
   assign sda_o = 1'b0;
734
 
735
endmodule

powered by: WebSVN 2.1.0

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