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

Subversion Repositories i2c

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

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

Rev 13 Rev 14
 
/////////////////////////////////////////////////////////////////////
 
////                                                             ////
 
////  WISHBONE rev.B2 compliant I2C Master byte-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_byte_ctrl.v,v 1.3 2001-11-05 11:59:25 rherveille Exp $
 
//
 
//  $Date: 2001-11-05 11:59:25 $
 
//  $Revision: 1.3 $
 
//  $Author: rherveille $
 
//  $Locker:  $
 
//  $State: Exp $
//
//
// WISHBONE revB2 compiant I2C master core
// Change History:
//
//               $Log: not supported by cvs2svn $
// author: Richard Herveille
 
// rev. 0.1 August  24th, 2001. Initial Verilog release.
 
// rev. 0.2 October 25th, 2001. Fixed some synthesis warnings.
 
//
 
 
 
`include "timescale.v"
`include "timescale.v"
`include "i2c_master_defines.v"
`include "i2c_master_defines.v"
 
 
module i2c_master_byte_ctrl (
module i2c_master_byte_ctrl (
        clk, rst, nReset, ena, clk_cnt, start, stop, read, write, ack_in, din,
        clk, rst, nReset, ena, clk_cnt, start, stop, read, write, ack_in, din,
        cmd_ack, ack_out, dout, i2c_busy, scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen );
        cmd_ack, ack_out, dout, i2c_busy, scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen );
 
 
        //
        //
        // inputs & outputs
        // inputs & outputs
        //
        //
        input clk;     // master clock
        input clk;     // master clock
        input rst;     // synchronous active high reset
        input rst;     // synchronous active high reset
        input nReset;  // asynchronous active low reset
        input nReset;  // asynchronous active low reset
        input ena;     // core enable signal
        input ena;     // core enable signal
 
 
        input [15:0] clk_cnt; // 4x SCL
        input [15:0] clk_cnt; // 4x SCL
 
 
        // control inputs
        // control inputs
        input       start;
        input       start;
        input       stop;
        input       stop;
        input       read;
        input       read;
        input       write;
        input       write;
        input       ack_in;
        input       ack_in;
        input [7:0] din;
        input [7:0] din;
 
 
        // status outputs
        // status outputs
        output       cmd_ack;
        output       cmd_ack;
        reg cmd_ack;
        reg cmd_ack;
        output       ack_out;
        output       ack_out;
        reg ack_out;
        reg ack_out;
        output       i2c_busy;
        output       i2c_busy;
        output [7:0] dout;
        output [7:0] dout;
 
 
        // I2C signals
        // I2C signals
        input  scl_i;
        input  scl_i;
        output scl_o;
        output scl_o;
        output scl_oen;
        output scl_oen;
        input  sda_i;
        input  sda_i;
        output sda_o;
        output sda_o;
        output sda_oen;
        output sda_oen;
 
 
 
 
        //
        //
        // Variable declarations
        // Variable declarations
        //
        //
 
 
        // statemachine
        // statemachine
        parameter [4:0] ST_IDLE  = 5'b0_0000;
        parameter [4:0] ST_IDLE  = 5'b0_0000;
        parameter [4:0] ST_START = 5'b0_0001;
        parameter [4:0] ST_START = 5'b0_0001;
        parameter [4:0] ST_READ  = 5'b0_0010;
        parameter [4:0] ST_READ  = 5'b0_0010;
        parameter [4:0] ST_WRITE = 5'b0_0100;
        parameter [4:0] ST_WRITE = 5'b0_0100;
        parameter [4:0] ST_ACK   = 5'b0_1000;
        parameter [4:0] ST_ACK   = 5'b0_1000;
        parameter [4:0] ST_STOP  = 5'b1_0000;
        parameter [4:0] ST_STOP  = 5'b1_0000;
 
 
        // signals for bit_controller
        // signals for bit_controller
        reg  [3:0] core_cmd;
        reg  [3:0] core_cmd;
        reg        core_txd;
        reg        core_txd;
        wire       core_ack, core_rxd;
        wire       core_ack, core_rxd;
 
 
        // signals for shift register
        // signals for shift register
        reg [7:0] sr; //8bit shift register
        reg [7:0] sr; //8bit shift register
        reg       shift, ld;
        reg       shift, ld;
 
 
        // signals for state machine
        // signals for state machine
        wire       go;
        wire       go;
        reg  [3:0] dcnt;
        reg  [2:0] dcnt;
        wire       cnt_done;
        wire       cnt_done;
 
 
        //
        //
        // Module body
        // Module body
        //
        //
 
 
        // hookup bit_controller
        // hookup bit_controller
        i2c_master_bit_ctrl bit_controller (
        i2c_master_bit_ctrl bit_controller (
                .clk(clk),
                .clk(clk),
                .rst(rst),
                .rst(rst),
                .nReset(nReset),
                .nReset(nReset),
                .ena(ena),
                .ena(ena),
                .clk_cnt(clk_cnt),
                .clk_cnt(clk_cnt),
                .cmd(core_cmd),
                .cmd(core_cmd),
                .cmd_ack(core_ack),
                .cmd_ack(core_ack),
                .busy(i2c_busy),
                .busy(i2c_busy),
                .din(core_txd),
                .din(core_txd),
                .dout(core_rxd),
                .dout(core_rxd),
                .scl_i(scl_i),
                .scl_i(scl_i),
                .scl_o(scl_o),
                .scl_o(scl_o),
                .scl_oen(scl_oen),
                .scl_oen(scl_oen),
                .sda_i(sda_i),
                .sda_i(sda_i),
                .sda_o(sda_o),
                .sda_o(sda_o),
                .sda_oen(sda_oen)
                .sda_oen(sda_oen)
        );
        );
 
 
        // generate go-signal
        // generate go-signal
        assign go = (read || write || stop) && !cmd_ack;
        assign go = (read || write || stop) && !cmd_ack;
 
 
        // assign dout output to shift-register
        // assign dout output to shift-register
        assign dout = sr;
        assign dout = sr;
 
 
        // generate shift register
        // generate shift register
        always@(posedge clk or negedge nReset)
        always@(posedge clk or negedge nReset)
                if (!nReset)
                if (!nReset)
                        sr <= #1 8'h0;
                        sr <= #1 8'h0;
                else if (rst)
                else if (rst)
                        sr <= #1 8'h0;
                        sr <= #1 8'h0;
                else if (ld)
                else if (ld)
                        sr <= #1 din;
                        sr <= #1 din;
                else if (shift)
                else if (shift)
                        sr <= #1 {sr[6:0], core_rxd};
                        sr <= #1 {sr[6:0], core_rxd};
 
 
        // generate counter
        // generate counter
        always@(posedge clk or negedge nReset)
        always@(posedge clk or negedge nReset)
                if (!nReset)
                if (!nReset)
                        dcnt <= #1 4'h0;
                        dcnt <= #1 3'h0;
                else if (rst)
                else if (rst)
                        dcnt <= #1 4'h0;
                        dcnt <= #1 3'h0;
                else if (ld)
                else if (ld)
                        dcnt <= #1 4'h7;
                        dcnt <= #1 3'h7;
                else if (shift)
                else if (shift)
                        dcnt <= #1 dcnt - 4'h1;
                        dcnt <= #1 dcnt - 3'h1;
 
 
        assign cnt_done = !(|dcnt);
        assign cnt_done = !(|dcnt);
 
 
        //
        //
        // state machine
        // state machine
        //
        //
        reg [4:0] c_state; // synopsis enum_state
        reg [4:0] c_state; // synopsis enum_state
 
 
        always@(posedge clk or negedge nReset)
        always@(posedge clk or negedge nReset)
                if (!nReset)
                if (!nReset)
                        begin
                        begin
                                core_cmd <= #1 `I2C_CMD_NOP;
                                core_cmd <= #1 `I2C_CMD_NOP;
                                core_txd <= #1 1'b0;
                                core_txd <= #1 1'b0;
 
 
                                shift    <= #1 1'b0;
                                shift    <= #1 1'b0;
                                ld       <= #1 1'b0;
                                ld       <= #1 1'b0;
 
 
                                cmd_ack  <= #1 1'b0;
                                cmd_ack  <= #1 1'b0;
                                c_state  <= #1 ST_IDLE;
                                c_state  <= #1 ST_IDLE;
 
 
 
                                ack_out  <= #1 1'b0;
                        end
                        end
                else if (rst)
                else if (rst)
                        begin
                        begin
                                core_cmd <= #1 `I2C_CMD_NOP;
                                core_cmd <= #1 `I2C_CMD_NOP;
                                core_txd <= #1 1'b0;
                                core_txd <= #1 1'b0;
 
 
                                shift    <= #1 1'b0;
                                shift    <= #1 1'b0;
                                ld       <= #1 1'b0;
                                ld       <= #1 1'b0;
 
 
                                cmd_ack  <= #1 1'b0;
                                cmd_ack  <= #1 1'b0;
                                c_state  <= #1 ST_IDLE;
                                c_state  <= #1 ST_IDLE;
 
 
 
                                ack_out  <= #1 1'b0;
                        end
                        end
        else
        else
                begin
                begin
                        // initially reset all signals
                        // initially reset all signals
                        core_txd <= #1 sr[7];
                        core_txd <= #1 sr[7];
 
 
                        shift    <= #1 1'b0;
                        shift    <= #1 1'b0;
                        ld       <= #1 1'b0;
                        ld       <= #1 1'b0;
 
 
                        cmd_ack  <= #1 1'b0;
                        cmd_ack  <= #1 1'b0;
 
 
                        case (c_state) // synopsis full_case parallel_case
                        case (c_state) // synopsis full_case parallel_case
                                ST_IDLE:
                                ST_IDLE:
                                        if (go)
                                        if (go)
                                                begin
                                                begin
                                                        if (start)
                                                        if (start)
                                                                begin
                                                                begin
                                                                        c_state  <= #1 ST_START;
                                                                        c_state  <= #1 ST_START;
                                                                        core_cmd <= #1 `I2C_CMD_START;
                                                                        core_cmd <= #1 `I2C_CMD_START;
                                                                end
                                                                end
                                                        else if (read)
                                                        else if (read)
                                                                begin
                                                                begin
                                                                        c_state  <= #1 ST_READ;
                                                                        c_state  <= #1 ST_READ;
                                                                        core_cmd <= #1 `I2C_CMD_READ;
                                                                        core_cmd <= #1 `I2C_CMD_READ;
                                                                end
                                                                end
                                                        else if (write)
                                                        else if (write)
                                                                begin
                                                                begin
                                                                        c_state  <= #1 ST_WRITE;
                                                                        c_state  <= #1 ST_WRITE;
                                                                        core_cmd <= #1 `I2C_CMD_WRITE;
                                                                        core_cmd <= #1 `I2C_CMD_WRITE;
                                                                end
                                                                end
                                                        else // stop
                                                        else // stop
                                                                begin
                                                                begin
                                                                        c_state  <= #1 ST_STOP;
                                                                        c_state  <= #1 ST_STOP;
                                                                        core_cmd <= #1 `I2C_CMD_STOP;
                                                                        core_cmd <= #1 `I2C_CMD_STOP;
 
 
                                                                        // generate command acknowledge signal
                                                                        // generate command acknowledge signal
                                                                        cmd_ack  <= #1 1'b1;
                                                                        cmd_ack  <= #1 1'b1;
                                                                end
                                                                end
 
 
                                                        ld       <= #1 1'b1;
                                                        ld       <= #1 1'b1;
                                                end
                                                end
 
 
                                ST_START:
                                ST_START:
                                        if (core_ack)
                                        if (core_ack)
                                                begin
                                                begin
                                                        if (read)
                                                        if (read)
                                                                begin
                                                                begin
                                                                        c_state  <= #1 ST_READ;
                                                                        c_state  <= #1 ST_READ;
                                                                        core_cmd <= #1 `I2C_CMD_READ;
                                                                        core_cmd <= #1 `I2C_CMD_READ;
                                                                end
                                                                end
                                                        else
                                                        else
                                                                begin
                                                                begin
                                                                        c_state  <= #1 ST_WRITE;
                                                                        c_state  <= #1 ST_WRITE;
                                                                        core_cmd <= #1 `I2C_CMD_WRITE;
                                                                        core_cmd <= #1 `I2C_CMD_WRITE;
                                                                end
                                                                end
 
 
                                                        ld       <= #1 1'b1;
                                                        ld       <= #1 1'b1;
                                                end
                                                end
 
 
                                ST_WRITE:
                                ST_WRITE:
                                        if (core_ack)
                                        if (core_ack)
                                                if (cnt_done)
                                                if (cnt_done)
                                                        begin
                                                        begin
                                                                c_state  <= #1 ST_ACK;
                                                                c_state  <= #1 ST_ACK;
                                                                core_cmd <= #1 `I2C_CMD_READ;
                                                                core_cmd <= #1 `I2C_CMD_READ;
                                                        end
                                                        end
                                                else
                                                else
                                                        begin
                                                        begin
                                                                c_state  <= #1 ST_WRITE;       // stay in same state
                                                                c_state  <= #1 ST_WRITE;       // stay in same state
                                                                core_cmd <= #1 `I2C_CMD_WRITE; // write next bit
                                                                core_cmd <= #1 `I2C_CMD_WRITE; // write next bit
 
 
                                                                shift    <= #1 1'b1;
                                                                shift    <= #1 1'b1;
                                                        end
                                                        end
 
 
                                ST_READ:
                                ST_READ:
                                                if (core_ack)
                                                if (core_ack)
                                                        begin
                                                        begin
                                                                if (cnt_done)
                                                                if (cnt_done)
                                                                        begin
                                                                        begin
                                                                                c_state  <= #1 ST_ACK;
                                                                                c_state  <= #1 ST_ACK;
                                                                                core_cmd <= #1 `I2C_CMD_WRITE;
                                                                                core_cmd <= #1 `I2C_CMD_WRITE;
                                                                        end
                                                                        end
                                                                else
                                                                else
                                                                        begin
                                                                        begin
                                                                                c_state  <= #1 ST_READ;       // stay in same state
                                                                                c_state  <= #1 ST_READ;       // stay in same state
                                                                                core_cmd <= #1 `I2C_CMD_READ; // read next bit
                                                                                core_cmd <= #1 `I2C_CMD_READ; // read next bit
                                                                        end
                                                                        end
 
 
                                                                shift    <= #1 1'b1;
                                                                shift    <= #1 1'b1;
 
                                                                core_txd <= #1 ack_in;
                                                        end
                                                        end
 
 
                                ST_ACK:
                                ST_ACK:
                                        if (core_ack)
                                        if (core_ack)
                                                begin
                                                begin
                                                        if (stop)
                                                        if (stop)
                                                                begin
                                                                begin
                                                                        c_state  <= #1 ST_STOP;
                                                                        c_state  <= #1 ST_STOP;
                                                                        core_cmd <= #1 `I2C_CMD_STOP;
                                                                        core_cmd <= #1 `I2C_CMD_STOP;
                                                                end
                                                                end
                                                        else
                                                        else
                                                                begin
                                                                begin
                                                                        c_state  <= #1 ST_IDLE;
                                                                        c_state  <= #1 ST_IDLE;
                                                                        core_cmd <= #1 `I2C_CMD_NOP;
                                                                        core_cmd <= #1 `I2C_CMD_NOP;
                                                                end
                                                                end
 
 
                                                        // assign ack_out output to bit_controller_rxd (contains last received bit)
                                                        // assign ack_out output to bit_controller_rxd (contains last received bit)
                                                        ack_out = core_rxd;
                                                        ack_out <= #1 core_rxd;
 
 
                                                        // generate command acknowledge signal
                                                        // generate command acknowledge signal
                                                        cmd_ack  <= #1 1'b1;
                                                        cmd_ack  <= #1 1'b1;
 
 
                                                        core_txd <= #1 1'b1;
                                                        core_txd <= #1 1'b1;
                                                end
                                                end
                                        else
                                        else
                                                core_txd <= #1 ack_in;
                                                core_txd <= #1 ack_in;
 
 
                                ST_STOP:
                                ST_STOP:
                                        if (core_ack)
                                        if (core_ack)
                                                begin
                                                begin
                                                        c_state  <= #1 ST_IDLE;
                                                        c_state  <= #1 ST_IDLE;
                                                        core_cmd <= #1 `I2C_CMD_NOP;
                                                        core_cmd <= #1 `I2C_CMD_NOP;
                                                end
                                                end
 
 
                        endcase
                        endcase
                end
                end
endmodule
endmodule
 
 
 
 
 
 

powered by: WebSVN 2.1.0

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