[1766] | 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.8 2009-01-19 20:29:26 rherveille Exp $ |
---|
| 41 | // |
---|
| 42 | // $Date: 2009-01-19 20:29:26 $ |
---|
| 43 | // $Revision: 1.8 $ |
---|
| 44 | // $Author: rherveille $ |
---|
| 45 | // $Locker: $ |
---|
| 46 | // $State: Exp $ |
---|
| 47 | // |
---|
| 48 | // Change History: |
---|
| 49 | // $Log: not supported by cvs2svn $ |
---|
| 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 | |
---|
| 75 | module 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; // synopsys 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 |
---|
| 344 | endmodule |
---|