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 543

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 543 julius
   // A counter to indicate a too-long wait has occurred for the next set
197
   // of clocks for the read, and in fact it's likely the master has simply
198
   // released SCL and wants to issue a stop.
199
   reg [3:0]           slave_read_timeout_cnt;
200
   wire               slave_read_timeout;
201
 
202
 
203
 
204 408 julius
   //
205
   // module body
206
   //
207
 
208
   // whenever the slave is not ready it can delay the cycle by pulling SCL low
209
   // delay scl_oen
210
   always @(posedge clk)
211
     dscl_oen <=  scl_oen;
212
 
213 543 julius
   // slave_wait is asserted when master wants to drive SCL high, but the 
214
   // slave pulls it low.
215 408 julius
   // slave_wait remains asserted until the slave releases SCL
216
   always @(posedge clk or negedge nReset)
217 543 julius
     if (!nReset)
218
       slave_wait <= 1'b0;
219
     else
220
       slave_wait <= (scl_oen & ~dscl_oen & ~sSCL) |
221
                     (slave_wait & ~sSCL) ;
222 408 julius
 
223
   // master drives SCL high, but another master pulls it low
224
   // master start counting down its low cycle now (clock synchronization)
225
   wire               scl_sync   = dSCL & ~sSCL & scl_oen;
226
 
227
 
228
   // generate clk enable signal
229
   always @(posedge clk or negedge nReset)
230
     if (~nReset)
231
       begin
232
          cnt    <=  16'h0;
233
          clk_en <=  1'b1;
234
       end
235
     else if (rst || ~|cnt || !ena || scl_sync)
236
       begin
237
          cnt    <=  clk_cnt;
238
          clk_en <=  1'b1;
239
       end
240
     else if (slave_wait)
241
       begin
242
          cnt    <=  cnt;
243
          clk_en <=  1'b0;
244
       end
245
     else
246
       begin
247
          cnt    <=  cnt - 16'h1;
248
          clk_en <=  1'b0;
249
       end
250
 
251
   // generate bus status controller
252
 
253
   // capture SDA and SCL
254
   // reduce metastability risk
255
   always @(posedge clk or negedge nReset)
256
     if (!nReset)
257
       begin
258
          cSCL <=  2'b00;
259
          cSDA <=  2'b00;
260
       end
261
     else if (rst)
262
       begin
263
          cSCL <=  2'b00;
264
          cSDA <=  2'b00;
265
       end
266
     else
267
       begin
268
          cSCL <= {cSCL[0],scl_i};
269
          cSDA <= {cSDA[0],sda_i};
270
       end
271
 
272
 
273
   // filter SCL and SDA signals; (attempt to) remove glitches
274
   always @(posedge clk or negedge nReset)
275
     if      (!nReset     ) filter_cnt <= 14'h0;
276
     else if (rst || !ena ) filter_cnt <= 14'h0;
277
     else if (~|filter_cnt) filter_cnt <= clk_cnt >> 2; //16x I2C bus frequency
278
     else                   filter_cnt <= filter_cnt -1;
279
 
280
 
281
   always @(posedge clk or negedge nReset)
282
     if (!nReset)
283
       begin
284
          fSCL <= 3'b111;
285
          fSDA <= 3'b111;
286
       end
287
     else if (rst)
288
       begin
289
          fSCL <= 3'b111;
290
          fSDA <= 3'b111;
291
       end
292
     else if (~|filter_cnt)
293
       begin
294
          fSCL <= {fSCL[1:0],cSCL[1]};
295
          fSDA <= {fSDA[1:0],cSDA[1]};
296
       end
297
 
298
 
299
   // generate filtered SCL and SDA signals
300
   always @(posedge clk or negedge nReset)
301
     if (~nReset)
302
       begin
303
          sSCL <=  1'b1;
304
          sSDA <=  1'b1;
305
 
306
          dSCL <=  1'b1;
307
          dSDA <=  1'b1;
308
       end
309
     else if (rst)
310
       begin
311
          sSCL <=  1'b1;
312
          sSDA <=  1'b1;
313
 
314
          dSCL <=  1'b1;
315
          dSDA <=  1'b1;
316
       end
317
     else
318
       begin
319
          sSCL <=  &fSCL[2:1] | &fSCL[1:0] | (fSCL[2] & fSCL[0]);
320
          sSDA <=  &fSDA[2:1] | &fSDA[1:0] | (fSDA[2] & fSDA[0]);
321
 
322
          dSCL <=  sSCL;
323
          dSDA <=  sSDA;
324
       end
325
 
326
   // detect start condition => detect falling edge on SDA while SCL is high
327
   // detect stop condition => detect rising edge on SDA while SCL is high
328
   reg sta_condition;
329
   reg sto_condition;
330
 
331
 
332
 
333
 
334
   always @(posedge clk or negedge nReset)
335
     if (~nReset)
336
       begin
337
          sta_condition <=  1'b0;
338
          sto_condition <=  1'b0;
339
       end
340
     else if (rst)
341
       begin
342
          sta_condition <=  1'b0;
343
          sto_condition <=  1'b0;
344
       end
345
     else
346
       begin
347
          sta_condition  <=  ~sSDA &  dSDA & sSCL;
348
          sto_condition  <=   sSDA & ~dSDA & sSCL;
349
       end
350
 
351
 
352
   // generate i2c bus busy signal
353
   always @(posedge clk or negedge nReset)
354
     if      (!nReset) busy <=  1'b0;
355
     else if (rst    ) busy <=  1'b0;
356
     else              busy <=  (sta_condition | busy) & ~sto_condition;
357
 
358
   //
359
   // generate arbitration lost signal
360
   // aribitration lost when:
361
   // 1) master drives SDA high, but the i2c bus is low
362
   // 2) stop detected while not requested
363
   reg cmd_stop;
364
   always @(posedge clk or negedge nReset)
365
     if (~nReset)
366
       cmd_stop <=  1'b0;
367
     else if (rst)
368
       cmd_stop <=  1'b0;
369
     else if (clk_en)
370
       cmd_stop <=  cmd == `I2C_CMD_STOP;
371
 
372
   always @(posedge clk or negedge nReset)
373
     if (~nReset)
374
       al <=  1'b0;
375
     else if (rst)
376
       al <=  1'b0;
377
     else
378
       al <=  (sda_chk & ~sSDA & sda_oen) | (|c_state & sto_condition & ~cmd_stop);
379
 
380
 
381
   // generate dout signal (store SDA on rising edge of SCL)
382
   always @(posedge clk)
383
     if (sSCL & ~dSCL) dout <=  sSDA;
384
 
385
 
386
   // generate statemachine
387
 
388
   // nxt_state decoder
389
   parameter [17:0] idle    = 18'b0_0000_0000_0000_0000;
390
   parameter [17:0] start_a = 18'b0_0000_0000_0000_0001;
391
   parameter [17:0] start_b = 18'b0_0000_0000_0000_0010;
392
   parameter [17:0] start_c = 18'b0_0000_0000_0000_0100;
393
   parameter [17:0] start_d = 18'b0_0000_0000_0000_1000;
394
   parameter [17:0] start_e = 18'b0_0000_0000_0001_0000;
395
   parameter [17:0] stop_a  = 18'b0_0000_0000_0010_0000;
396
   parameter [17:0] stop_b  = 18'b0_0000_0000_0100_0000;
397
   parameter [17:0] stop_c  = 18'b0_0000_0000_1000_0000;
398
   parameter [17:0] stop_d  = 18'b0_0000_0001_0000_0000;
399
   parameter [17:0] rd_a    = 18'b0_0000_0010_0000_0000;
400
   parameter [17:0] rd_b    = 18'b0_0000_0100_0000_0000;
401
   parameter [17:0] rd_c    = 18'b0_0000_1000_0000_0000;
402
   parameter [17:0] rd_d    = 18'b0_0001_0000_0000_0000;
403
   parameter [17:0] wr_a    = 18'b0_0010_0000_0000_0000;
404
   parameter [17:0] wr_b    = 18'b0_0100_0000_0000_0000;
405
   parameter [17:0] wr_c    = 18'b0_1000_0000_0000_0000;
406
   parameter [17:0] wr_d    = 18'b1_0000_0000_0000_0000;
407
   reg scl_oen_master ;
408
   reg sda_oen_master ;
409
   reg sda_oen_slave;
410
   reg scl_oen_slave;
411
 
412
   always @(posedge clk or negedge nReset)
413
     if (!nReset)
414
       begin
415
          c_state <=  idle;
416
          cmd_ack <=  1'b0;
417
          scl_oen_master <=  1'b1;
418
          sda_oen_master <=  1'b1;
419
          sda_chk <=  1'b0;
420
       end
421
     else if (rst | al)
422
       begin
423
          c_state <=  idle;
424
          cmd_ack <=  1'b0;
425
          scl_oen_master <=  1'b1;
426
          sda_oen_master <=  1'b1;
427
          sda_chk <=  1'b0;
428
       end
429
     else
430
       begin
431
          cmd_ack   <=  1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle
432
 
433
          if (clk_en )
434
            case (c_state) // synopsys full_case parallel_case
435
              // idle state
436
              idle:
437
                begin
438
                   case (cmd) // synopsys full_case parallel_case
439
                     `I2C_CMD_START: c_state <=  start_a;
440
                     `I2C_CMD_STOP:  c_state <=  stop_a;
441
                     `I2C_CMD_WRITE: c_state <=  wr_a;
442
                     `I2C_CMD_READ:  c_state <=  rd_a;
443
                     default:        c_state <=  idle;
444
                   endcase
445
 
446
                   scl_oen_master <=  scl_oen_master; // keep SCL in same state
447
                   sda_oen_master <=  sda_oen_master; // keep SDA in same state
448
                   sda_chk <=  1'b0;    // don't check SDA output
449
                end
450
 
451
              // start
452
              start_a:
453
                begin
454
                   c_state <=  start_b;
455
                   scl_oen_master <=  scl_oen_master; // keep SCL in same state
456
                   sda_oen_master <=  1'b1;    // set SDA high
457
                   sda_chk <=  1'b0;    // don't check SDA output
458
                end
459
 
460
              start_b:
461
                begin
462
                   c_state <=  start_c;
463
                   scl_oen_master <=  1'b1; // set SCL high
464
                   sda_oen_master <=  1'b1; // keep SDA high
465
                   sda_chk <=  1'b0; // don't check SDA output
466
                end
467
 
468
              start_c:
469
                begin
470
                   c_state <=  start_d;
471
                   scl_oen_master <=  1'b1; // keep SCL high
472
                   sda_oen_master <=  1'b0; // set SDA low
473
                   sda_chk <=  1'b0; // don't check SDA output
474
                end
475
 
476
              start_d:
477
                begin
478
                   c_state <=  start_e;
479
                   scl_oen_master <=  1'b1; // keep SCL high
480
                   sda_oen_master <=  1'b0; // keep SDA low
481
                   sda_chk <=  1'b0; // don't check SDA output
482
                end
483
 
484
              start_e:
485
                begin
486
                   c_state <=  idle;
487
                   cmd_ack <=  1'b1;
488
                   scl_oen_master <=  1'b0; // set SCL low
489
                   sda_oen_master <=  1'b0; // keep SDA low
490
                   sda_chk <=  1'b0; // don't check SDA output
491
                end
492
 
493
              // stop
494
              stop_a:
495
                begin
496
                   c_state <=  stop_b;
497
                   scl_oen_master <=  1'b0; // keep SCL low
498
                   sda_oen_master <=  1'b0; // set SDA low
499
                   sda_chk <=  1'b0; // don't check SDA output
500
                end
501
 
502
              stop_b:
503
                begin
504
                   c_state <=  stop_c;
505
                   scl_oen_master <=  1'b1; // set SCL high
506
                   sda_oen_master <=  1'b0; // keep SDA low
507
                   sda_chk <=  1'b0; // don't check SDA output
508
                end
509
 
510
              stop_c:
511
                begin
512
                   c_state <=  stop_d;
513
                   scl_oen_master <=  1'b1; // keep SCL high
514
                   sda_oen_master <=  1'b0; // keep SDA low
515
                   sda_chk <=  1'b0; // don't check SDA output
516
                end
517
 
518
              stop_d:
519
                begin
520
                   c_state <=  idle;
521
                   cmd_ack <=  1'b1;
522
                   scl_oen_master <=  1'b1; // keep SCL high
523
                   sda_oen_master <=  1'b1; // set SDA high
524
                   sda_chk <=  1'b0; // don't check SDA output
525
                end
526
 
527
              // read
528
              rd_a:
529
                begin
530
                   c_state <=  rd_b;
531
                   scl_oen_master <=  1'b0; // keep SCL low
532
                   sda_oen_master <=  1'b1; // tri-state SDA
533
                   sda_chk <=  1'b0; // don't check SDA output
534
                end
535
 
536
              rd_b:
537
                begin
538
                   c_state <=  rd_c;
539
                   scl_oen_master <=  1'b1; // set SCL high
540
                   sda_oen_master <=  1'b1; // keep SDA tri-stated
541
                   sda_chk <=  1'b0; // don't check SDA output
542
                end
543
 
544
              rd_c:
545
                begin
546
                   c_state <=  rd_d;
547
                   scl_oen_master <=  1'b1; // keep SCL high
548
                   sda_oen_master <=  1'b1; // keep SDA tri-stated
549
                   sda_chk <=  1'b0; // don't check SDA output
550
                end
551
 
552
              rd_d:
553
                begin
554
                   c_state <=  idle;
555
                   cmd_ack <=  1'b1;
556
                   scl_oen_master <=  1'b0; // set SCL low
557
                   sda_oen_master <=  1'b1; // keep SDA tri-stated
558
                   sda_chk <=  1'b0; // don't check SDA output
559
                end
560
 
561
              // write
562
              wr_a:
563
                begin
564
                   c_state <=  wr_b;
565
                   scl_oen_master <=  1'b0; // keep SCL low
566
                   sda_oen_master <=  din;  // set SDA
567
                   sda_chk <=  1'b0; // don't check SDA output (SCL low)
568
                end
569
 
570
              wr_b:
571
                begin
572
                   c_state <=  wr_c;
573
                   scl_oen_master <=  1'b1; // set SCL high
574
                   sda_oen_master <=  din;  // keep SDA
575
                   sda_chk <=  1'b0; // don't check SDA output yet
576
                   // allow some time for SDA and SCL to settle
577
                end
578
 
579
              wr_c:
580
                begin
581
                   c_state <=  wr_d;
582
                   scl_oen_master <=  1'b1; // keep SCL high
583
                   sda_oen_master <=  din;
584
                   sda_chk <=  1'b1; // check SDA output
585
                end
586
 
587
              wr_d:
588
                begin
589
                   c_state <=  idle;
590
                   cmd_ack <=  1'b1;
591
                   scl_oen_master <=  1'b0; // set SCL low
592
                   sda_oen_master <=  din;
593
                   sda_chk <=  1'b0; // don't check SDA output (SCL low)
594
                end
595
 
596
            endcase
597
 
598
 
599
 
600
       end
601
 
602
   //----------Addition for slave mode...
603
   reg [3:0] slave_cnt;
604
 
605
   //The SCL can only be driven when Master mode
606
 
607
   assign sda_oen = master_mode ? sda_oen_master : sda_oen_slave ;
608
   assign scl_oen = master_mode ? scl_oen_master : scl_oen_slave ;
609
   reg       slave_act;
610
   reg       slave_adr_received_d;
611
 
612
   //A 1 cycle pulse slave_adr_recived is generated when a slave adress is recvied after a startcommand.
613
 
614
   always @(posedge clk or negedge nReset)
615
     if (!nReset) begin
616
        slave_adr <=  8'h0;
617
        slave_cnt <=  4'h8;
618
        slave_adr_received <=  1'b0;
619
        slave_act <=  1'b0;
620
     end
621
     else begin
622
        slave_adr_received <=  1'b0;
623
 
624
        if ((sSCL & ~dSCL) && slave_cnt != 4'h0 && slave_act)    begin
625
           slave_adr <=  {slave_adr[6:0], sSDA};
626
           slave_cnt <=  slave_cnt -1;
627
        end
628
        else if (slave_cnt == 4'h0 && !sta_condition && slave_act) begin
629
           slave_adr_received <=  1'b1;
630
           slave_act <=  1'b0;
631
        end
632
 
633
        if (sta_condition) begin
634
           slave_cnt <=  4'h8;
635
           slave_adr <=  8'h0;
636
           slave_adr_received <=  1'b0;
637
           slave_act <=  1'b1;
638
        end
639
        if(sto_condition) begin
640
           slave_adr_received <=  1'b0;
641
           slave_act <=  1'b0;
642
        end
643
     end
644 543 julius
 
645 408 julius
   parameter [4:0] slave_idle    = 5'b0_0000;
646
   parameter [4:0] slave_wr      = 5'b0_0001;
647
   parameter [4:0] slave_wr_a    = 5'b0_0010;
648
   parameter [4:0] slave_rd      = 5'b0_0100;
649
   parameter [4:0] slave_rd_a    = 5'b0_1000;
650
   parameter [4:0] slave_wait_next_cmd_1   = 5'b1_0000;
651
   parameter [4:0] slave_wait_next_cmd_2   = 5'b1_0001;
652 543 julius
 
653 408 julius
 
654 543 julius
   // Slave timeout counter during read
655 408 julius
   always @(posedge clk or negedge nReset)
656 543 julius
     if (~nReset)
657
       slave_read_timeout_cnt <= 0;
658
     else if (rst)
659
       slave_read_timeout_cnt <= 0;
660
     else if (slave_state==slave_wr)
661
       slave_read_timeout_cnt <= 0;
662
     else if (slave_state==slave_wr_a && sSCL && cnt==1)
663
       slave_read_timeout_cnt <= slave_read_timeout_cnt + 1;
664
 
665
   assign slave_read_timeout =  (&slave_read_timeout_cnt) & cnt==1;
666
 
667
   always @(posedge clk or negedge nReset)
668 408 julius
     if (!nReset)
669
       begin
670
          slave_state <=  slave_idle;
671
          cmd_slave_ack   <=  1'b0;
672
          sda_oen_slave   <=  1'b1;
673
          scl_oen_slave   <=  1'b1;
674
       end
675
     else if (rst | sta_condition || !ena)
676
       begin
677
          slave_state <=  slave_idle;
678
          cmd_slave_ack   <=  1'b0;
679
          sda_oen_slave   <=  1'b1;
680
          scl_oen_slave   <=  1'b1;
681
       end
682
     else
683
       begin
684
          cmd_slave_ack   <=  1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle
685
 
686
          if (sl_wait)
687
            scl_oen_slave   <=  1'b0;
688
          else
689
            scl_oen_slave   <=  1'b1;
690
 
691
          case (slave_state)
692
            slave_idle:
693
 
694
              begin
695
 
696
                 case (slave_cmd) // synopsys full_case parallel_case                             
697
                   `I2C_SLAVE_CMD_WRITE: slave_state <=  slave_wr;
698
                   `I2C_SLAVE_CMD_READ:  slave_state <=  slave_rd;
699
                   default:
700
                     begin
701
                        slave_state <=  slave_idle;
702
                        sda_oen_slave <=  1'b1; // Moved this here, JB
703
                     end
704
                 endcase
705
              end
706
 
707
            slave_wr:
708
              begin
709
                 if (~sSCL & ~dSCL)  begin //SCL = LOW                         
710
                    slave_state <=  slave_wr_a;
711
                    sda_oen_slave <=  din;
712
                 end
713
              end
714
 
715
            slave_wr_a:
716
              begin
717
                 if (~sSCL & dSCL)  begin //SCL FALLING EDGE
718
                    cmd_slave_ack <=  1'b1;
719
                    slave_state <=  slave_wait_next_cmd_1;
720 543 julius
                 end
721
                 // Timeout! Go back to idle, release SDA
722
                 else if(slave_read_timeout) begin
723
                    slave_state <= slave_idle;
724
                    sda_oen_slave <= 1;
725 408 julius
                 end
726
              end
727
 
728
            slave_wait_next_cmd_1:
729
              slave_state <=  slave_wait_next_cmd_2;
730
 
731
            slave_wait_next_cmd_2:
732
              slave_state <=  slave_idle;
733
 
734
 
735
            slave_rd:
736
              begin
737
                 if (sSCL & ~dSCL)  begin
738
                    slave_state <=  slave_rd_a;
739
                 end
740
              end
741
 
742
            slave_rd_a:
743
              begin
744
                 if (~sSCL & dSCL)  begin
745
                    cmd_slave_ack <=  1'b1;
746
                    slave_state <=  slave_wait_next_cmd_1;
747
                 end
748
              end
749
          endcase // case (slave_state)
750
       end
751
 
752
   assign slave_reset = sta_condition | sto_condition;
753
 
754
   // assign scl and sda output (always gnd)
755
   assign scl_o = 1'b0;
756
   assign sda_o = 1'b0;
757
 
758
endmodule

powered by: WebSVN 2.1.0

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