1///////////////////////////////////////////////////////////////////// 2//// //// 3//// WISHBONE rev.B2 compliant I2C Master byte-controller //// 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_byte_ctrl.v,v 1.7 2004/02/18 11:40:46 rherveille Exp $ 41// 42// $Date: 2004/02/18 11:40:46 $ 43// $Revision: 1.7 $ 44// $Author: rherveille $ 45// $Locker: $ 46// $State: Exp $ 47// 48// Change History: 49// $Log: i2c_master_byte_ctrl.v,v $ 50// Revision 1.7 2004/02/18 11:40:46 rherveille 51// Fixed a potential bug in the statemachine. During a 'stop' 2 cmd_ack signals were generated. Possibly canceling a new start command. 52// 53// Revision 1.6 2003/08/09 07:01:33 rherveille 54// Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line. 55// Fixed a potential bug in the byte controller's host-acknowledge generation. 56// 57// Revision 1.5 2002/12/26 15:02:32 rherveille 58// Core is now a Multimaster I2C controller 59// 60// Revision 1.4 2002/11/30 22:24:40 rherveille 61// Cleaned up code 62// 63// Revision 1.3 2001/11/05 11:59:25 rherveille 64// Fixed wb_ack_o generation bug. 65// Fixed bug in the byte_controller statemachine. 66// Added headers. 67// 68 69// synopsys translate_off 70//`include "timescale.v" 71// synopsys translate_on 72 73`include "i2c_master_defines.v" 74 75module i2c_master_byte_ctrl ( 76 clk, rst, nReset, ena, clk_cnt, start, stop, read, write, ack_in, din, 77 cmd_ack, ack_out, dout, i2c_busy, i2c_al, scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen ); 78 79 // 80 // inputs & outputs 81 // 82 input clk; // master clock 83 input rst; // synchronous active high reset 84 input nReset; // asynchronous active low reset 85 input ena; // core enable signal 86 87 input [15:0] clk_cnt; // 4x SCL 88 89 // control inputs 90 input start; 91 input stop; 92 input read; 93 input write; 94 input ack_in; 95 input [7:0] din; 96 97 // status outputs 98 output cmd_ack; 99 reg cmd_ack; 100 output ack_out; 101 reg ack_out; 102 output i2c_busy; 103 output i2c_al; 104 output [7:0] dout; 105 106 // I2C signals 107 input scl_i; 108 output scl_o; 109 output scl_oen; 110 input sda_i; 111 output sda_o; 112 output sda_oen; 113 114 115 // 116 // Variable declarations 117 // 118 119 // statemachine 120 parameter [4:0] ST_IDLE = 5'b0_0000; 121 parameter [4:0] ST_START = 5'b0_0001; 122 parameter [4:0] ST_READ = 5'b0_0010; 123 parameter [4:0] ST_WRITE = 5'b0_0100; 124 parameter [4:0] ST_ACK = 5'b0_1000; 125 parameter [4:0] ST_STOP = 5'b1_0000; 126 127 // signals for bit_controller 128 reg [3:0] core_cmd; 129 reg core_txd; 130 wire core_ack, core_rxd; 131 132 // signals for shift register 133 reg [7:0] sr; //8bit shift register 134 reg shift, ld; 135 136 // signals for state machine 137 wire go; 138 reg [2:0] dcnt; 139 wire cnt_done; 140 141 // 142 // Module body 143 // 144 145 // hookup bit_controller 146 i2c_master_bit_ctrl bit_controller ( 147 .clk ( clk ), 148 .rst ( rst ), 149 .nReset ( nReset ), 150 .ena ( ena ), 151 .clk_cnt ( clk_cnt ), 152 .cmd ( core_cmd ), 153 .cmd_ack ( core_ack ), 154 .busy ( i2c_busy ), 155 .al ( i2c_al ), 156 .din ( core_txd ), 157 .dout ( core_rxd ), 158 .scl_i ( scl_i ), 159 .scl_o ( scl_o ), 160 .scl_oen ( scl_oen ), 161 .sda_i ( sda_i ), 162 .sda_o ( sda_o ), 163 .sda_oen ( sda_oen ) 164 ); 165 166 // generate go-signal 167 assign go = (read | write | stop) & ~cmd_ack; 168 169 // assign dout output to shift-register 170 assign dout = sr; 171 172 // generate shift register 173 always @(posedge clk or negedge nReset) 174 if (!nReset) 175 sr <= #1 8'h0; 176 else if (rst) 177 sr <= #1 8'h0; 178 else if (ld) 179 sr <= #1 din; 180 else if (shift) 181 sr <= #1 {sr[6:0], core_rxd}; 182 183 // generate counter 184 always @(posedge clk or negedge nReset) 185 if (!nReset) 186 dcnt <= #1 3'h0; 187 else if (rst) 188 dcnt <= #1 3'h0; 189 else if (ld) 190 dcnt <= #1 3'h7; 191 else if (shift) 192 dcnt <= #1 dcnt - 3'h1; 193 194 assign cnt_done = ~(|dcnt); 195 196 // 197 // state machine 198 // 199 reg [4:0] c_state; // synopsis enum_state 200 201 always @(posedge clk or negedge nReset) 202 if (!nReset) 203 begin 204 core_cmd <= #1 `I2C_CMD_NOP; 205 core_txd <= #1 1'b0; 206 shift <= #1 1'b0; 207 ld <= #1 1'b0; 208 cmd_ack <= #1 1'b0; 209 c_state <= #1 ST_IDLE; 210 ack_out <= #1 1'b0; 211 end 212 else if (rst | i2c_al) 213 begin 214 core_cmd <= #1 `I2C_CMD_NOP; 215 core_txd <= #1 1'b0; 216 shift <= #1 1'b0; 217 ld <= #1 1'b0; 218 cmd_ack <= #1 1'b0; 219 c_state <= #1 ST_IDLE; 220 ack_out <= #1 1'b0; 221 end 222 else 223 begin 224 // initially reset all signals 225 core_txd <= #1 sr[7]; 226 shift <= #1 1'b0; 227 ld <= #1 1'b0; 228 cmd_ack <= #1 1'b0; 229 230 case (c_state) // synopsys full_case parallel_case 231 ST_IDLE: 232 if (go) 233 begin 234 if (start) 235 begin 236 c_state <= #1 ST_START; 237 core_cmd <= #1 `I2C_CMD_START; 238 end 239 else if (read) 240 begin 241 c_state <= #1 ST_READ; 242 core_cmd <= #1 `I2C_CMD_READ; 243 end 244 else if (write) 245 begin 246 c_state <= #1 ST_WRITE; 247 core_cmd <= #1 `I2C_CMD_WRITE; 248 end 249 else // stop 250 begin 251 c_state <= #1 ST_STOP; 252 core_cmd <= #1 `I2C_CMD_STOP; 253 end 254 255 ld <= #1 1'b1; 256 end 257 258 ST_START: 259 if (core_ack) 260 begin 261 if (read) 262 begin 263 c_state <= #1 ST_READ; 264 core_cmd <= #1 `I2C_CMD_READ; 265 end 266 else 267 begin 268 c_state <= #1 ST_WRITE; 269 core_cmd <= #1 `I2C_CMD_WRITE; 270 end 271 272 ld <= #1 1'b1; 273 end 274 275 ST_WRITE: 276 if (core_ack) 277 if (cnt_done) 278 begin 279 c_state <= #1 ST_ACK; 280 core_cmd <= #1 `I2C_CMD_READ; 281 end 282 else 283 begin 284 c_state <= #1 ST_WRITE; // stay in same state 285 core_cmd <= #1 `I2C_CMD_WRITE; // write next bit 286 shift <= #1 1'b1; 287 end 288 289 ST_READ: 290 if (core_ack) 291 begin 292 if (cnt_done) 293 begin 294 c_state <= #1 ST_ACK; 295 core_cmd <= #1 `I2C_CMD_WRITE; 296 end 297 else 298 begin 299 c_state <= #1 ST_READ; // stay in same state 300 core_cmd <= #1 `I2C_CMD_READ; // read next bit 301 end 302 303 shift <= #1 1'b1; 304 core_txd <= #1 ack_in; 305 end 306 307 ST_ACK: 308 if (core_ack) 309 begin 310 if (stop) 311 begin 312 c_state <= #1 ST_STOP; 313 core_cmd <= #1 `I2C_CMD_STOP; 314 end 315 else 316 begin 317 c_state <= #1 ST_IDLE; 318 core_cmd <= #1 `I2C_CMD_NOP; 319 320 // generate command acknowledge signal 321 cmd_ack <= #1 1'b1; 322 end 323 324 // assign ack_out output to bit_controller_rxd (contains last received bit) 325 ack_out <= #1 core_rxd; 326 327 core_txd <= #1 1'b1; 328 end 329 else 330 core_txd <= #1 ack_in; 331 332 ST_STOP: 333 if (core_ack) 334 begin 335 c_state <= #1 ST_IDLE; 336 core_cmd <= #1 `I2C_CMD_NOP; 337 338 // generate command acknowledge signal 339 cmd_ack <= #1 1'b1; 340 end 341 342 endcase 343 end 344endmodule 345