I2C Slave Controller
February 2015                                                                                                                    Reference Design RD1140
Introduction
I2C, or Inter-Integrated Circuit, is a popular serial interface protocol that is widely used in many electronic systems.
The I2C interface is a two-wire interface capable of half-duplex serial communication at moderate to high speeds of
up to a few megabits per second. The I2C system incorporates an addressing system to identify the multiple I2C
‘slaves’ on the I2C bus. An I2C system can have single or multiple masters. The two bidirectional lines of the I2C
system are SDA (Serial Data) and SCL (Serial Clock). An important electrical feature of the I2C lines are that they
are both made up of open drain ports and are pulled high by resistors.
This reference design illustrates the implementation of an I2C slave using an iCE40™ ultra low density FPGA. The
I2C slave implements functions as a port expander via an I2C bus.
Features
• 7/10-bit slave address support
• Supports repeated start operations
• Interrupt generation logic
• Standard and High-speed modes of operation
• Verilog RTL, test bench
Functional Description
Figure 1. Functional Block Diagram
                                                      i_sys_clk
                                                      i_rst
                                                      i_data
                                                      o_data
                                                      o_data_request
                                                      o_data_valid
                                                      i_s c lk_s tretch_en
                                                      o_i2cs _bus y
                                                      i _ s la v e _ a d d r
                                                      i_addr_10bit_en                                i_s da/ o_s da
                                                      i_hs _mode
                                                      i _ ti m e ou t_ en
                                                                                                     i _ s c l/ o _ s c l
                             Generic Host             i_timeout_val            I2C Slave
                                                                                                                            I2C Master
                           Register Interface         o_timeout_err
                                                                               Controller
                                                      i_ack_bus y                                   o_s c l_tri_en
                                                      o_tx_s tatus
                                                      o_rx_s tatus
                                                      i_init_intr_en
                                                                                                    o_s da_tri_en
                                                      i_rw_done_intr_en
                                                      i_timeout_intr_en
                                                      o_intr
                                                      o_init_done
                                                      o_rd_done
                                                      o_wr_done
                                                      o_init_intr
                                                      o_rw_intr
                                                      o_timeout_intr
© 2015 Lattice Semiconductor Corp. All Lattice trademarks, registered trademarks, patents, and disclaimers are as listed at www.latticesemi.com/legal. All other brand
or product names are trademarks or registered trademarks of their respective holders. The specifications and information herein are subject to change without notice.
www.latticesemi.com                                                               1                                                                  RD1140_1.1
                                                                                              I2C Slave Controller
Pin Descriptions
Table 1. Pin Descriptions
         Signal        Width   Type                                           Description
i_sys_clk               1      Input    System clock
i_rst                    1     Input    Active high asynchronous reset
i_data [7:0]             8     Input    Input data from register interface
o_data [7:0]             8     Output   Output data to register interface
o_data_request          1      Output   When high, requests input i_data. Can be used as read enable.
o_data_valid             1     Output   When high, indicates valid data on the o_data output bus.
i_sclk_stretch_en        1     Input    When high, SCL will be stretched by the slave during address or R/W phase.
                                        Goes high when slave is in a non-idle state (when in the address, data read and
o_i2cs_busy              1     Output
                                        write phases).
                                        10-bit slave address. If 7-bit addressing mode is enabled (i_addr_10bit_en is
i_slave_addr [9:0]      10     Input
                                        low) then the controller will take only slave_addr[6:0].
i_addr_10bit_en          1     Input    When high, 10-bit addressing mode is enabled.
i_hs_mode                      Input    When high, high-speed mode is enabled.
                                        When high, the timeout feature helps to come out from SCL unstable conditions.
i_timeout_en             1     Input
                                        This can be used to issue a software reset from the processor.
                                        When i_timeout_en is high, the slave checks whether SCL is still low for the
i_timeout_val [15:0]    16     Input
                                        value specified in i_timeout_val, then issues a reset condition to the slave FSM.
                                        When high, the slave will generate NACK to the master during the address or
i_ack_busy               1     Input
                                        data read phase.
o_tx_status              1     Output   Goes high when the slave Receive-Master Transmit mode is in progress.
o_rx_status              1     Output   Goes high when the slave Transmit-Master Receive mode is in progress.
                                        When high, an interrupt will be generated when the slave acknowledges the
i_init_intr_en          1      Input    address and R/W bits, indicating that the slave is entering the data read or write
                                        states.
                                        When high, an interrupt will be generated when there is a STOP condition or a
i_rw_done_intr_en       1      Input    change of direction (read-to-write or write-to read) in the data transaction using
                                        a repeated START.
                                        When high, an interrupt will be generated when a timeout reset condition is
i_timeout_intr_ en      1      Input
                                        encountered.
                                        Goes high when any interrupt generated by making i_init_intr_en,
o_intr                   1     Output
                                        i_rw_done_intr_en or i_timeout_intr_en high.
o_init_done              1     Output   Goes high when a slave receives address and R/W bits.
                                        Goes high when a slave completes reading of data in slave receive-master
o_rd_done                1     Output
                                        transmit mode.
                                        Goes high when a slave completes writing of data in slave Transmit-Master
o_wr_done                1     Output
                                        Receive mode.
o_timeout_err            1     Output   Goes high when a timeout reset condition is encountered.
i_scl                    1     Input    SCL input to the slave from the master
i_sda                    1     Input    SDA input to the slave from the master
o_sda                    1     Output   SDA output from the slave to the master
o_scl                    1     Output   SCL output form the slave to the master
o_scl_tri_en             1     Output   Tristate enable for SCL
o_sda_tri_en             1     Output   Tristate enable for SDA
o_rw_intr                1     Output   Interrupt signal for i_init_intr_en
o_timeout_intr           1     Output   Interrupt signal for i_timeout_intr_en
o_init_intr              1     Output   Interrupt signal for i_init_intr_en
                                                          2
                                                                                                                                    I2C Slave Controller
Design Module Description
The slave controller has a slave FSM (state machine) that continually monitors the state of the SCL and SDA lines
and generates the appropriate signals on the I2C bus. To begin a data transfer, the state machine looks for a start
command which is defined by a stable SCL high signal with a falling SDA line. On receipt of a start command, the
slave will latch the slave address and the R/W flag over the next eight consecutive bits. If the slave address on the
bus corresponds to the slave address, then the controller will generate an acknowledge signal and data transfer
may commence. If the slave address mismatches, then the controller reverts back to its idle state waiting for the
next start condition. Once the controller has been addressed correctly, the master may continue to send a
sequence of writes or reads as required.
Figure 2. Slave FSM
                                                                                                              start_detect_i=0 or
                                                                                                              stop_detect_i=0
                                           stop_detect_i=1
                                                                              BUS_IDLE
                                                                                       start_detect_i=0
                                                                     start_detect_i=1
                                                                                                                     (not_write_ack_i)=1
                                                                                   REPEAT_SR_DETECT_HS
                                           stop_detect_i=1                  (mastercode_
                                                                            not_ack_i)=1
                                                                                           start_detect_i=1
                                                           READ_ADDRESS_                              (addr_ack_1_i=1) &&                  WRITE_DATA
                                                               BYTE1
                                                                                                      (rw_mode_i=0) &&
                                                                                                      i_slave_10bit_addr=0
                                   (start_detect_i=1) &&                     (addr_ack_1_i=1) &&
                                   i_slave_10bit_addr=0                      (rw_mode_i=0) &&                                                            (count_i /=1)
                                                                             i_slave _10bit _addr=0
                                                    (addr_ack_1_i=1) &&
   (count_i=0) &&                                   (rw_mode_i=0) &&
   (stop_detect_i=0)
                                                    i_slave_10bit_addr=0                                                                           (count_i=0) &&
                                                                                                                                                   (stop_detect_i=0)
                                                                                    READ_ADDRESS_BYTE2
          (count_i/=1)     READ_DATA
                                                                                   (addr_ack_2_i=1) &&
                                                                                   i_slave_10bit_addr=1
                                                  start_detect_i=0                                                        (addr_ack_3_i=1) &&
                                                                                                                          (rw_mode_i=1) &&
                                                                                                                          (i_slave_10bit_addr=1)
                                                                     REPEAT_SR__DETECT_10BIT
                                                   (start_detect_i=1) &&
                         (addr_ack_3_i=1) &&       (i_slave_10bit_addr=1)        start_detect_i=1
                         (rw_mode_i=0) &&
                         (i_slave_10bit_addr=1)
                                                                      READ_ADDRESS_BYTE3
                                                                             3
                                                                                                                         I2C Slave Controller
Operation Sequence
7-Bit Addressing Mode
Single/Multiple Byte Write Operation
Figure 3 shows a Master Write operation in 7-bit addressing mode. The master generates the START bit and sends
the 7-bit slave address, followed by the eighth bit which is a data direction read/write bit (R/W). ‘0’ is sent for this
WRITE operation. The master sends the data followed by an acknowledgment (A) from the slave. The slave gener-
ates an acknowledgment for every byte of data from the master. The processor can either STOP the transaction by
sending a STOP bit, or the slave can respond with a NACK (A') so that the master stops the data write by generat-
ing a STOP condition to terminate the data transfer.
If i_ack_busy is high during the address phase, the slave will report a NACK to the master which will detach itself
from the data transaction. If it is high during the data read phase, the slave will report a NACK to the master, indi-
cating that it can no longer accept data and hence the master can issue a STOP condition.
Figure 3. Data Format for I2C Master Write to a 7-bit Address Slave
                            S     Slave Address          R/~W        A   Data      A     Data      A/~A      P
                                                                             Data transferred
                                                       ‘0’ (write)       (n bytes + acknowledge)
                                From Master to Slave        ~A – Not-Acknowledge       R/~W – Data Direction Bit
                                From Slave to Master        S – Start Bit              ‘0’ – Indicates Write Operation
                                                            P – Stop Bit               ‘1’ – Indicates Read Operation
                                                            A – Acknowledge
Single/Multi-Byte Read Operation
Figure 4 shows a Master Read operation in 7-bit addressing mode. The master generates a START bit, transmits a
7-bit slave address, followed by an eighth bit which is a data direction bit (R/W). A ‘1’ is sent for this READ opera-
tion. The slave acknowledges this by a positive acknowledgment (A). The slave transmits a byte of data, which the
master should acknowledge (A) for further data transactions to continue. The master generates a Not Acknowledge
(A) before generating a STOP condition to terminate the data transfer.
Figure 4. Data Format for I2C Master Read from a 7-Bit Address Slave
                                  S    Slave Address           R/~W      A    Data      A     Data     ~A    P
                                                                                 Data transferred
                                                            ‘1’ (read)       (n bytes + acknowledge)
Read/Write with Repeated Start
Figure 5 shows a Read and Write with Repeated Start. The master generates a START bit and sends a 7-bit slave
address plus the eighth R/W bit as ‘0’ for the write transaction. The slave acknowledges this request. The master
then sends one or more data byte followed by an acknowledgment from the slave. Instead of generating a STOP
condition, the master generates another START (i.e. ‘Repeated START’) that changes the data transfer mode from
Write to Read. The master again sends the slave address and sets the R/W bit to ‘1’ for the read transaction. The
master continues to read from the slave. It can switch back to Write mode by re-issuing a repeat start and the slave
address plus the R/W bit. Otherwise, the master generates a STOP condition to terminate the data transfer. The
first data transaction need not be a write; it can be a read as well.
                                                                         4
                                                                                                                                    I2C Slave Controller
Figure 5. Read and Write with Repeated Start
             S     Slave Address         R/~W         A       Data        A/~A   Sr    Slave Address       R/~W          A     Data       A/~A       P
                                                              Data transferred
                                      read or write              (n bytes +                              read or write
                                                               acknowledge)
                                                                                                                 Direction of transfer
                                                                            Repeated start                      may change at this point
10-Bit Addressing Mode
10-bit addressing allows the use of up to 1,024 additional addresses to prevent problems with the allocation of
slave addresses as the number of I2C devices rapidly expands. It does not change the format for addresses defined
in the I2C Bus Specification, using addresses reserved in the existing specification. Using 10-bit addressing allows
devices with 7-bit and/or 10-bit addresses to be connected to the same I2C bus. Using 10 bits for addressing
exploits the reserved combination ‘1111XXX’ for the first seven bits of the first byte following a START (S) or
repeated START (Sr) condition. 10-bit addressing mode is enabled when i_addr_10bit_en is made high.
Single/Multi-byte Write Operation
Figure 6 shows a Master Write operation in 10-bit addressing mode. The master generates the START condition
and sends the first seven bits of the first byte. The first seven bits are ‘11110XX’, of which the last two bits (XX) are
the two Most-Significant Bits (MSBs) of the 10-bit address, followed by a ‘0’ R/W eighth bit. Slaves supporting 10-
bit mode and matching the two MSB address bits respond with an acknowledgment (A1). The master sends the
second byte of the slave address and which is acknowledged (A2) by the matching slave. Hereafter, the write data
transfer is similar to conventional 7-bit addressing mode.
Figure 6. Master Write Operation for 10-Bit Addressing
                                  11110XX                 0
                               Slave Address                              Slave Address
                           S                          R/~W           A1                 A2        Data     A     Data         A/~A        P
                                First 7 Bits                               Second Byte
                                                      write
Single/Multi-byte Read Operation
Figure 7 shows the Master Read operation in 10-bit addressing mode. The master generates the START condition
and sends the first seven bits of the first byte. The first seven bits are ‘11110XX” of which the last two bits (XX) are
the two Most-Significant Bits (MSBs) of the 10-bit address, followed by a ‘0’ R/W eighth bit. Slaves supporting 10-
bit mode and matching the two MSB address bits respond with an acknowledgment (A1). The master sends the
second byte of the slave address which is acknowledged (A2) by the matching slave. The master generates a
‘Repeated START’ and sends the same first byte of the address followed by a ‘1’ on the R/W bit. The slave gener-
ates a positive acknowledgement (A3). Hereafter, the read data transaction is similar to conventional 7-bit address-
ing mode.
Figure 7. Master Read Operation for 10-Bit Addressing
                 11110XX          0                                                     11110XX           0
           Slave Address                         Slave Address       Slave Address
       S                        R/~W        A1                 A2 Sr                                     R/~W     A3         Data     A       Data   ~A   P
            First 7 Bits                          Second Byte         First 7 Bits
                                 write                                                                   read
High-Speed Mode
High-speed mode (Hs-mode) devices offer a quantum leap in I2C-bus transfer speeds. Hs-mode devices can trans-
fer information at bit rates of up to 3.4 Mbps, yet they remain fully downward compatible with Fast-mode Plus, Fast-
or Standard-mode (F/S) devices for bidirectional communication in a mixed-speed bus system. To achieve data
transfer rate of up to 3.4 Mbps, the I2C protocol provides High-speed mode. Serial data transfer format in Hs-mode
meets the standard-mode I2C Bus Specification. Hs-mode can only commence after the following conditions (all of
                                                                                  5
                                                                                                 I2C Slave Controller
which are in F/S-mode): START condition (S), followed by 8-bit master code (00001XXX) and a Not-acknowledge
bit (A) as shown in Figure 8.
The master then sends a ‘Repeated START’, followed by either a 7-bit or 10-bit address with a R/W bit. The slave
acknowledges this and the rest of the communication is similar to conventional 7-bit mode. The master switches
back to F/S mode after a STOP condition, otherwise it can continue in High-speed mode. High-speed mode also
supports interleave read and write using a repeat start, similar to conventional F/S modes.
The slave responds to high-speed mode master code and the address only when i_hs_mode is high. Otherwise,
the slave supports only F/S speed modes.
Figure 8. Data Transfer in High-Speed Mode
                       F/S Mode                        High-Speed Mode                         F/S Mode
                 S   Master Code     ~A Sr Slave Address   R/~W    A     Data   A/~A    P
                                                                                       Hs mode continues
                                                                                       Sr Slave Address
Clock Stretching
Clock stretching pauses a transaction by holding the SCL line LOW. The transaction cannot continue until the line
is released HIGH again. On the byte level, a device may be able to receive bytes of data at a fast rate, but needs
more time to store a received byte or prepare another byte to be transmitted. The slave can then hold the SCL line
LOW after reception and acknowledgment of a byte to force the master into a wait state until the slave is ready for
the next byte transfer in a handshake procedure.
When i_sclk_stretch_en is high, clock stretching feature is enabled. Processor interface logic can control clock
stretch during the address and data read/write phases by pulling this signal high.
Timeout Condition
The timeout condition is provided as an exit path for the slave if a bus error occurs, during unstable conditions or if
an I2C transmission is terminated. If the timeout enable i_time_out_en is high, then a counter will start counting the
SCL low period. When the counter reaches i_timeout_val and SCL is still low, a reset signal is triggered for the
FSM to switch to the IDLE state. If SCL goes high before the counter reaches the timeout value specified in
i_timeout_val, then the counter goes to the reset state without forcing the reset condition to FSM. Under such con-
ditions, FSM continues operating in normal read/write mode.
Interrupt Generation
There are three interrupt enables:
• i_init_intr_en – When high, an interrupt o_init_intr will be generated when a slave acknowledges address and
  R/W bits, indicating that the slave is entering the data read or write states.
• i_rw_done_intr_en – When high, an interrupt o_rw_intr will be generated when there is a STOP condition or
  there is a change of direction (read-to-write or write-to-read) in the data transaction using a Repeated Start.
• i_timeout_intr_en – When high, an interrupt o_timeout_intr will be generated when a timeout reset condition is
  encountered.
An output interrupt will become active when any of these three interrupts are generated.
Status Signals Generation
• o_rx_status – Goes high while slave Transmit-Master Receive mode is in progress.
• o_tx_status – Goes high while slave Receive-Master Transmit mode is in progress.
• o_i2cs_busy – Goes high when the slave is in the non-idle state (in address, data read and write phases)
                                                           6
                                                                                                        I2C Slave Controller
• o_init_done – Goes high when the slave receives address and R/W bits
• o_rd_done – Goes high when the slave completes reading of data in slave Receive-Master Transmit mode
• o_wr_done – Goes high when the slave completes writing of data in slave Transmit-Master Receive mode
• o_timeout_err – Goes high when a timeout reset condition is encountered
Simulation Waveforms
Figure 9. Simulation Waveforms
Implementation
This design is implemented in Verilog. When using this design in a different device, density, speed or grade, perfor-
mance and utilization may vary.
Table 2. Performance and Resource Utilization
                                                            Utilization                                              Architecture
 Device Family        Language        Synthesis Tool         (LUTs)            fMAX (MHz)             I/Os            Resources
                                             LSE                371               95.59                69                N/A
     iCE401             Verilog
                                           Syn Pro              367               81.43                69                N/A
1. Performance utilization characteristics are generated using iCE40LP1K-CM121 with iCEcube2™ 2014.08 design software.
References
• DS1040, iCE40 LP/HX Family Data Sheet
Technical Support Assistance
e-mail:   techsupport@latticesemi.com
Internet: www.latticesemi.com
                                                                 7
                                                                        I2C Slave Controller
Revision History
       Date        Version                            Change Summary
   February 2015     1.1     Updated Pin Descriptions section. Revised Table 1, Pin Descriptions.
                             Added signals.
                             Updated Simulation Waveforms section. Revised Figure 9, Simulation
                             Waveforms with the SCL clock not freely running.
                             Updated Implementation section. Revised Table 2, Performance and
                             Resource Utilization.
                             Updated References section.
                             Updated Technical Support Assistance information.
   October 2012     01.0     Initial release.