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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 408 julius
/////////////////////////////////////////////////////////////////////
2
////                                                             ////
3
////  WISHBONE rev.B2 compliant I2C Master byte-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_byte_ctrl.v,v 1.8 2009-01-19 20:29:26 rherveille Exp $
41
//
42
//  $Date: 2009-01-19 20:29:26 $
43
//  $Revision: 1.8 $
44
//  $Author: rherveille $
45
//  $Locker:  $
46
//  $State: Exp $
47
//
48
// Change History:
49
//               $Log: not supported by cvs2svn $
50
//               Revision 1.7  2004/02/18 11:40:46  rherveille
51
//               Fixed a potential bug in the statemachine. During a 'stop' 2 cmd_ack signals were generated. Possibly canceling a new start command.
52
//
53
//               Revision 1.6  2003/08/09 07:01:33  rherveille
54
//               Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
55
//               Fixed a potential bug in the byte controller's host-acknowledge generation.
56
//
57
//               Revision 1.5  2002/12/26 15:02:32  rherveille
58
//               Core is now a Multimaster I2C controller
59
//
60
//               Revision 1.4  2002/11/30 22:24:40  rherveille
61
//               Cleaned up code
62
//
63
//               Revision 1.3  2001/11/05 11:59:25  rherveille
64
//               Fixed wb_ack_o generation bug.
65
//               Fixed bug in the byte_controller statemachine.
66
//               Added headers.
67
//
68
 
69
// synopsys translate_off
70
`include "timescale.v"
71
// synopsys translate_on
72
 
73
`include "i2c_master_slave_defines.v"
74
 
75
module i2c_master_byte_ctrl
76
  (
77
   clk, my_addr, rst, nReset, ena, clk_cnt, start, stop, read, write, ack_in,
78
   din, cmd_ack, ack_out, dout, i2c_busy, i2c_al, scl_i, sl_cont, scl_o,
79
   scl_oen, sda_i, sda_o, sda_oen,slave_dat_req, slave_en, slave_dat_avail,
80
   slave_act, slave_cmd_ack
81
   );
82
 
83
 
84
   //
85
   // inputs & outputs
86
   //
87
   input clk;     // master clock
88
   input my_addr; // Slave address input
89
   input rst;     // synchronous active high reset
90
   input nReset;  // asynchronous active low reset
91
   input ena;     // core enable signal
92
   input sl_cont;
93
   input [15:0] clk_cnt; // 4x SCL
94
 
95
   // control inputs
96
   input        start;
97
   input        stop;
98
   input        read;
99
   input        write;
100
   input        ack_in;
101
   input [7:0]   din;
102
 
103
   // status outputs
104
   output       cmd_ack;
105
   reg          cmd_ack;
106
   output       ack_out;
107
   reg          ack_out;
108
   output       i2c_busy;
109
   output       i2c_al;
110
   output [7:0] dout;
111
 
112
   // I2C signals
113
   input        scl_i;
114
   output       scl_o;
115
   output       scl_oen;
116
   input        sda_i;
117
   output       sda_o;
118
   output       sda_oen;
119
   input        slave_en;
120
   output reg   slave_dat_req;
121
   output reg   slave_dat_avail;
122
   output reg   slave_act;
123
   output reg   slave_cmd_ack;
124
   //
125
   // Variable declarations
126
   //
127
 
128
   // statemachine
129
   parameter [9:0] ST_IDLE       = 10'b00_0000_0000;
130
   parameter [9:0] ST_START      = 10'b00_0000_0001;
131
   parameter [9:0] ST_READ       = 10'b00_0000_0010;
132
   parameter [9:0] ST_WRITE      = 10'b00_0000_0100;
133
   parameter [9:0] ST_ACK        = 10'b00_0000_1000;
134
   parameter [9:0] ST_STOP       = 10'b00_0001_0000;
135
   parameter [9:0] ST_SL_ACK     = 10'b00_0010_0000;
136
   parameter [9:0] ST_SL_RD      = 10'b00_0100_0000;
137
   parameter [9:0] ST_SL_WR      = 10'b00_1000_0000;
138
   parameter [9:0] ST_SL_WAIT    = 10'b01_0000_0000;
139
   parameter [9:0] ST_SL_PRELOAD = 10'b10_0000_0000;
140
 
141
 
142
   reg          sl_wait;
143
   // signals for bit_controller
144
   wire [6:0]    my_addr;
145
   reg [3:0]     core_cmd;
146
   reg          core_txd;
147
   wire         core_ack, core_rxd;
148
   wire         sl_cont;
149
   // signals for shift register
150
   reg [7:0]     sr; //8bit shift register
151
   reg          shift, ld;
152
   reg          master_mode;
153
   reg [1:0]     slave_cmd_out;
154
   // signals for state machine
155
   wire         go;
156
   reg [2:0]     dcnt;
157
   wire         cnt_done;
158
   wire         slave_ack;
159
 
160
 
161
   //Slave signals
162
   wire         slave_adr_received;
163
   wire [7:0]    slave_adr;
164
 
165
 
166
   reg [1:0]     slave_cmd;
167
   //
168
   // Module body
169
   //
170
 
171
   // hookup bit_controller
172
   i2c_master_bit_ctrl bit_controller
173
     (
174
      .clk     ( clk      ),
175
      .rst     ( rst      ),
176
      .nReset  ( nReset   ),
177
      .ena     ( ena      ),
178
      .clk_cnt ( clk_cnt  ),
179
      .cmd     ( core_cmd ),
180
      .cmd_ack ( core_ack ),
181
      .busy    ( i2c_busy ),
182
      .al      ( i2c_al   ),
183
      .din     ( core_txd   ),
184
      .dout    ( core_rxd ),
185
      .scl_i   ( scl_i    ),
186
      .scl_o   ( scl_o    ),
187
      .scl_oen ( scl_oen  ),
188
      .sda_i   ( sda_i    ),
189
      .sda_o   ( sda_o    ),
190
      .sda_oen ( sda_oen  ),
191
      .slave_adr_received ( slave_adr_received  ),
192
      .slave_adr  ( slave_adr  ),
193
      .master_mode (master_mode),
194
      .cmd_slave_ack (slave_ack),
195
      .slave_cmd (slave_cmd_out),
196
      .sl_wait (sl_wait),
197
      .slave_reset (slave_reset)
198
      );
199
 
200
   reg          slave_adr_received_d;
201
   // generate go-signal
202
   assign go = (read | write | stop) & ~cmd_ack;
203
 
204
   // assign dout output to shift-register
205
   assign dout = sr;
206
 
207
   always @(posedge clk or negedge nReset)
208
     if (!nReset)
209
       slave_adr_received_d <=  1'b0;
210
     else
211
       slave_adr_received_d <=   slave_adr_received;
212
 
213
   // generate shift register
214
   always @(posedge clk or negedge nReset)
215
     if (!nReset)
216
       sr <=  8'h0;
217
     else if (rst)
218
       sr <=  8'h0;
219
     else if (ld)
220
       sr <=  din;
221
     else if (shift)
222
       sr <=  {sr[6:0], core_rxd};
223
     else if (slave_adr_received_d & slave_act)
224
       sr <=  {slave_adr[7:1], 1'b0};
225
 
226
 
227
 
228
   // generate counter
229
   always @(posedge clk or negedge nReset)
230
     if (!nReset)
231
       dcnt <=  3'h0;
232
     else if (rst)
233
       dcnt <=  3'h0;
234
     else if (ld)
235
       dcnt <=  3'h7;
236
 
237
     else if (shift)
238
       dcnt <=  dcnt - 3'h1;
239
 
240
   assign cnt_done = ~(|dcnt);
241
 
242
   //
243
   // state machine
244
   //
245
   reg [9:0]     c_state; // synopsys enum_state
246
 
247
 
248
 
249
   always @(posedge clk or negedge nReset)
250
     if (!nReset)
251
       begin
252
          sl_wait <=  1'b0;
253
          core_cmd <=  `I2C_CMD_NOP;
254
          core_txd <=  1'b0;
255
          shift    <=  1'b0;
256
          ld       <=  1'b0;
257
          cmd_ack  <=  1'b0;
258
          c_state  <=  ST_IDLE;
259
          ack_out  <=  1'b0;
260
          master_mode <=  1'b0;
261
          slave_cmd  <=  2'b0;
262
          slave_dat_req <=  1'b0;
263
          slave_dat_avail       <=  1'b0;
264
          slave_act <=  1'b0;
265
          slave_cmd_out <=  2'b0;
266
          slave_cmd_ack <=  1'b0;
267
       end
268
     else if (rst | i2c_al | slave_reset)
269
       begin
270
          core_cmd <=  `I2C_CMD_NOP;
271
          core_txd <=  1'b0;
272
          shift    <=  1'b0;
273
          sl_wait  <=  1'b0;
274
          ld       <=  1'b0;
275
          cmd_ack  <=  1'b0;
276
          c_state  <=  ST_IDLE;
277
          ack_out  <=  1'b0;
278
          master_mode <=  1'b0;
279
          slave_cmd  <=  2'b0;
280
          slave_cmd_out <=  2'b0;
281
          slave_dat_req <=  1'b0;
282
          slave_dat_avail       <=  1'b0;
283
          slave_act <=  1'b0;
284
          slave_cmd_ack <=  1'b0;
285
       end
286
     else
287
       begin
288
          slave_cmd_out <=  slave_cmd;
289
          // initially reset all signals
290
          core_txd <=  sr[7];
291
          shift    <=  1'b0;
292
          ld       <=  1'b0;
293
          cmd_ack  <=  1'b0;
294
          slave_cmd_ack <=  1'b0;
295
 
296
          case (c_state) // synopsys full_case parallel_case
297
            ST_IDLE:
298
              begin
299
                 slave_act <=  1'b0;
300
                 if (slave_en & slave_adr_received &
301
                     (slave_adr[7:1] == my_addr )) begin
302
 
303
                    c_state  <=  ST_SL_ACK;
304
                    master_mode <=  1'b0;
305
                    slave_act <=  1'b1;
306
                    slave_cmd <=  `I2C_SLAVE_CMD_WRITE;
307
                    core_txd <=  1'b0;
308
 
309
                 end
310
                 else if (go && !slave_act )
311
                   begin
312
                      if (start )
313
                        begin
314
                           c_state  <=  ST_START;
315
                           core_cmd <=  `I2C_CMD_START;
316
                           master_mode <=  1'b1;
317
                        end
318
                      else if (read)
319
                        begin
320
                           c_state  <=  ST_READ;
321
                           core_cmd <=  `I2C_CMD_READ;
322
                        end
323
                      else if (write)
324
                        begin
325
                           c_state  <=  ST_WRITE;
326
                           core_cmd <=  `I2C_CMD_WRITE;
327
                        end
328
                      else // stop
329
                        begin
330
                           c_state  <=  ST_STOP;
331
                           core_cmd <=  `I2C_CMD_STOP;
332
 
333
                        end
334
 
335
                      ld <=  1'b1;
336
                   end
337
 
338
              end
339
            ST_SL_RD: //If master read, slave sending data
340
              begin
341
                 slave_cmd <=  `I2C_SLAVE_CMD_NOP;
342
                 if (slave_ack) begin
343
                    if (cnt_done) begin
344
                       c_state   <=  ST_SL_ACK;
345
                       slave_cmd <=  `I2C_SLAVE_CMD_READ;
346
                    end
347
                    else
348
                      begin
349
                         c_state   <=  ST_SL_RD;
350
                         slave_cmd <=  `I2C_SLAVE_CMD_WRITE;
351
                         shift     <=  1'b1;
352
                      end
353
                 end
354
              end
355
            ST_SL_WR: //If master write, slave reading data   
356
              begin
357
                 slave_cmd <=  `I2C_SLAVE_CMD_NOP;
358
                 if (slave_ack)
359
                   begin
360
                      if (cnt_done)
361
                        begin
362
                           c_state  <=  ST_SL_ACK;
363
                           slave_cmd <=  `I2C_SLAVE_CMD_WRITE;
364
                           core_txd <=  1'b0;
365
                        end
366
                      else
367
                        begin
368
                           c_state  <=  ST_SL_WR;
369
                           slave_cmd <=  `I2C_SLAVE_CMD_READ;
370
                        end
371
                      shift    <=  1'b1;
372
                   end
373
              end
374
            ST_SL_WAIT: //Wait for interupt-clear and hold SCL in waitstate
375
              begin
376
                 sl_wait <=  1'b1;
377
                 if (sl_cont) begin
378
                    sl_wait <=  1'b0;
379
                    ld <=  1'b1;
380
                    slave_dat_req       <=  1'b0;
381
                    slave_dat_avail     <=  1'b0;
382
                    c_state   <=  ST_SL_PRELOAD;
383
                 end
384
              end
385
 
386
            ST_SL_PRELOAD:
387
              if (slave_adr[0]) begin
388
                 c_state   <=  ST_SL_RD;
389
                 slave_cmd <=  `I2C_SLAVE_CMD_WRITE;
390
              end
391
              else begin
392
                 c_state  <=  ST_SL_WR;
393
                 slave_cmd <=  `I2C_SLAVE_CMD_READ;
394
              end
395
 
396
            ST_SL_ACK:
397
              begin
398
                 slave_cmd <=  `I2C_SLAVE_CMD_NOP;
399
                 if (slave_ack)  begin
400
                    ack_out <=  core_rxd;
401
                    slave_cmd_ack  <=  1'b1;
402
                    if (!core_rxd) begin // Valid ack recived
403
                       // generate slave command acknowledge signal if 
404
                       // succesful transfer                      
405
                       c_state   <=  ST_SL_WAIT;
406
                       if (slave_adr[0]) begin // I2C read request
407
                          slave_dat_req <=  1'b1;
408
                       end
409
                       else begin              // I2C write request
410
                          slave_dat_avail       <=  1'b1;
411
                       end
412
                    end
413
                    else begin
414
                       c_state   <=  ST_IDLE;
415
                    end
416
                 end
417
                 else begin
418
                    core_txd <=  1'b0;
419
                 end
420
              end
421
 
422
            ST_START:
423
              if (core_ack)
424
                begin
425
                   if (read)
426
                     begin
427
                        c_state  <=  ST_READ;
428
                        core_cmd <=  `I2C_CMD_READ;
429
                     end
430
                   else
431
                     begin
432
                        c_state  <=  ST_WRITE;
433
                        core_cmd <=  `I2C_CMD_WRITE;
434
                     end
435
 
436
                   ld <=  1'b1;
437
                end
438
 
439
            ST_WRITE:
440
              if (core_ack)
441
                if (cnt_done)
442
                  begin
443
                     c_state  <=  ST_ACK;
444
                     core_cmd <=  `I2C_CMD_READ;
445
                  end
446
                else
447
                  begin
448
                     c_state  <=  ST_WRITE;       // stay in same state
449
                     core_cmd <=  `I2C_CMD_WRITE; // write next bit
450
                     shift    <=  1'b1;
451
                  end
452
 
453
            ST_READ:
454
              if (core_ack)
455
                begin
456
                   if (cnt_done)
457
                     begin
458
                        c_state  <=  ST_ACK;
459
                        core_cmd <=  `I2C_CMD_WRITE;
460
                     end
461
                   else
462
                     begin
463
                        c_state  <=  ST_READ;       // stay in same state
464
                        core_cmd <=  `I2C_CMD_READ; // read next bit
465
                     end
466
 
467
                   shift    <=  1'b1;
468
                   core_txd <=  ack_in;
469
                end
470
 
471
            ST_ACK:
472
              if (core_ack)
473
                begin
474
                   if (stop)
475
                     begin
476
                        c_state  <=  ST_STOP;
477
                        core_cmd <=  `I2C_CMD_STOP;
478
                     end
479
                   else
480
                     begin
481
                        c_state  <=  ST_IDLE;
482
                        core_cmd <=  `I2C_CMD_NOP;
483
 
484
                        // generate command acknowledge signal
485
                        cmd_ack  <=  1'b1;
486
                     end
487
 
488
                   // assign ack_out output to bit_controller_rxd (contains 
489
                   // last received bit)
490
                   ack_out <=  core_rxd;
491
 
492
                   core_txd <=  1'b1;
493
                end
494
              else
495
                core_txd <=  ack_in;
496
 
497
            ST_STOP:
498
              if (core_ack)
499
                begin
500
                   c_state  <=  ST_IDLE;
501
                   core_cmd <=  `I2C_CMD_NOP;
502
 
503
                   // generate command acknowledge signal
504
                   cmd_ack  <=  1'b1;
505
                end
506
 
507
          endcase
508
       end
509
endmodule

powered by: WebSVN 2.1.0

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