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

Subversion Repositories oms8051mini

[/] [oms8051mini/] [trunk/] [rtl/] [i2cm/] [i2cm_byte_ctrl.v] - Blame information for rev 36

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 28 dinesha
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  OMS8051 I2C Master byte-controller Module                  ////
4
////  WISHBONE rev.B2 compliant I2C Master byte-controller       ////
5
////                                                              ////
6
////  This file is part of the OMS 8051 cores project             ////
7
////  http://www.opencores.org/cores/oms8051mini/                 ////
8
////                                                              ////
9
////  Description                                                 ////
10
////  OMS 8051 definitions.                                       ////
11
////                                                              ////
12
////  To Do:                                                      ////
13
////    nothing                                                   ////
14
////                                                              ////
15
////  Author(s):                                                  ////
16
////      -Richard Herveille ,  richard@asics.ws, www.asics.ws    ////
17
////      -Dinesh Annayya, dinesha@opencores.org                  ////
18
////                                                              ////
19
////  Revision : Jan 6, 2017                                      //// 
20
////                                                              ////
21
//////////////////////////////////////////////////////////////////////
22 36 dinesha
////   v0.0 - Dinesh A, 6th Jan 2017
23
////        1. Initail version picked from
24
////            http://www.opencores.org/projects/i2c/
25
////        2. renaming of reset signal to aresetn and sresetn
26
////   v0.1 - Dinesh.A, 19th Jan 2017
27
////        1. Lint Error fixes
28 28 dinesha
//////////////////////////////////////////////////////////////////////
29
////                                                              ////
30
//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
31
////                                                              ////
32
//// This source file may be used and distributed without         ////
33
//// restriction provided that this copyright statement is not    ////
34
//// removed from the file and that any derivative work contains  ////
35
//// the original copyright notice and the associated disclaimer. ////
36
////                                                              ////
37
//// This source file is free software; you can redistribute it   ////
38
//// and/or modify it under the terms of the GNU Lesser General   ////
39
//// Public License as published by the Free Software Foundation; ////
40
//// either version 2.1 of the License, or (at your option) any   ////
41
//// later version.                                               ////
42
////                                                              ////
43
//// This source is distributed in the hope that it will be       ////
44
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
45
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
46
//// PURPOSE.  See the GNU Lesser General Public License for more ////
47
//// details.                                                     ////
48
////                                                              ////
49
//// You should have received a copy of the GNU Lesser General    ////
50
//// Public License along with this source; if not, download it   ////
51
//// from http://www.opencores.org/lgpl.shtml                     ////
52
////                                                              ////
53
//////////////////////////////////////////////////////////////////////
54
 
55
`include "i2cm_defines.v"
56
 
57
module i2cm_byte_ctrl (
58
        //
59
        // inputs & outputs
60
        //
61
        input        clk,     // master clock
62
        input        sresetn, // synchronous active high reset
63
        input        aresetn, // 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 reg   cmd_ack,
78
        output reg   ack_out,
79
        output       i2c_busy,
80
        output       i2c_al,
81
        output [7:0] dout,
82
 
83
        // I2C signals
84
        input        scl_i,
85
        output       scl_o,
86
        output       scl_oen,
87
        input        sda_i,
88
        output       sda_o,
89
        output       sda_oen
90
 
91
       );
92
 
93
 
94
 
95
        //
96
        // Variable declarations
97
        //
98
 
99
        // statemachine
100
        parameter [4:0] ST_IDLE  = 5'b0_0000;
101
        parameter [4:0] ST_START = 5'b0_0001;
102
        parameter [4:0] ST_READ  = 5'b0_0010;
103
        parameter [4:0] ST_WRITE = 5'b0_0100;
104
        parameter [4:0] ST_ACK   = 5'b0_1000;
105
        parameter [4:0] ST_STOP  = 5'b1_0000;
106
 
107
        // signals for bit_controller
108
        reg  [3:0] core_cmd;
109
        reg        core_txd;
110
        wire       core_ack, core_rxd;
111
 
112
        // signals for shift register
113
        reg [7:0] sr; //8bit shift register
114
        reg       shift, ld;
115
 
116
        // signals for state machine
117
        wire       go;
118
        reg  [2:0] dcnt;
119
        wire       cnt_done;
120
 
121
        //
122
        // Module body
123
        //
124
 
125
        // hookup bit_controller
126
        i2cm_bit_ctrl u_bit_ctrl (
127
                .clk     ( clk      ),
128
                .sresetn ( sresetn  ),
129
                .aresetn ( aresetn ),
130
                .ena     ( ena      ),
131
                .clk_cnt ( clk_cnt  ),
132
                .cmd     ( core_cmd ),
133
                .cmd_ack ( core_ack ),
134
                .busy    ( i2c_busy ),
135
                .al      ( i2c_al   ),
136
                .din     ( core_txd ),
137
                .dout    ( core_rxd ),
138
                .scl_i   ( scl_i    ),
139
                .scl_o   ( scl_o    ),
140
                .scl_oen ( scl_oen  ),
141
                .sda_i   ( sda_i    ),
142
                .sda_o   ( sda_o    ),
143
                .sda_oen ( sda_oen  )
144
        );
145
 
146
        // generate go-signal
147
        assign go = (read | write | stop) & ~cmd_ack;
148
 
149
        // assign dout output to shift-register
150
        assign dout = sr;
151
 
152
        // generate shift register
153
        always @(posedge clk or negedge aresetn)
154
          if (!aresetn)
155 36 dinesha
            sr <= 8'h0;
156 28 dinesha
          else if (!sresetn)
157 36 dinesha
            sr <= 8'h0;
158 28 dinesha
          else if (ld)
159 36 dinesha
            sr <= din;
160 28 dinesha
          else if (shift)
161 36 dinesha
            sr <= {sr[6:0], core_rxd};
162 28 dinesha
 
163
        // generate counter
164
        always @(posedge clk or negedge aresetn)
165
          if (!aresetn)
166 36 dinesha
            dcnt <= 3'h0;
167 28 dinesha
          else if (!sresetn)
168 36 dinesha
            dcnt <= 3'h0;
169 28 dinesha
          else if (ld)
170 36 dinesha
            dcnt <= 3'h7;
171 28 dinesha
          else if (shift)
172 36 dinesha
            dcnt <= dcnt - 3'h1;
173 28 dinesha
 
174
        assign cnt_done = ~(|dcnt);
175
 
176
        //
177
        // state machine
178
        //
179
        reg [4:0] c_state; // synopsys enum_state
180
 
181
        always @(posedge clk or negedge aresetn)
182
          if (!aresetn)
183
            begin
184 36 dinesha
                core_cmd <= `I2C_CMD_NOP;
185
                core_txd <= 1'b0;
186
                shift    <= 1'b0;
187
                ld       <= 1'b0;
188
                cmd_ack  <= 1'b0;
189
                c_state  <= ST_IDLE;
190
                ack_out  <= 1'b0;
191 28 dinesha
            end
192
          else if (!sresetn | i2c_al)
193
           begin
194 36 dinesha
               core_cmd <= `I2C_CMD_NOP;
195
               core_txd <= 1'b0;
196
               shift    <= 1'b0;
197
               ld       <= 1'b0;
198
               cmd_ack  <= 1'b0;
199
               c_state  <= ST_IDLE;
200
               ack_out  <= 1'b0;
201 28 dinesha
           end
202
        else
203
          begin
204
              // initially reset all signals
205 36 dinesha
              core_txd <= sr[7];
206
              shift    <= 1'b0;
207
              ld       <= 1'b0;
208
              cmd_ack  <= 1'b0;
209 28 dinesha
 
210
              case (c_state) // synopsys full_case parallel_case
211
                ST_IDLE:
212
                  if (go)
213
                    begin
214
                        if (start)
215
                          begin
216 36 dinesha
                              c_state  <= ST_START;
217
                              core_cmd <= `I2C_CMD_START;
218 28 dinesha
                          end
219
                        else if (read)
220
                          begin
221 36 dinesha
                              c_state  <= ST_READ;
222
                              core_cmd <= `I2C_CMD_READ;
223 28 dinesha
                          end
224
                        else if (write)
225
                          begin
226 36 dinesha
                              c_state  <= ST_WRITE;
227
                              core_cmd <= `I2C_CMD_WRITE;
228 28 dinesha
                          end
229
                        else // stop
230
                          begin
231 36 dinesha
                              c_state  <= ST_STOP;
232
                              core_cmd <= `I2C_CMD_STOP;
233 28 dinesha
                          end
234
 
235 36 dinesha
                        ld <= 1'b1;
236 28 dinesha
                    end
237
 
238
                ST_START:
239
                  if (core_ack)
240
                    begin
241
                        if (read)
242
                          begin
243 36 dinesha
                              c_state  <= ST_READ;
244
                              core_cmd <= `I2C_CMD_READ;
245 28 dinesha
                          end
246
                        else
247
                          begin
248 36 dinesha
                              c_state  <= ST_WRITE;
249
                              core_cmd <= `I2C_CMD_WRITE;
250 28 dinesha
                          end
251
 
252 36 dinesha
                        ld <= 1'b1;
253 28 dinesha
                    end
254
 
255
                ST_WRITE:
256
                  if (core_ack)
257
                    if (cnt_done)
258
                      begin
259 36 dinesha
                          c_state  <= ST_ACK;
260
                          core_cmd <= `I2C_CMD_READ;
261 28 dinesha
                      end
262
                    else
263
                      begin
264 36 dinesha
                          c_state  <= ST_WRITE;       // stay in same state
265
                          core_cmd <= `I2C_CMD_WRITE; // write next bit
266
                          shift    <= 1'b1;
267 28 dinesha
                      end
268
 
269
                ST_READ:
270
                  if (core_ack)
271
                    begin
272
                        if (cnt_done)
273
                          begin
274 36 dinesha
                              c_state  <= ST_ACK;
275
                              core_cmd <= `I2C_CMD_WRITE;
276 28 dinesha
                          end
277
                        else
278
                          begin
279 36 dinesha
                              c_state  <= ST_READ;       // stay in same state
280
                              core_cmd <= `I2C_CMD_READ; // read next bit
281 28 dinesha
                          end
282
 
283 36 dinesha
                        shift    <= 1'b1;
284
                        core_txd <= ack_in;
285 28 dinesha
                    end
286
 
287
                ST_ACK:
288
                  if (core_ack)
289
                    begin
290
                       if (stop)
291
                         begin
292 36 dinesha
                             c_state  <= ST_STOP;
293
                             core_cmd <= `I2C_CMD_STOP;
294 28 dinesha
                         end
295
                       else
296
                         begin
297 36 dinesha
                             c_state  <= ST_IDLE;
298
                             core_cmd <= `I2C_CMD_NOP;
299 28 dinesha
 
300
                             // generate command acknowledge signal
301 36 dinesha
                             cmd_ack  <= 1'b1;
302 28 dinesha
                         end
303
 
304
                         // assign ack_out output to bit_controller_rxd (contains last received bit)
305 36 dinesha
                         ack_out <=  core_rxd;
306 28 dinesha
 
307 36 dinesha
                         core_txd <=  1'b1;
308 28 dinesha
                     end
309
                   else
310 36 dinesha
                     core_txd <= ack_in;
311 28 dinesha
 
312
                ST_STOP:
313
                  if (core_ack)
314
                    begin
315 36 dinesha
                        c_state  <= ST_IDLE;
316
                        core_cmd <= `I2C_CMD_NOP;
317 28 dinesha
 
318
                        // generate command acknowledge signal
319 36 dinesha
                        cmd_ack  <= 1'b1;
320 28 dinesha
                    end
321 36 dinesha
               default: c_state  <= ST_IDLE;
322 28 dinesha
 
323
              endcase
324
          end
325
endmodule

powered by: WebSVN 2.1.0

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