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

Subversion Repositories i2c

[/] [i2c/] [trunk/] [bench/] [verilog/] [i2c_slave_model.v] - Diff between revs 10 and 19

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 10 Rev 19
Line 1... Line 1...
 
/////////////////////////////////////////////////////////////////////
 
////                                                             ////
 
////  WISHBONE rev.B2 compliant synthesizable I2C Slave model    ////
 
////                                                             ////
 
////                                                             ////
 
////  Authors: Richard Herveille (richard@asics.ws) www.asics.ws ////
 
////           John Sheahan (jrsheahan@optushome.com.au)         ////
 
////                                                             ////
 
////  Downloaded from: http://www.opencores.org/projects/i2c/    ////
 
////                                                             ////
 
/////////////////////////////////////////////////////////////////////
 
////                                                             ////
 
//// Copyright (C) 2001,2002 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_slave_model.v,v 1.2 2002-03-17 10:26:38 rherveille Exp $
//
//
// I2C slave model
//  $Date: 2002-03-17 10:26:38 $
 
//  $Revision: 1.2 $
 
//  $Author: rherveille $
 
//  $Locker:  $
 
//  $State: Exp $
//
//
 
// Change History:
 
//               $Log: not supported by cvs2svn $
 
 
`include "timescale.v"
`include "timescale.v"
 
 
module i2c_slave_model (scl, sda);
module i2c_slave_model (scl, sda);
 
 
Line 18... Line 63...
        inout sda;
        inout sda;
 
 
        //
        //
        // Variable declaration
        // Variable declaration
        //
        //
 
        wire debug = 1'b1;
 
 
        reg [7:0] mem [3:0]; // initiate memory
        reg [7:0] mem [3:0]; // initiate memory
        reg [7:0] mem_adr;   // memory address
        reg [7:0] mem_adr;   // memory address
        reg [7:0] mem_do;    // memory data output
        reg [7:0] mem_do;    // memory data output
 
 
        reg sta, d_sta;
        reg sta, d_sta;
Line 62... Line 109...
        always@(posedge scl)
        always@(posedge scl)
                sr <= #1 {sr[6:0],sda};
                sr <= #1 {sr[6:0],sda};
 
 
        //detect my_address
        //detect my_address
        assign my_adr = (sr[7:1] == I2C_ADR);
        assign my_adr = (sr[7:1] == I2C_ADR);
 
        // FIXME: This should not be a generic assign, but rather 
 
        // qualified on address transfer phase and probably reset by stop
 
 
        //generate bit-counter
        //generate bit-counter
        always@(posedge scl)
        always@(posedge scl)
                if (ld)
                if (ld)
                        bit_cnt <= #1 3'b111;
                        bit_cnt <= #1 3'b111;
Line 76... Line 125...
        assign acc_done = !(|bit_cnt);
        assign acc_done = !(|bit_cnt);
 
 
        //detect start condition
        //detect start condition
        always@(negedge sda)
        always@(negedge sda)
                if (scl)
                if (scl)
 
                begin
                        sta <= #1 1'b1;
                        sta <= #1 1'b1;
 
 
 
                        if (debug)
 
                                $display("DEBUG i2c_slave; start condition detected at %t", $time);
 
                end
                else
                else
                        sta <= #1 1'b0;
                        sta <= #1 1'b0;
 
 
        always@(posedge scl)
        always@(posedge scl)
                d_sta <= #1 sta;
                d_sta <= #1 sta;
 
 
        // detect stop condition
        // detect stop condition
        always@(posedge sda)
        always@(posedge sda)
                if (scl)
                if (scl)
 
                begin
                        sto <= #1 1'b1;
                        sto <= #1 1'b1;
 
 
 
                        if (debug)
 
                                $display("DEBUG i2c_slave; stop condition detected at %t", $time);
 
                end
                else
                else
                        sto <= #1 1'b0;
                        sto <= #1 1'b0;
 
 
        //generate i2c_reset signal
        //generate i2c_reset signal
        assign i2c_reset = sta || sto;
        assign i2c_reset = sta || sto;
Line 116... Line 175...
                                                                begin
                                                                begin
                                                                        state <= #1 slave_ack;
                                                                        state <= #1 slave_ack;
                                                                        rw <= #1 sr[0];
                                                                        rw <= #1 sr[0];
 
 
                                                                        sda_o <= #1 1'b0; // generate i2c_ack
                                                                        sda_o <= #1 1'b0; // generate i2c_ack
 
 
 
                                                        #2;
 
                                                        if (debug && rw)
 
                                                                $display("DEBUG i2c_slave; command byte received (read) at %t", $time);
 
                                                        if (debug && !rw)
 
                                                                $display("DEBUG i2c_slave; command byte received (write) at %t", $time);
 
 
 
                                                        if (rw)
 
                                                        begin
 
                                                                mem_do <= #1 mem[mem_adr];
 
 
 
                                                                if (debug)
 
                                                                begin
 
                                                                        #2 $display("DEBUG i2c_slave; data block read %x from address %x (1)", mem_do, mem_adr);
 
                                                                        #2 $display("DEBUG i2c_slave; memcheck [0]=%x, [1]=%x, [2]=%x", mem[4'h0], mem[4'h1], mem[4'h2]);
 
                                                                end
 
                                                        end
                                                                end
                                                                end
 
 
                                        slave_ack:
                                        slave_ack:
                                                begin
                                                begin
                                                        if (rw)
                                                        if (rw)
Line 138... Line 214...
                                                        begin
                                                        begin
                                                                state <= #1 gma_ack;
                                                                state <= #1 gma_ack;
                                                                mem_adr <= #1 sr; // store memory address
                                                                mem_adr <= #1 sr; // store memory address
 
 
                                                                sda_o <= #1 !(sr <= 15); // generate i2c_ack, for valid address
                                                                sda_o <= #1 !(sr <= 15); // generate i2c_ack, for valid address
 
 
 
                                                        if (debug)
 
                                                                #1 $display("DEBUG i2c_slave; address received. adr=%x, ack=%b", sr, sda_o);
                                                        end
                                                        end
 
 
                                        gma_ack:
                                        gma_ack:
                                                begin
                                                begin
                                                        state <= #1 data;
                                                        state <= #1 data;
Line 155... Line 234...
 
 
                                                        if (acc_done)
                                                        if (acc_done)
                                                                begin
                                                                begin
                                                                        state <= #1 data_ack;
                                                                        state <= #1 data_ack;
 
 
                                                                        mem_adr <= #1 mem_adr + 8'h1;
                                                                mem_adr <= #2 mem_adr + 8'h1;
 
 
 
                                                                if (rw)
 
                                                                begin
 
                                                                        #3 mem_do <= mem[mem_adr];
 
 
 
                                                                        if (debug)
 
                                                                                #5 $display("DEBUG i2c_slave; data block read %x from address %x (2)", mem_do, mem_adr);
 
                                                                end
 
 
                                                                        if (!rw)
                                                                        if (!rw)
 
                                                                begin
                                                                                mem[ mem_adr[3:0] ] <= #1 sr; // store data in memory
                                                                                mem[ mem_adr[3:0] ] <= #1 sr; // store data in memory
 
 
 
                                                                        if (debug)
 
                                                                                #2 $display("DEBUG i2c_slave; data block write %x to address %x", sr, mem_adr);
 
                                                                end
 
 
                                                                        sda_o <= #1 (rw && (mem_adr <= 15) ); // send ack on write, receive ack on read
                                                                        sda_o <= #1 (rw && (mem_adr <= 15) ); // send ack on write, receive ack on read
                                                                end
                                                                end
                                                end
                                                end
 
 
                                        data_ack:
                                        data_ack:
Line 191... Line 283...
                                endcase
                                endcase
                        end
                        end
 
 
        // read data from memory
        // read data from memory
        always@(posedge scl)
        always@(posedge scl)
                if (acc_done)
                if (!acc_done && rw)
                        mem_do <= #1 mem[mem_adr];
 
                else
 
                        mem_do <= #1 {mem_do[6:0], 1'b1}; // insert 1'b1 for host ack generation
                        mem_do <= #1 {mem_do[6:0], 1'b1}; // insert 1'b1 for host ack generation
 
 
        // generate tri-states
        // generate tri-states
        assign sda = sda_o ? 1'bz : 1'b0;
        assign sda = sda_o ? 1'bz : 1'b0;
 
 
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.