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