OpenCores
URL https://opencores.org/ocsvn/i2c/i2c/trunk

Subversion Repositories i2c

[/] [i2c/] [tags/] [rel_1/] [rtl/] [verilog/] [i2c_master_bit_ctrl.v] - Diff between revs 10 and 14

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 10 Rev 14
 
/////////////////////////////////////////////////////////////////////
 
////                                                             ////
 
////  WISHBONE rev.B2 compliant I2C Master bit-controller        ////
 
////                                                             ////
 
////                                                             ////
 
////  Author: Richard Herveille                                  ////
 
////          richard@asics.ws                                   ////
 
////          www.asics.ws                                       ////
 
////                                                             ////
 
////  Downloaded from: http://www.opencores.org/projects/i2c/    ////
 
////                                                             ////
 
/////////////////////////////////////////////////////////////////////
 
////                                                             ////
 
//// Copyright (C) 2001 Richard Herveille                        ////
 
////                    richard@asics.ws                         ////
 
////                                                             ////
 
//// This source file may be used and distributed without        ////
 
//// restriction provided that this copyright statement is not   ////
 
//// removed from the file and that any derivative work contains ////
 
//// the original copyright notice and the associated disclaimer.////
 
////                                                             ////
 
////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
 
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
 
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
 
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
 
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
 
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
 
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
 
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
 
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
 
//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
 
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
 
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
 
//// POSSIBILITY OF SUCH DAMAGE.                                 ////
 
////                                                             ////
 
/////////////////////////////////////////////////////////////////////
 
 
 
//  CVS Log
 
//
 
//  $Id: i2c_master_bit_ctrl.v,v 1.2 2001-11-05 11:59:25 rherveille Exp $
 
//
 
//  $Date: 2001-11-05 11:59:25 $
 
//  $Revision: 1.2 $
 
//  $Author: rherveille $
 
//  $Locker:  $
 
//  $State: Exp $
//
//
// WISHBONE revB2 compiant I2C master core, bit controller
// Change History:
//
//               $Log: not supported by cvs2svn $
// author: Richard Herveille
 
// rev. 0.1 August 19th, 2001. Initial Verilog release.
 
//
 
 
 
 
 
//
//
/////////////////////////////////////
/////////////////////////////////////
// Bit controller section
// Bit controller section
/////////////////////////////////////
/////////////////////////////////////
//
//
// Translate simple commands into SCL/SDA transitions
// Translate simple commands into SCL/SDA transitions
// Each command has 5 states, A/B/C/D/idle
// Each command has 5 states, A/B/C/D/idle
//
//
// start:       SCL     ~~~~~~~~~~\____
// start:       SCL     ~~~~~~~~~~\____
//      SDA     ~~~~~~~~\______
//      SDA     ~~~~~~~~\______
//               x | A | B | C | D | i
//               x | A | B | C | D | i
//
//
// repstart     SCL     ____/~~~~\___
// repstart     SCL     ____/~~~~\___
//      SDA     __/~~~\______
//      SDA     __/~~~\______
//               x | A | B | C | D | i
//               x | A | B | C | D | i
//
//
// stop SCL     ____/~~~~~~~~
// stop SCL     ____/~~~~~~~~
//      SDA     ==\____/~~~~~
//      SDA     ==\____/~~~~~
//               x | A | B | C | D | i
//               x | A | B | C | D | i
//
//
//- write       SCL     ____/~~~~\____
//- write       SCL     ____/~~~~\____
//      SDA     ==X=========X=
//      SDA     ==X=========X=
//               x | A | B | C | D | i
//               x | A | B | C | D | i
//
//
//- read        SCL     ____/~~~~\____
//- read        SCL     ____/~~~~\____
//      SDA     XXXX=====XXXX
//      SDA     XXXX=====XXXX
//               x | A | B | C | D | i
//               x | A | B | C | D | i
//
//
 
 
// Timing:              Normal mode     Fast mode
// Timing:              Normal mode     Fast mode
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// Fscl           100KHz                400KHz
// Fscl           100KHz                400KHz
// Th_scl                4.0us          0.6us   High period of SCL
// Th_scl                4.0us          0.6us   High period of SCL
// Tl_scl                4.7us          1.3us   Low period of SCL
// Tl_scl                4.7us          1.3us   Low period of SCL
// Tsu:sta              4.7us           0.6us   setup time for a repeated start condition
// Tsu:sta              4.7us           0.6us   setup time for a repeated start condition
// Tsu:sto              4.0us           0.6us   setup time for a stop conditon
// Tsu:sto              4.0us           0.6us   setup time for a stop conditon
// Tbuf            4.7us                1.3us   Bus free time between a stop and start condition
// Tbuf            4.7us                1.3us   Bus free time between a stop and start condition
//
//
 
 
`include "timescale.v"
`include "timescale.v"
`include "i2c_master_defines.v"
`include "i2c_master_defines.v"
 
 
module i2c_master_bit_ctrl(clk, rst, nReset, clk_cnt, ena, cmd, cmd_ack, busy, din, dout, scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen);
module i2c_master_bit_ctrl(clk, rst, nReset, clk_cnt, ena, cmd, cmd_ack, busy, din, dout, scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen);
 
 
        //
        //
        // inputs & outputs
        // inputs & outputs
        //
        //
        input clk;
        input clk;
        input rst;
        input rst;
        input nReset;
        input nReset;
        input ena;            // core enable signal
        input ena;            // core enable signal
 
 
        input [15:0] clk_cnt; // clock prescale value
        input [15:0] clk_cnt; // clock prescale value
 
 
        input  [3:0] cmd;
        input  [3:0] cmd;
        output       cmd_ack;
        output       cmd_ack;
        reg cmd_ack;
        reg cmd_ack;
        output       busy;
        output       busy;
        reg busy;
        reg busy;
 
 
        input  din;
        input  din;
        output dout;
        output dout;
        reg dout;
        reg dout;
 
 
        // I2C lines
        // I2C lines
        input  scl_i;    // i2c clock line input
        input  scl_i;    // i2c clock line input
        output scl_o;    // i2c clock line output
        output scl_o;    // i2c clock line output
        output scl_oen;  // i2c clock line output enable (active low)
        output scl_oen;  // i2c clock line output enable (active low)
        reg scl_oen;
        reg scl_oen;
        input  sda_i;    // i2c data line input
        input  sda_i;    // i2c data line input
        output sda_o;    // i2c data line output
        output sda_o;    // i2c data line output
        output sda_oen;  // i2c data line output enable (active low)
        output sda_oen;  // i2c data line output enable (active low)
        reg sda_oen;
        reg sda_oen;
 
 
 
 
        //
        //
        // variable declarations
        // variable declarations
        //
        //
 
 
        reg sSCL, sSDA;                             // synchronized SCL and SDA inputs
        reg sSCL, sSDA;                             // synchronized SCL and SDA inputs
        reg clk_en;                 // clock generation signals
        reg clk_en;                 // clock generation signals
        wire slave_wait;
        wire slave_wait;
//      reg [15:0] cnt = clk_cnt;         // clock divider counter (simulation)
//      reg [15:0] cnt = clk_cnt;         // clock divider counter (simulation)
        reg [15:0] cnt;             // clock divider counter (synthesis)
        reg [15:0] cnt;             // clock divider counter (synthesis)
 
 
        //
        //
        // module body
        // module body
        //
        //
 
 
        // synchronize SCL and SDA inputs
        // synchronize SCL and SDA inputs
        always@(posedge clk)
        always@(posedge clk)
                begin
                begin
                        sSCL <= #1 scl_i;
                        sSCL <= #1 scl_i;
                        sSDA <= #1 sda_i;
                        sSDA <= #1 sda_i;
                end
                end
 
 
        // whenever the slave is not ready it can delay the cycle by pulling SCL low
        // whenever the slave is not ready it can delay the cycle by pulling SCL low
        assign slave_wait = scl_oen && !sSCL;
        assign slave_wait = scl_oen && !sSCL;
 
 
        // generate clk enable signal
        // generate clk enable signal
        always@(posedge clk or negedge nReset)
        always@(posedge clk or negedge nReset)
                if (!nReset)
                if (!nReset)
                        begin
                        begin
                                cnt    <= #1 15'h0;
                                cnt    <= #1 16'h0;
                                clk_en <= #1 1'b1;
                                clk_en <= #1 1'b1;
                        end
                        end
                else if (rst)
                else if (rst)
                        begin
                        begin
                                cnt    <= #1 15'h0;
                                cnt    <= #1 16'h0;
                                clk_en <= #1 1'b1;
                                clk_en <= #1 1'b1;
                        end
                        end
                else if ( !(|cnt) || !ena)
                else if ( !(|cnt) || !ena)
                        begin
                        begin
                                cnt    <= #1 clk_cnt;
                                cnt    <= #1 clk_cnt;
                                clk_en <= #1 1'b1;
                                clk_en <= #1 1'b1;
                        end
                        end
                else
                else
                        begin
                        begin
                                if (!slave_wait)
                                if (!slave_wait)
                                        cnt <= #1 cnt - 1'h1;
                                        cnt <= #1 cnt - 16'h1;
 
 
                                clk_en <= #1 1'b0;
                                clk_en <= #1 1'b0;
                        end
                        end
 
 
 
 
        // generate bus status controller
        // generate bus status controller
        reg dSDA;
        reg dSDA;
        reg sta_condition;
        reg sta_condition;
        reg sto_condition;
        reg sto_condition;
 
 
        // detect start condition => detect falling edge on SDA while SCL is high
        // detect start condition => detect falling edge on SDA while SCL is high
        // detect stop condition => detect rising edge on SDA while SCL is high
        // detect stop condition => detect rising edge on SDA while SCL is high
        always@(posedge clk)
        always@(posedge clk)
                begin
                begin
                        dSDA <= #1 sSDA; // generate a delayed versio nof sSDA
                        dSDA <= #1 sSDA; // generate a delayed versio nof sSDA
 
 
                        sta_condition <= #1 !sSDA &&  dSDA && sSCL;
                        sta_condition <= #1 !sSDA &&  dSDA && sSCL;
                        sto_condition <= #1  sSDA && !dSDA && sSCL;
                        sto_condition <= #1  sSDA && !dSDA && sSCL;
                end
                end
 
 
        // generate bus busy signal
        // generate bus busy signal
        always@(posedge clk or negedge nReset)
        always@(posedge clk or negedge nReset)
                if (!nReset)
                if (!nReset)
                        busy <= #1 1'b0;
                        busy <= #1 1'b0;
                else if (rst)
                else if (rst)
                        busy <= #1 1'b0;
                        busy <= #1 1'b0;
                else
                else
                        busy <= (sta_condition || busy) && !sto_condition;
                        busy <= (sta_condition || busy) && !sto_condition;
 
 
 
 
        // generate statemachine
        // generate statemachine
 
 
        // nxt_state decoder
        // nxt_state decoder
        parameter [14:0] idle    = 15'b000_0000_0000_0000;
        parameter [14:0] idle    = 15'b000_0000_0000_0000;
        parameter [14:0] start_a = 15'b000_0000_0000_0001;
        parameter [14:0] start_a = 15'b000_0000_0000_0001;
        parameter [14:0] start_b = 15'b000_0000_0000_0010;
        parameter [14:0] start_b = 15'b000_0000_0000_0010;
        parameter [14:0] start_c = 15'b000_0000_0000_0100;
        parameter [14:0] start_c = 15'b000_0000_0000_0100;
        parameter [14:0] start_d = 15'b000_0000_0000_1000;
        parameter [14:0] start_d = 15'b000_0000_0000_1000;
        parameter [14:0] stop_a  = 15'b000_0000_0001_0000;
        parameter [14:0] stop_a  = 15'b000_0000_0001_0000;
        parameter [14:0] stop_b  = 15'b000_0000_0010_0000;
        parameter [14:0] stop_b  = 15'b000_0000_0010_0000;
        parameter [14:0] stop_c  = 15'b000_0000_0100_0000;
        parameter [14:0] stop_c  = 15'b000_0000_0100_0000;
        parameter [14:0] rd_a    = 15'b000_0000_1000_0000;
        parameter [14:0] rd_a    = 15'b000_0000_1000_0000;
        parameter [14:0] rd_b    = 15'b000_0001_0000_0000;
        parameter [14:0] rd_b    = 15'b000_0001_0000_0000;
        parameter [14:0] rd_c    = 15'b000_0010_0000_0000;
        parameter [14:0] rd_c    = 15'b000_0010_0000_0000;
        parameter [14:0] rd_d    = 15'b000_0100_0000_0000;
        parameter [14:0] rd_d    = 15'b000_0100_0000_0000;
        parameter [14:0] wr_a    = 15'b000_1000_0000_0000;
        parameter [14:0] wr_a    = 15'b000_1000_0000_0000;
        parameter [14:0] wr_b    = 15'b001_0000_0000_0000;
        parameter [14:0] wr_b    = 15'b001_0000_0000_0000;
        parameter [14:0] wr_c    = 15'b010_0000_0000_0000;
        parameter [14:0] wr_c    = 15'b010_0000_0000_0000;
        parameter [14:0] wr_d    = 15'b100_0000_0000_0000;
        parameter [14:0] wr_d    = 15'b100_0000_0000_0000;
 
 
        reg [14:0] c_state, nxt_state; // synopsis enum_state
        reg [14:0] c_state, nxt_state; // synopsis enum_state
        reg icmd_ack, store_sda;
        reg icmd_ack, store_sda;
 
 
        always@(c_state or cmd)
        always@(c_state or cmd)
                begin
                begin
                                nxt_state  = c_state;
                                nxt_state  = c_state;
                                icmd_ack   = 1'b0; // default no command acknowledge
                                icmd_ack   = 1'b0; // default no command acknowledge
                                store_sda  = 1'b0;
                                store_sda  = 1'b0;
 
 
                                case (c_state) // synopsis full_case parallel_case
                                case (c_state) // synopsis full_case parallel_case
                                        // idle state
                                        // idle state
                                        idle:
                                        idle:
                                                case (cmd) // synopsis full_case parallel_case
                                                case (cmd) // synopsis full_case parallel_case
                                                        `I2C_CMD_START:
                                                        `I2C_CMD_START:
                                                                nxt_state = start_a;
                                                                nxt_state = start_a;
 
 
                                                        `I2C_CMD_STOP:
                                                        `I2C_CMD_STOP:
                                                                nxt_state = stop_a;
                                                                nxt_state = stop_a;
 
 
                                                        `I2C_CMD_WRITE:
                                                        `I2C_CMD_WRITE:
                                                                nxt_state = wr_a;
                                                                nxt_state = wr_a;
 
 
                                                        `I2C_CMD_READ:
                                                        `I2C_CMD_READ:
                                                                nxt_state = rd_a;
                                                                nxt_state = rd_a;
 
 
                                                        default:
                                                        default:
                                                                nxt_state = idle;
                                                                nxt_state = idle;
 
 
                                                endcase
                                                endcase
 
 
                                        // start                        
                                        // start                        
                                        start_a:
                                        start_a:
                                                nxt_state = start_b;
                                                nxt_state = start_b;
 
 
                                        start_b:
                                        start_b:
                                                nxt_state = start_c;
                                                nxt_state = start_c;
 
 
                                        start_c:
                                        start_c:
                                                nxt_state = start_d;
                                                nxt_state = start_d;
 
 
                                        start_d:
                                        start_d:
                                                begin
                                                begin
                                                        nxt_state = idle;
                                                        nxt_state = idle;
                                                        icmd_ack  = 1'b1;
                                                        icmd_ack  = 1'b1;
                                                end
                                                end
 
 
                                        // stop                 
                                        // stop                 
                                        stop_a:
                                        stop_a:
                                                nxt_state = stop_b;
                                                nxt_state = stop_b;
 
 
                                        stop_b:
                                        stop_b:
                                                nxt_state = stop_c;
                                                nxt_state = stop_c;
 
 
                                        stop_c:
                                        stop_c:
                                                begin
                                                begin
                                                        nxt_state = idle;
                                                        nxt_state = idle;
                                                        icmd_ack  = 1'b1;
                                                        icmd_ack  = 1'b1;
                                                end
                                                end
 
 
                                        // read
                                        // read
                                        rd_a:
                                        rd_a:
                                                nxt_state = rd_b;
                                                nxt_state = rd_b;
 
 
                                        rd_b:
                                        rd_b:
                                                nxt_state = rd_c;
                                                nxt_state = rd_c;
 
 
                                        rd_c:
                                        rd_c:
                                                begin
                                                begin
                                                        nxt_state = rd_d;
                                                        nxt_state = rd_d;
                                                        store_sda = 1'b1;
                                                        store_sda = 1'b1;
                                                end
                                                end
 
 
                                        rd_d:
                                        rd_d:
                                                begin
                                                begin
                                                        nxt_state = idle;
                                                        nxt_state = idle;
                                                        icmd_ack  = 1'b1;
                                                        icmd_ack  = 1'b1;
                                                end
                                                end
 
 
                                        // write
                                        // write
                                        wr_a:
                                        wr_a:
                                                nxt_state = wr_b;
                                                nxt_state = wr_b;
 
 
                                        wr_b:
                                        wr_b:
                                                nxt_state = wr_c;
                                                nxt_state = wr_c;
 
 
                                        wr_c:
                                        wr_c:
                                                nxt_state = wr_d;
                                                nxt_state = wr_d;
 
 
                                        wr_d:
                                        wr_d:
                                                begin
                                                begin
                                                        nxt_state = idle;
                                                        nxt_state = idle;
                                                        icmd_ack  = 1'b1;
                                                        icmd_ack  = 1'b1;
                                                end
                                                end
 
 
                                endcase
                                endcase
                end
                end
 
 
 
 
        // generate registers
        // generate registers
        always@(posedge clk or negedge nReset)
        always@(posedge clk or negedge nReset)
                if (!nReset)
                if (!nReset)
                        begin
                        begin
                                c_state <= #1 idle;
                                c_state <= #1 idle;
                                cmd_ack <= #1 1'b0;
                                cmd_ack <= #1 1'b0;
                                dout    <= #1 1'b0;
                                dout    <= #1 1'b0;
                        end
                        end
                else if (rst)
                else if (rst)
                        begin
                        begin
                                c_state <= #1 idle;
                                c_state <= #1 idle;
                                cmd_ack <= #1 1'b0;
                                cmd_ack <= #1 1'b0;
                                dout    <= #1 1'b0;
                                dout    <= #1 1'b0;
                        end
                        end
                else
                else
                        begin
                        begin
                                if (clk_en)
                                if (clk_en)
                                        begin
                                        begin
                                                c_state <= #1 nxt_state;
                                                c_state <= #1 nxt_state;
                                                if(store_sda)
                                                if(store_sda)
                                                        dout <= #1 sSDA;
                                                        dout <= #1 sSDA;
                                        end
                                        end
 
 
                                cmd_ack <= #1 icmd_ack && clk_en;
                                cmd_ack <= #1 icmd_ack && clk_en;
                        end
                        end
 
 
        //
        //
        // convert states to SCL and SDA signals
        // convert states to SCL and SDA signals
        //
        //
 
 
        // assign scl and sda output (always gnd)
        // assign scl and sda output (always gnd)
        assign scl_o = 1'b0;
        assign scl_o = 1'b0;
        assign sda_o = 1'b0;
        assign sda_o = 1'b0;
 
 
        // assign scl and sda output_enables
        // assign scl and sda output_enables
        always@(posedge clk or negedge nReset)
        always@(posedge clk or negedge nReset)
                if (!nReset)
                if (!nReset)
                        begin
                        begin
                                scl_oen <= #1 1'b1;
                                scl_oen <= #1 1'b1;
                                sda_oen <= #1 1'b1;
                                sda_oen <= #1 1'b1;
                        end
                        end
                else if (rst)
                else if (rst)
                        begin
                        begin
                                scl_oen <= #1 1'b1;
                                scl_oen <= #1 1'b1;
                                sda_oen <= #1 1'b1;
                                sda_oen <= #1 1'b1;
                        end
                        end
                else    if (clk_en)
                else    if (clk_en)
                        case (c_state) // synopsis full_case parallel_case
                        case (c_state) // synopsis full_case parallel_case
 
 
                                // idle state
                                // idle state
                                idle:
                                idle:
                                        begin
                                        begin
                                                scl_oen <= #1 scl_oen; // keep SCL in same state
                                                scl_oen <= #1 scl_oen; // keep SCL in same state
                                                sda_oen <= #1 sda_oen; // keep SDA in same state
                                                sda_oen <= #1 sda_oen; // keep SDA in same state
                                        end
                                        end
 
 
                                // start
                                // start
                                start_a:
                                start_a:
                                        begin
                                        begin
                                                scl_oen <= #1 scl_oen; // keep SCL in same state
                                                scl_oen <= #1 scl_oen; // keep SCL in same state
                                                sda_oen <= #1 1'b1;    // set SDA high
                                                sda_oen <= #1 1'b1;    // set SDA high
                                        end
                                        end
 
 
                                start_b:
                                start_b:
                                        begin
                                        begin
                                                scl_oen <= #1 1'b1; // set SCL high
                                                scl_oen <= #1 1'b1; // set SCL high
                                                sda_oen <= #1 1'b1; // keep SDA high
                                                sda_oen <= #1 1'b1; // keep SDA high
                                        end
                                        end
 
 
                                start_c:
                                start_c:
                                        begin
                                        begin
                                                scl_oen <= #1 1'b1; // keep SCL high
                                                scl_oen <= #1 1'b1; // keep SCL high
                                                sda_oen <= #1 1'b0; // set SDA low
                                                sda_oen <= #1 1'b0; // set SDA low
                                        end
                                        end
 
 
                                start_d:
                                start_d:
                                        begin
                                        begin
                                                scl_oen <= #1 1'b0; // set SCL low
                                                scl_oen <= #1 1'b0; // set SCL low
                                                sda_oen <= #1 1'b0; // keep SDA low
                                                sda_oen <= #1 1'b0; // keep SDA low
                                        end
                                        end
 
 
                                // stop
                                // stop
                                stop_a:
                                stop_a:
                                        begin
                                        begin
                                                scl_oen <= #1 1'b0; // keep SCL low
                                                scl_oen <= #1 1'b0; // keep SCL low
                                                sda_oen <= #1 1'b0; // set SDA low
                                                sda_oen <= #1 1'b0; // set SDA low
                                        end
                                        end
 
 
                                stop_b:
                                stop_b:
                                        begin
                                        begin
                                                scl_oen <= #1 1'b1; // set SCL high
                                                scl_oen <= #1 1'b1; // set SCL high
                                                sda_oen <= #1 1'b0; // keep SDA low
                                                sda_oen <= #1 1'b0; // keep SDA low
                                        end
                                        end
 
 
                                stop_c:
                                stop_c:
                                        begin
                                        begin
                                                scl_oen <= #1 1'b1; // keep SCL high
                                                scl_oen <= #1 1'b1; // keep SCL high
                                                sda_oen <= #1 1'b1; // set SDA high
                                                sda_oen <= #1 1'b1; // set SDA high
                                        end
                                        end
 
 
                                //write
                                //write
                                wr_a:
                                wr_a:
                                        begin
                                        begin
                                                scl_oen <= #1 1'b0; // keep SCL low
                                                scl_oen <= #1 1'b0; // keep SCL low
                                                sda_oen <= #1 din;  // set SDA
                                                sda_oen <= #1 din;  // set SDA
                                        end
                                        end
 
 
                                wr_b:
                                wr_b:
                                        begin
                                        begin
                                                scl_oen <= #1 1'b1; // set SCL high
                                                scl_oen <= #1 1'b1; // set SCL high
                                                sda_oen <= #1 din;  // keep SDA
                                                sda_oen <= #1 din;  // keep SDA
                                        end
                                        end
 
 
                                wr_c:
                                wr_c:
                                        begin
                                        begin
                                                scl_oen <= #1 1'b1; // keep SCL high
                                                scl_oen <= #1 1'b1; // keep SCL high
                                                sda_oen <= #1 din;
                                                sda_oen <= #1 din;
                                        end
                                        end
 
 
                                wr_d:
                                wr_d:
                                        begin
                                        begin
                                                scl_oen <= #1 1'b0; // set SCL low
                                                scl_oen <= #1 1'b0; // set SCL low
                                                sda_oen <= #1 din;
                                                sda_oen <= #1 din;
                                        end
                                        end
 
 
                                // read
                                // read
                                rd_a:
                                rd_a:
                                        begin
                                        begin
                                                scl_oen <= #1 1'b0; // keep SCL low
                                                scl_oen <= #1 1'b0; // keep SCL low
                                                sda_oen <= #1 1'b1; // tri-state SDA
                                                sda_oen <= #1 1'b1; // tri-state SDA
                                        end
                                        end
 
 
                                rd_b:
                                rd_b:
                                        begin
                                        begin
                                                scl_oen <= #1 1'b1; // set SCL high
                                                scl_oen <= #1 1'b1; // set SCL high
                                                sda_oen <= #1 1'b1; // keep SDA tri-stated
                                                sda_oen <= #1 1'b1; // keep SDA tri-stated
                                        end
                                        end
 
 
                                rd_c:
                                rd_c:
                                        begin
                                        begin
                                                scl_oen <= #1 1'b1; // keep SCL high
                                                scl_oen <= #1 1'b1; // keep SCL high
                                                sda_oen <= #1 1'b1;
                                                sda_oen <= #1 1'b1;
                                        end
                                        end
 
 
                                rd_d:
                                rd_d:
                                        begin
                                        begin
                                                scl_oen <= #1 1'b0; // set SCL low
                                                scl_oen <= #1 1'b0; // set SCL low
                                                sda_oen <= #1 1'b1;
                                                sda_oen <= #1 1'b1;
                                        end
                                        end
 
 
                        endcase
                        endcase
 
 
endmodule
endmodule
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.