aboutsummaryrefslogblamecommitdiff
path: root/src/rtl/i2c.v
blob: 112ad7054a1b7f53f9cc752b61efc2c64f00416f (plain) (tree)


























































































































































































































                                                                        
//======================================================================
//
// i2c.v
// ------
// Top level wrapper for the i2c core.
//
// A simple I2C interface.
//
//
// Author: Joachim Strombergson
// Copyright (c) 2014, SUNET
// 
// Redistribution and use in source and binary forms, with or 
// without modification, are permitted provided that the following 
// conditions are met: 
// 
// 1. Redistributions of source code must retain the above copyright 
//    notice, this list of conditions and the following disclaimer. 
// 
// 2. Redistributions in binary form must reproduce the above copyright 
//    notice, this list of conditions and the following disclaimer in 
//    the documentation and/or other materials provided with the 
//    distribution. 
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
// COPYRIGHT OWNER 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.
//
//======================================================================

module i2c(
            input wire 		 clk,
            input wire 		 reset_n,

            // External interface.
	    input wire 		 SCL,
	    input wire 		 SDA,
	    output wire 	 SDA_pd,
	    input wire [7:0] 	 i2c_device_addr,

            // Internal receive interface.
            output wire 	 rxd_syn,
            output [7 : 0] 	 rxd_data,
            input wire 		 rxd_ack,

            // Internal transmit interface.
            input wire 		 txd_syn,
            input wire [7 : 0] 	 txd_data,
            output wire 	 txd_ack,
            
            // API interface.
            input wire 		 cs,
            input wire 		 we,
            input wire [7 : 0] 	 address,
            input wire [31 : 0]  write_data,
            output wire [31 : 0] read_data,
            output wire 	 error,

            // Debug output.
            output wire [7 : 0]  debug
           );

  
  //----------------------------------------------------------------
  // Internal constant and parameter definitions.
  //----------------------------------------------------------------
  // API addresses.
  parameter ADDR_CORE_NAME0   = 8'h00;
  parameter ADDR_CORE_NAME1   = 8'h01;
  parameter ADDR_CORE_TYPE    = 8'h02;
  parameter ADDR_CORE_VERSION = 8'h03;

  // Core ID constants.
  parameter CORE_NAME0   = 32'h69326320;  // "i2c "
  parameter CORE_NAME1   = 32'h20202020;  // "    "
  parameter CORE_TYPE    = 32'h20202031;  // "   1"
  parameter CORE_VERSION = 32'h302e3031;  // "0.01"

  //----------------------------------------------------------------
  // Wires.
  //----------------------------------------------------------------

  wire 	        core_SCL;
  wire 	        core_SDA;
  wire 		core_SDA_pd;
  wire [7:0] 	core_i2c_device_addr;

  wire          core_rxd_syn;
  wire [7 : 0]  core_rxd_data;
  wire          core_rxd_ack;

  wire          core_txd_syn;
  wire [7 : 0]  core_txd_data;
  wire          core_txd_ack;

  reg [31 : 0]  tmp_read_data;
  reg           tmp_error;

  
  //----------------------------------------------------------------
  // Concurrent connectivity for ports etc.
  //----------------------------------------------------------------
  assign core_SCL      = SCL;
  assign core_SDA      = SDA;
  assign SDA_pd        = core_SDA_pd;
  assign core_i2c_device_addr = i2c_device_addr;

  assign rxd_syn       = core_rxd_syn;
  assign rxd_data      = core_rxd_data;
  assign core_rxd_ack  = rxd_ack;
  
  assign core_txd_syn  = txd_syn;
  assign core_txd_data = txd_data;
  assign txd_ack       = core_txd_ack;
  
  assign read_data     = tmp_read_data;
  assign error         = tmp_error;

  assign debug         = core_rxd_data;
  

  //----------------------------------------------------------------
  // core
  //
  // Instantiation of the i2c core.
  //----------------------------------------------------------------
  i2c_core core(
                 .clk(clk),
                 .reset(reset_n),

                 // External data interface
		.SCL(core_SCL),
		.SDA(core_SDA),
		.SDA_pd(core_SDA_pd),
		.i2c_device_addr(core_i2c_device_addr),

                 // Internal receive interface.
                 .rxd_syn(core_rxd_syn),
                 .rxd_data(core_rxd_data),
                 .rxd_ack(core_rxd_ack),
                 
                 // Internal transmit interface.
                 .txd_syn(core_txd_syn),
                 .txd_data(core_txd_data),
                 .txd_ack(core_txd_ack)
                );

  
  //----------------------------------------------------------------
  // api
  //
  // The core API that allows an internal host to control the
  // core functionality.
  //----------------------------------------------------------------
  always @*
    begin: api
      // Default assignments.
      tmp_read_data = 32'h00000000;
      tmp_error     = 0;
      
      if (cs)
        begin
          if (we)
            begin
              // Write operations.
              case (address)
                default:
                  begin
                    tmp_error = 1;
                  end
              endcase // case (address)
            end
          else
            begin
              // Read operations.
              case (address)
                ADDR_CORE_NAME0:
                  begin
                    tmp_read_data = CORE_NAME0;
                  end

                ADDR_CORE_NAME1:
                  begin
                    tmp_read_data = CORE_NAME1;
                  end

                ADDR_CORE_TYPE:
                  begin
                    tmp_read_data = CORE_TYPE;
                  end

                ADDR_CORE_VERSION:
                  begin
                    tmp_read_data = CORE_VERSION;
                  end
                
                default:
                  begin
                    tmp_error = 1;
                  end
              endcase // case (address)
            end
        end
    end
  
endmodule // i2c

//======================================================================
// EOF i2c.v
//======================================================================