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

Subversion Repositories i2c

[/] [i2c/] [trunk/] [rtl/] [verilog/] [i2c_master_byte_ctrl.v] - Blame information for rev 27

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

powered by: WebSVN 2.1.0

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