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

Subversion Repositories i2cslave

[/] [i2cslave/] [trunk/] [model/] [i2c_master_byte_ctrl.v] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 sfielding
/////////////////////////////////////////////////////////////////////
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.1 2008-11-08 13:15:10 sfielding Exp $
41
//
42
//  $Date: 2008-11-08 13:15:10 $
43
//  $Revision: 1.1 $
44
//  $Author: sfielding $
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_defines.v"
74
 
75
module i2c_master_byte_ctrl (
76
        clk, rst, nReset, ena, clk_cnt, start, stop, read, write, ack_in, din,
77
        cmd_ack, ack_out, dout, i2c_busy, i2c_al, scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen );
78
 
79
        //
80
        // inputs & outputs
81
        //
82
        input clk;     // master clock
83
        input rst;     // synchronous active high reset
84
        input nReset;  // asynchronous active low reset
85
        input ena;     // core enable signal
86
 
87
        input [15:0] clk_cnt; // 4x SCL
88
 
89
        // control inputs
90
        input       start;
91
        input       stop;
92
        input       read;
93
        input       write;
94
        input       ack_in;
95
        input [7:0] din;
96
 
97
        // status outputs
98
        output       cmd_ack;
99
        reg cmd_ack;
100
        output       ack_out;
101
        reg ack_out;
102
        output       i2c_busy;
103
        output       i2c_al;
104
        output [7:0] dout;
105
 
106
        // I2C signals
107
        input  scl_i;
108
        output scl_o;
109
        output scl_oen;
110
        input  sda_i;
111
        output sda_o;
112
        output sda_oen;
113
 
114
 
115
        //
116
        // Variable declarations
117
        //
118
 
119
        // statemachine
120
        parameter [4:0] ST_IDLE  = 5'b0_0000;
121
        parameter [4:0] ST_START = 5'b0_0001;
122
        parameter [4:0] ST_READ  = 5'b0_0010;
123
        parameter [4:0] ST_WRITE = 5'b0_0100;
124
        parameter [4:0] ST_ACK   = 5'b0_1000;
125
        parameter [4:0] ST_STOP  = 5'b1_0000;
126
 
127
        // signals for bit_controller
128
        reg  [3:0] core_cmd;
129
        reg        core_txd;
130
        wire       core_ack, core_rxd;
131
 
132
        // signals for shift register
133
        reg [7:0] sr; //8bit shift register
134
        reg       shift, ld;
135
 
136
        // signals for state machine
137
        wire       go;
138
        reg  [2:0] dcnt;
139
        wire       cnt_done;
140
 
141
        //
142
        // Module body
143
        //
144
 
145
        // hookup bit_controller
146
        i2c_master_bit_ctrl bit_controller (
147
                .clk     ( clk      ),
148
                .rst     ( rst      ),
149
                .nReset  ( nReset   ),
150
                .ena     ( ena      ),
151
                .clk_cnt ( clk_cnt  ),
152
                .cmd     ( core_cmd ),
153
                .cmd_ack ( core_ack ),
154
                .busy    ( i2c_busy ),
155
                .al      ( i2c_al   ),
156
                .din     ( core_txd ),
157
                .dout    ( core_rxd ),
158
                .scl_i   ( scl_i    ),
159
                .scl_o   ( scl_o    ),
160
                .scl_oen ( scl_oen  ),
161
                .sda_i   ( sda_i    ),
162
                .sda_o   ( sda_o    ),
163
                .sda_oen ( sda_oen  )
164
        );
165
 
166
        // generate go-signal
167
        assign go = (read | write | stop) & ~cmd_ack;
168
 
169
        // assign dout output to shift-register
170
        assign dout = sr;
171
 
172
        // generate shift register
173
        always @(posedge clk or negedge nReset)
174
          if (!nReset)
175
            sr <= #1 8'h0;
176
          else if (rst)
177
            sr <= #1 8'h0;
178
          else if (ld)
179
            sr <= #1 din;
180
          else if (shift)
181
            sr <= #1 {sr[6:0], core_rxd};
182
 
183
        // generate counter
184
        always @(posedge clk or negedge nReset)
185
          if (!nReset)
186
            dcnt <= #1 3'h0;
187
          else if (rst)
188
            dcnt <= #1 3'h0;
189
          else if (ld)
190
            dcnt <= #1 3'h7;
191
          else if (shift)
192
            dcnt <= #1 dcnt - 3'h1;
193
 
194
        assign cnt_done = ~(|dcnt);
195
 
196
        //
197
        // state machine
198
        //
199
        reg [4:0] c_state; // synopsis enum_state
200
 
201
        always @(posedge clk or negedge nReset)
202
          if (!nReset)
203
            begin
204
                core_cmd <= #1 `I2C_CMD_NOP;
205
                core_txd <= #1 1'b0;
206
                shift    <= #1 1'b0;
207
                ld       <= #1 1'b0;
208
                cmd_ack  <= #1 1'b0;
209
                c_state  <= #1 ST_IDLE;
210
                ack_out  <= #1 1'b0;
211
            end
212
          else if (rst | i2c_al)
213
           begin
214
               core_cmd <= #1 `I2C_CMD_NOP;
215
               core_txd <= #1 1'b0;
216
               shift    <= #1 1'b0;
217
               ld       <= #1 1'b0;
218
               cmd_ack  <= #1 1'b0;
219
               c_state  <= #1 ST_IDLE;
220
               ack_out  <= #1 1'b0;
221
           end
222
        else
223
          begin
224
              // initially reset all signals
225
              core_txd <= #1 sr[7];
226
              shift    <= #1 1'b0;
227
              ld       <= #1 1'b0;
228
              cmd_ack  <= #1 1'b0;
229
 
230
              case (c_state) // synopsys full_case parallel_case
231
                ST_IDLE:
232
                  if (go)
233
                    begin
234
                        if (start)
235
                          begin
236
                              c_state  <= #1 ST_START;
237
                              core_cmd <= #1 `I2C_CMD_START;
238
                          end
239
                        else if (read)
240
                          begin
241
                              c_state  <= #1 ST_READ;
242
                              core_cmd <= #1 `I2C_CMD_READ;
243
                          end
244
                        else if (write)
245
                          begin
246
                              c_state  <= #1 ST_WRITE;
247
                              core_cmd <= #1 `I2C_CMD_WRITE;
248
                          end
249
                        else // stop
250
                          begin
251
                              c_state  <= #1 ST_STOP;
252
                              core_cmd <= #1 `I2C_CMD_STOP;
253
                          end
254
 
255
                        ld <= #1 1'b1;
256
                    end
257
 
258
                ST_START:
259
                  if (core_ack)
260
                    begin
261
                        if (read)
262
                          begin
263
                              c_state  <= #1 ST_READ;
264
                              core_cmd <= #1 `I2C_CMD_READ;
265
                          end
266
                        else
267
                          begin
268
                              c_state  <= #1 ST_WRITE;
269
                              core_cmd <= #1 `I2C_CMD_WRITE;
270
                          end
271
 
272
                        ld <= #1 1'b1;
273
                    end
274
 
275
                ST_WRITE:
276
                  if (core_ack)
277
                    if (cnt_done)
278
                      begin
279
                          c_state  <= #1 ST_ACK;
280
                          core_cmd <= #1 `I2C_CMD_READ;
281
                      end
282
                    else
283
                      begin
284
                          c_state  <= #1 ST_WRITE;       // stay in same state
285
                          core_cmd <= #1 `I2C_CMD_WRITE; // write next bit
286
                          shift    <= #1 1'b1;
287
                      end
288
 
289
                ST_READ:
290
                  if (core_ack)
291
                    begin
292
                        if (cnt_done)
293
                          begin
294
                              c_state  <= #1 ST_ACK;
295
                              core_cmd <= #1 `I2C_CMD_WRITE;
296
                          end
297
                        else
298
                          begin
299
                              c_state  <= #1 ST_READ;       // stay in same state
300
                              core_cmd <= #1 `I2C_CMD_READ; // read next bit
301
                          end
302
 
303
                        shift    <= #1 1'b1;
304
                        core_txd <= #1 ack_in;
305
                    end
306
 
307
                ST_ACK:
308
                  if (core_ack)
309
                    begin
310
                       if (stop)
311
                         begin
312
                             c_state  <= #1 ST_STOP;
313
                             core_cmd <= #1 `I2C_CMD_STOP;
314
                         end
315
                       else
316
                         begin
317
                             c_state  <= #1 ST_IDLE;
318
                             core_cmd <= #1 `I2C_CMD_NOP;
319
 
320
                             // generate command acknowledge signal
321
                             cmd_ack  <= #1 1'b1;
322
                         end
323
 
324
                         // assign ack_out output to bit_controller_rxd (contains last received bit)
325
                         ack_out <= #1 core_rxd;
326
 
327
                         core_txd <= #1 1'b1;
328
                     end
329
                   else
330
                     core_txd <= #1 ack_in;
331
 
332
                ST_STOP:
333
                  if (core_ack)
334
                    begin
335
                        c_state  <= #1 ST_IDLE;
336
                        core_cmd <= #1 `I2C_CMD_NOP;
337
 
338
                        // generate command acknowledge signal
339
                        cmd_ack  <= #1 1'b1;
340
                    end
341
 
342
              endcase
343
          end
344
endmodule

powered by: WebSVN 2.1.0

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