//======================================================================
//
// 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,
output wire [6: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 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 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(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
//======================================================================