1 /////////////////////////////////////////////////////////////////////
3 //// WISHBONE revB.2 compliant I2C Master controller Top-level ////
6 //// Author: Richard Herveille ////
7 //// richard@asics.ws ////
10 //// Downloaded from: http://www.opencores.org/projects/i2c/ ////
12 /////////////////////////////////////////////////////////////////////
14 //// Copyright (C) 2001 Richard Herveille ////
15 //// richard@asics.ws ////
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.////
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. ////
36 /////////////////////////////////////////////////////////////////////
40 // $Id: i2c_master_top.v,v 1.11 2005/02/27 09:26:24 rherveille Exp $
42 // $Date: 2005/02/27 09:26:24 $
44 // $Author: rherveille $
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.
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.
57 // Revision 1.9 2003/01/09 16:44:45 rherveille
58 // Fixed a bug in the Command Register declaration.
60 // Revision 1.8 2002/12/26 16:05:12 rherveille
61 // Small code simplifications
63 // Revision 1.7 2002/12/26 15:02:32 rherveille
64 // Core is now a Multimaster I2C controller
66 // Revision 1.6 2002/11/30 22:24:40 rherveille
69 // Revision 1.5 2001/11/10 10:52:55 rherveille
70 // Changed PRER reset value from 0x0000 to 0xffff, conform specs.
73 // synopsys translate_off
74 `include "timescale.v"
75 // synopsys translate_on
77 `include "i2c_master_defines.v"
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 );
85 parameter ARST_LVL = 1'b0; // asynchronous reset level
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
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)
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)
121 // variable declarations
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
132 // done signal: command completed, clear command register
135 // core enable signal
139 // status register signals
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
152 // generate internal reset
153 wire rst_i = arst_i ^ ARST_LVL;
155 // generate wishbone signals
156 wire wb_wacc = wb_cyc_i & wb_stb_i & wb_we_i;
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
163 always @(posedge wb_clk_i)
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
177 // generate registers
178 always @(posedge wb_clk_i or negedge rst_i)
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;
201 // generate command register (special case)
202 always @(posedge wb_clk_i or negedge rst_i)
209 if (core_en & (wb_adr_i == 3'b100) )
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
222 // decode command register
230 // decode control register
231 assign core_en = ctr[7];
234 // hookup byte controller block
235 i2c_master_byte_ctrl byte_controller (
250 .i2c_busy ( i2c_busy ),
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 )
260 // status register block + interrupt request signal
261 always @(posedge wb_clk_i or negedge rst_i)
278 al <= #1 i2c_al | (al & ~sta);
281 irq_flag <= #1 (done | i2c_al | irq_flag) & ~iack; // interrupt request flag is always generated
284 // generate interrupt request signals
285 always @(posedge wb_clk_i or negedge rst_i)
287 wb_inta_o <= #1 1'b0;
289 wb_inta_o <= #1 1'b0;
291 wb_inta_o <= #1 irq_flag && ien; // interrupt signal is only generated when IEN (interrupt enable bit is set)
293 // assign status register bits
294 assign sr[7] = rxack;
295 assign sr[6] = i2c_busy;
297 assign sr[4:2] = 3'h0; // reserved
299 assign sr[0] = irq_flag;