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 79module 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 301endmodule 302