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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 408 julius
/////////////////////////////////////////////////////////////////////
2
////                                                             ////
3
////  WISHBONE revB.2 compliant I2C Master controller Top-level  ////
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_top.v,v 1.12 2009-01-19 20:29:26 rherveille Exp $
41
//
42
//  $Date: 2009-01-19 20:29:26 $
43
//  $Revision: 1.12 $
44
//  $Author: rherveille $
45
//  $Locker:  $
46
//  $State: Exp $
47
//
48
// Change History:
49
//               Revision 1.11  2005/02/27 09:26:24  rherveille
50
//               Fixed register overwrite issue.
51
//               Removed full_case pragma, replaced it by a default statement.
52
//
53
//               Revision 1.10  2003/09/01 10:34:38  rherveille
54
//               Fix a blocking vs. non-blocking error in the wb_dat output mux.
55
//
56
//               Revision 1.9  2003/01/09 16:44:45  rherveille
57
//               Fixed a bug in the Command Register declaration.
58
//
59
//               Revision 1.8  2002/12/26 16:05:12  rherveille
60
//               Small code simplifications
61
//
62
//               Revision 1.7  2002/12/26 15:02:32  rherveille
63
//               Core is now a Multimaster I2C controller
64
//
65
//               Revision 1.6  2002/11/30 22:24:40  rherveille
66
//               Cleaned up code
67
//
68
//               Revision 1.5  2001/11/10 10:52:55  rherveille
69
//               Changed PRER reset value from 0x0000 to 0xffff, conform specs.
70
//
71
 
72
// synopsys translate_off
73
`include "timescale.v"
74
// synopsys translate_on
75
 
76
`include "i2c_master_slave_defines.v"
77
 
78
//module i2c_master_top(
79
module i2c_master_slave
80
  (
81
   wb_clk_i, wb_rst_i, arst_i, wb_adr_i, wb_dat_i, wb_dat_o,
82
   wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_inta_o,
83
   scl_pad_i, scl_pad_o, scl_padoen_o, sda_pad_i, sda_pad_o, sda_padoen_o );
84
 
85
   // parameters
86
   parameter ARST_LVL = 1'b1; // asynchronous reset level
87
   parameter [6:0] DEFAULT_SLAVE_ADDR  = 7'b111_1110;
88
   //
89
   // inputs & outputs
90
   //
91
 
92
   // wishbone signals
93
   input        wb_clk_i;     // master clock input
94
   input        wb_rst_i;     // synchronous active high reset
95
   input        arst_i;       // asynchronous reset
96
   input [2:0]   wb_adr_i;     // lower address bits
97
   input [7:0]   wb_dat_i;     // databus input
98
   output [7:0] wb_dat_o;     // databus output
99
   input        wb_we_i;      // write enable input
100
   input        wb_stb_i;     // stobe/core select signal
101
   input        wb_cyc_i;     // valid bus cycle input
102
   output       wb_ack_o;     // bus cycle acknowledge output
103
   output       wb_inta_o;    // interrupt request signal output
104
 
105
   reg [7:0]     wb_dat_o;
106
   reg          wb_ack_o;
107
   reg          wb_inta_o;
108
 
109
   // I2C signals
110
   // i2c clock line
111
   input        scl_pad_i;       // SCL-line input
112
   output       scl_pad_o;       // SCL-line output (always 1'b0)
113
   output       scl_padoen_o;    // SCL-line output enable (active low)
114
 
115
   // i2c data line
116
   input        sda_pad_i;       // SDA-line input
117
   output       sda_pad_o;       // SDA-line output (always 1'b0)
118
   output       sda_padoen_o;    // SDA-line output enable (active low)
119
 
120
 
121
   //
122
   // variable declarations
123
   //
124
 
125
   // registers
126
   reg [15:0]    prer; // clock prescale register
127
   reg [ 7:0]    ctr;  // control register
128
   reg [ 7:0]    txr;  // transmit register
129
   wire [ 7:0]   rxr;  // receive register
130
   reg [ 7:0]    cr;   // command register
131
   wire [ 7:0]   sr;   // status register
132
   reg [ 6:0]    sladr;  // slave address register   
133
 
134
   // done signal: command completed, clear command register
135
   wire         done;
136
   wire         slave_done;
137
   // core enable signal
138
   wire         core_en;
139
   wire         ien;
140
   wire         slave_en;
141
 
142
   // status register signals
143
   wire         irxack;
144
   reg          rxack;       // received aknowledge from slave
145
   reg          tip;         // transfer in progress
146
   reg          irq_flag;    // interrupt pending flag
147
   wire         i2c_busy;    // bus busy (start signal detected)
148
   wire         i2c_al;      // i2c bus arbitration lost
149
   reg          al;          // status register arbitration lost bit
150
   reg          slave_mode;
151
   //
152
   // module body
153
   //
154
   wire         slave_act;
155
   // generate internal reset
156
   wire         rst_i = arst_i ^ ARST_LVL;
157
 
158
   // generate wishbone signals
159
   wire         wb_wacc = wb_we_i & wb_ack_o;
160
 
161
   // generate acknowledge output signal ...
162
   always @(posedge wb_clk_i)
163
     // ... because timing is always honored.    
164
     wb_ack_o <=  wb_cyc_i & wb_stb_i & ~wb_ack_o;
165
 
166
   // assign DAT_O
167
   always @(posedge wb_clk_i)
168
     begin
169
        case (wb_adr_i) // synopsys parallel_case
170
          3'b000: wb_dat_o <= prer[ 7:0];
171
          3'b001: wb_dat_o <=  prer[15:8];
172
          3'b010: wb_dat_o <=  ctr;
173
          3'b011: wb_dat_o <=  rxr; // write is transmit register (txr)
174
          3'b100: wb_dat_o <=  sr;  // write is command register (cr)
175
          3'b101: wb_dat_o <=  txr; // Debug out of TXR
176
          3'b110: wb_dat_o <=  cr;  // Debug out control reg
177
          3'b111: wb_dat_o <=  {1'b0,sladr};   // slave address register
178
        endcase
179
     end
180
 
181
   // generate registers
182
   always @(posedge wb_clk_i or negedge rst_i)
183
     if (!rst_i)
184
       begin
185
          prer  <=  16'hffff;
186
          ctr   <=   8'h0;
187
          txr   <=   8'h0;
188
          sladr <=  DEFAULT_SLAVE_ADDR;
189
       end
190
     else if (wb_rst_i)
191
       begin
192
          prer  <=  16'hffff;
193
          ctr   <=   8'h0;
194
          txr   <=   8'h0;
195
          sladr <=  DEFAULT_SLAVE_ADDR;
196
       end
197
     else
198
       if (wb_wacc)
199
         case (wb_adr_i) // synopsys parallel_case
200
           3'b000 : prer [ 7:0] <=  wb_dat_i;
201
           3'b001 : prer [15:8] <=  wb_dat_i;
202
           3'b010 : ctr         <=  wb_dat_i;
203
           3'b011 : txr         <=  wb_dat_i;
204
           3'b111 : sladr       <=  wb_dat_i[6:0];
205
           default: ;
206
         endcase
207
 
208
   // generate command register (special case)
209
   always @(posedge wb_clk_i or negedge rst_i)
210
     if (!rst_i)
211
       cr <=  8'h0;
212
     else if (wb_rst_i)
213
       cr <=  8'h0;
214
     else if (wb_wacc)
215
       begin
216
          if (core_en & (wb_adr_i == 3'b100) )
217
            cr <=  wb_dat_i;
218
       end
219
     else
220
       begin
221
          cr[1] <=  1'b0;
222
          if (done | i2c_al)
223
            cr[7:4] <=  4'h0;           // clear command bits when done
224
          // or when aribitration lost
225
          cr[2] <=  1'b0;             // reserved bits
226
          cr[0]   <=  1'b0;             // clear IRQ_ACK bit
227
 
228
 
229
 
230
       end
231
 
232
 
233
   // decode command register
234
   wire sta  = cr[7];
235
   wire sto  = cr[6];
236
   wire rd   = cr[5];
237
   wire wr   = cr[4];
238
   wire ack  = cr[3];
239
   wire sl_cont = cr[1];
240
   wire iack    = cr[0];
241
 
242
   // decode control register
243
   assign core_en = ctr[7];
244
   assign ien = ctr[6];
245
   assign slave_en = ctr[5];
246
 
247
 
248
   // hookup byte controller block
249
   i2c_master_byte_ctrl byte_controller
250
     (
251
      .clk      ( wb_clk_i     ),
252
      .my_addr  ( sladr        ),
253
      .rst      ( wb_rst_i     ),
254
      .nReset   ( rst_i        ),
255
      .ena      ( core_en      ),
256
      .clk_cnt  ( prer         ),
257
      .start    ( sta          ),
258
      .stop     ( sto          ),
259
      .read     ( rd           ),
260
      .write    ( wr           ),
261
      .ack_in   ( ack          ),
262
      .din      ( txr          ),
263
      .cmd_ack  ( done         ),
264
      .ack_out  ( irxack       ),
265
      .dout     ( rxr          ),
266
      .i2c_busy ( i2c_busy     ),
267
      .i2c_al   ( i2c_al       ),
268
      .scl_i    ( scl_pad_i    ),
269
      .scl_o    ( scl_pad_o    ),
270
      .scl_oen  ( scl_padoen_o ),
271
      .sda_i    ( sda_pad_i    ),
272
      .sda_o    ( sda_pad_o    ),
273
      .sda_oen  ( sda_padoen_o ),
274
      .sl_cont  ( sl_cont       ),
275
      .slave_en ( slave_en      ),
276
      .slave_dat_req (slave_dat_req),
277
      .slave_dat_avail (slave_dat_avail),
278
      .slave_act (slave_act),
279
      .slave_cmd_ack (slave_done)
280
      );
281
 
282
   // status register block + interrupt request signal
283
   always @(posedge wb_clk_i or negedge rst_i)
284
     if (!rst_i)
285
       begin
286
          al       <=  1'b0;
287
          rxack    <=  1'b0;
288
          tip      <=  1'b0;
289
          irq_flag <=  1'b0;
290
          slave_mode <=  1'b0;
291
       end
292
     else if (wb_rst_i)
293
       begin
294
          al       <=  1'b0;
295
          rxack    <=  1'b0;
296
          tip      <=  1'b0;
297
          irq_flag <=  1'b0;
298
          slave_mode <=  1'b0;
299
       end
300
     else
301
       begin
302
          al       <=  i2c_al | (al & ~sta);
303
          rxack    <=  irxack;
304
          tip      <=  (rd | wr);
305
          // interrupt request flag is always generated   
306
          irq_flag <=  (done | slave_done| i2c_al | slave_dat_req |
307
                          slave_dat_avail | irq_flag) & ~iack;
308
          if (done)
309
            slave_mode <=  slave_act;
310
 
311
       end
312
 
313
   // generate interrupt request signals
314
   always @(posedge wb_clk_i or negedge rst_i)
315
     if (!rst_i)
316
       wb_inta_o <=  1'b0;
317
     else if (wb_rst_i)
318
       wb_inta_o <=  1'b0;
319
     else
320
       // interrupt signal is only generated when IEN (interrupt enable bit 
321
       // is set)       
322
       wb_inta_o <=  irq_flag && ien;
323
 
324
   // assign status register bits
325
   assign sr[7]   = rxack;
326
   assign sr[6]   = i2c_busy;
327
   assign sr[5]   = al;
328
   assign sr[4]   = slave_mode; // reserved
329
   assign sr[3]   = slave_dat_avail;
330
   assign sr[2]   = slave_dat_req;
331
   assign sr[1]   = tip;
332
   assign sr[0]   = irq_flag;
333
 
334
endmodule

powered by: WebSVN 2.1.0

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