diff options
Diffstat (limited to 'src/rtl/i2c.v')
-rw-r--r-- | src/rtl/i2c.v | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/src/rtl/i2c.v b/src/rtl/i2c.v new file mode 100644 index 0000000..112ad70 --- /dev/null +++ b/src/rtl/i2c.v @@ -0,0 +1,219 @@ +//====================================================================== +// +// 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 +//====================================================================== |