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

Subversion Repositories i2c

[/] [i2c/] [trunk/] [rtl/] [verilog/] [i2c_master_top.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 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 10 rherveille
//
40 14 rherveille
//  $Id: i2c_master_top.v,v 1.4 2001-11-05 11:59:25 rherveille Exp $
41 10 rherveille
//
42 14 rherveille
//  $Date: 2001-11-05 11:59:25 $
43
//  $Revision: 1.4 $
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_top(
55
        wb_clk_i, wb_rst_i, arst_i, wb_adr_i, wb_dat_i, wb_dat_o,
56
        wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_inta_o,
57
        scl_pad_i, scl_pad_o, scl_padoen_o, sda_pad_i, sda_pad_o, sda_padoen_o );
58
 
59 11 rherveille
        // parameters
60
        parameter ARST_LVL = 1'b0; // asynchronous reset level
61
 
62 10 rherveille
        //
63
        // inputs & outputs
64
        //
65
 
66
        // wishbone signals
67
        input        wb_clk_i;     // master clock input
68
        input        wb_rst_i;     // synchronous active high reset
69
        input        arst_i;       // asynchronous reset
70
        input  [2:0] wb_adr_i;     // lower address bits
71
        input  [7:0] wb_dat_i;     // databus input
72
        output [7:0] wb_dat_o;     // databus output
73
        reg [7:0] wb_dat_o;
74
        input        wb_we_i;      // write enable input
75
        input        wb_stb_i;     // stobe/core select signal
76
        input        wb_cyc_i;     // valid bus cycle input
77
        output       wb_ack_o;     // bus cycle acknowledge output
78
        output       wb_inta_o;    // interrupt request signal output
79
        reg wb_inta_o;
80
 
81
        // I2C signals
82
        // i2c clock line
83
        input  scl_pad_i;       // SCL-line input
84
        output scl_pad_o;       // SCL-line output (always 1'b0)
85
        output scl_padoen_o;    // SCL-line output enable (active low)
86
        // i2c data line
87
        input  sda_pad_i;       // SDA-line input
88
        output sda_pad_o;       // SDA-line output (always 1'b0)
89
        output sda_padoen_o;    // SDA-line output enable (active low)
90
 
91
 
92
        //
93
        // variable declarations
94
        //
95
 
96
        // registers
97
        reg  [15:0] prer; // clock prescale register
98
        reg  [ 7:0] ctr;  // control register
99
        reg  [ 7:0] txr;  // transmit register
100
        wire [ 7:0] rxr;  // receive register
101
        reg  [ 7:0] cr;   // command register
102
        wire [ 7:0] sr;   // status register
103
 
104
        // done signal: command completed, clear command register
105
        wire done;
106
 
107
        // core enable signal
108
        wire core_en;
109 13 rherveille
        wire ien;
110 10 rherveille
 
111
        // status register signals
112
        wire irxack;
113
        reg  rxack;       // received aknowledge from slave
114
        reg  tip;         // transfer in progress
115
        reg  irq_flag;    // interrupt pending flag
116
        wire i2c_busy;    // bus busy (start signal detected)
117
 
118
        //
119
        // module body
120
        //
121
 
122
        // generate internal reset
123 11 rherveille
        wire rst_i = arst_i ^ ARST_LVL;
124 10 rherveille
 
125
        // generate acknowledge output signal
126
        assign wb_ack_o = wb_cyc_i && wb_stb_i; // because timing is always honored
127
 
128
        // assign DAT_O
129
        always@(wb_adr_i or prer or ctr or txr or cr or rxr or sr)
130
        begin
131
                case (wb_adr_i) // synopsis full_case parallel_case
132
                        3'b000: wb_dat_o = prer[ 7:0];
133
                        3'b001: wb_dat_o = prer[15:8];
134
                        3'b010: wb_dat_o = ctr;
135
                        3'b011: wb_dat_o = rxr; // write is transmit register (txr)
136
                        3'b100: wb_dat_o = sr;  // write is command register (cr)
137
                        3'b101: wb_dat_o = txr;
138
                        3'b110: wb_dat_o = cr;
139 14 rherveille
                        3'b111: wb_dat_o = 0;   // reserved
140 10 rherveille
                endcase
141
        end
142
 
143
 
144
        // generate registers
145
        always@(posedge wb_clk_i or negedge rst_i)
146
                if (!rst_i)
147
                        begin
148
                                prer <= #1 16'h0;
149
                                ctr  <= #1  8'h0;
150
                                txr  <= #1  8'h0;
151
                                cr   <= #1  8'h0;
152
                        end
153
                else if (wb_rst_i)
154
                        begin
155
                                prer <= #1 16'h0;
156
                                ctr  <= #1  8'h0;
157
                                txr  <= #1  8'h0;
158
                                cr   <= #1  8'h0;
159
                        end
160
                else
161
                        if (wb_cyc_i && wb_stb_i && wb_we_i)
162
                                begin
163
                                        if (!wb_adr_i[2])
164
                                                case (wb_adr_i[1:0]) // synopsis full_case parallel_case
165
                                                        2'b00 : prer [ 7:0] <= #1 wb_dat_i;
166
                                                        2'b01 : prer [15:8] <= #1 wb_dat_i;
167
                                                        2'b10 : ctr         <= #1 wb_dat_i;
168
                                                        2'b11 : txr         <= #1 wb_dat_i;
169
                                                endcase
170
                                        else
171
                                                if (core_en && (wb_adr_i[1:0] == 2'b00) ) // only take new commands when i2c core enabled, pending commands are finished
172
                                                        cr <= #1 wb_dat_i;
173
                                end
174
                        else
175
                                begin
176
                                        if (done)
177
                                                cr[7:4] <= #1 4'h0; // clear command bits when done
178
 
179
                                        cr[2:1] <= #1 2'b00;  // reserved bits
180
                                        cr[0]   <= #1 cr[0] && irq_flag; // clear when irq_flag cleared
181
                                end
182
 
183
 
184
        // decode command register
185
        wire sta  = cr[7];
186
        wire sto  = cr[6];
187
        wire rd   = cr[5];
188
        wire wr   = cr[4];
189
        wire ack  = cr[3];
190
        wire iack = cr[0];
191
 
192
        // decode control register
193
        assign core_en = ctr[7];
194 13 rherveille
        assign ien = ctr[6];
195 10 rherveille
 
196
        // hookup byte controller block
197
        i2c_master_byte_ctrl byte_controller (
198
                .clk(wb_clk_i),
199
                .rst(wb_rst_i),
200
                .nReset(rst_i),
201
                .ena(core_en),
202
                .clk_cnt(prer),
203
                .start(sta),
204
                .stop(sto),
205
                .read(rd),
206
                .write(wr),
207
                .ack_in(ack),
208
                .din(txr),
209
                .cmd_ack(done),
210
                .ack_out(irxack),
211
                .dout(rxr),
212
                .i2c_busy(i2c_busy),
213
                .scl_i(scl_pad_i),
214
                .scl_o(scl_pad_o),
215
                .scl_oen(scl_padoen_o),
216
                .sda_i(sda_pad_i),
217
                .sda_o(sda_pad_o),
218
                .sda_oen(sda_padoen_o)
219
        );
220
 
221
 
222
        // status register block + interrupt request signal
223
        always@(posedge wb_clk_i or negedge rst_i)
224
                if (!rst_i)
225
                        begin
226
                                rxack    <= #1 1'b0;
227
                                tip      <= #1 1'b0;
228
                                irq_flag <= #1 1'b0;
229
                        end
230
                else if (wb_rst_i)
231
                        begin
232
                                rxack    <= #1 1'b0;
233
                                tip      <= #1 1'b0;
234
                                irq_flag <= #1 1'b0;
235
                        end
236
                else
237
                        begin
238
                                rxack    <= #1 irxack;
239
                                tip      <= #1 (rd || wr);
240
                                irq_flag <= #1 (done || irq_flag) && !iack; // interrupt request flag is always generated
241
                        end
242
 
243
                // generate interrupt request signals
244
                always@(posedge wb_clk_i or negedge rst_i)
245
                        if (!rst_i)
246
                                wb_inta_o <= #1 1'b0;
247
                        else if (wb_rst_i)
248
                                wb_inta_o <= #1 1'b0;
249
                        else
250 13 rherveille
                                wb_inta_o <= #1 irq_flag && ien; // interrupt signal is only generated when IEN (interrupt enable bit is set)
251 10 rherveille
 
252
                // assign status register bits
253
                assign sr[7]   = rxack;
254
                assign sr[6]   = i2c_busy;
255
                assign sr[5:2] = 4'h0; // reserved
256
                assign sr[1]   = tip;
257
                assign sr[0]   = irq_flag;
258
 
259
endmodule
260
 
261
 
262
 
263
 
264
 
265
 
266
 
267
 
268 11 rherveille
 

powered by: WebSVN 2.1.0

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