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

Subversion Repositories i2c

[/] [i2c/] [tags/] [asyst_3/] [rtl/] [verilog/] [i2c_master_byte_ctrl.v] - Blame information for rev 14

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

powered by: WebSVN 2.1.0

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