Entity: i2c_fsm
- File: i2c_fsm.sv
Diagram
Description
Copyright lowRISC contributors. Licensed under the Apache License, Version 2.0, see LICENSE for details. SPDX-License-Identifier: Apache-2.0
Description: I2C finite state machine
Ports
| Port name | Direction | Type | Description |
|---|---|---|---|
| clk_i | input | clock | |
| rst_ni | input | active low reset | |
| scl_i | input | serial clock input from i2c bus | |
| scl_o | output | serial clock output to i2c bus | |
| sda_i | input | serial data input from i2c bus | |
| sda_o | output | serial data output to i2c bus | |
| host_enable_i | input | enable host functionality | |
| target_enable_i | input | enable target functionality | |
| fmt_fifo_rvalid_i | input | indicates there is valid data in fmt_fifo | |
| fmt_fifo_wvalid_i | input | indicates data is being put into fmt_fifo | |
| fmt_fifo_depth_i | input | [6:0] | fmt_fifo_depth |
| fmt_fifo_rready_o | output | populates fmt_fifo | |
| fmt_byte_i | input | [7:0] | byte in fmt_fifo to be sent to target |
| fmt_flag_start_before_i | input | issue start before sending byte | |
| fmt_flag_stop_after_i | input | issue stop after sending byte | |
| fmt_flag_read_bytes_i | input | indicates byte is an number of reads | |
| fmt_flag_read_continue_i | input | host to send Ack to final byte read | |
| fmt_flag_nak_ok_i | input | no Ack is expected | |
| rx_fifo_wvalid_o | output | high if there is valid data in rx_fifo | |
| rx_fifo_wdata_o | output | [7:0] | byte in rx_fifo read from target |
| tx_fifo_rvalid_i | input | indicates there is valid data in tx_fifo | |
| tx_fifo_wvalid_i | input | indicates data is being put into tx_fifo | |
| tx_fifo_depth_i | input | [6:0] | tx_fifo_depth |
| tx_fifo_rready_o | output | populates tx_fifo | |
| tx_fifo_rdata_i | input | [7:0] | byte in tx_fifo to be sent to host |
| acq_fifo_wready_i | input | low if acq_fifo is full | |
| acq_fifo_wvalid_o | output | high if there is valid data in acq_fifo | |
| acq_fifo_wdata_o | output | [9:0] | byte and signal in acq_fifo read from target |
| host_idle_o | output | indicates the host is idle | |
| target_idle_o | output | indicates the target is idle | |
| thigh_i | input | [15:0] | high period of the SCL in clock units |
| tlow_i | input | [15:0] | low period of the SCL in clock units |
| t_r_i | input | [15:0] | rise time of both SDA and SCL in clock units |
| t_f_i | input | [15:0] | fall time of both SDA and SCL in clock units |
| thd_sta_i | input | [15:0] | hold time for (repeated) START in clock units |
| tsu_sta_i | input | [15:0] | setup time for repeated START in clock units |
| tsu_sto_i | input | [15:0] | setup time for STOP in clock units |
| tsu_dat_i | input | [15:0] | data setup time in clock units |
| thd_dat_i | input | [15:0] | data hold time in clock units |
| t_buf_i | input | [15:0] | bus free time between STOP and START in clock units |
| stretch_timeout_i | input | [30:0] | max time target may stretch the clock |
| timeout_enable_i | input | assert if target stretches clock past max | |
| host_timeout_i | input | [31:0] | max time target waits for host to pull clock down |
| stretch_en_addr_tx_i | input | target stretches clock after address matching for transmit | |
| stretch_en_addr_acq_i | input | target stretches clock after address matching for acquire | |
| stretch_stop_tx_i | input | stop stretching clock for transmit, resume normal operation | |
| stretch_stop_acq_i | input | stop stretching clock for acquire, resume normal operation | |
| target_address0_i | input | [6:0] | |
| target_mask0_i | input | [6:0] | |
| target_address1_i | input | [6:0] | |
| target_mask1_i | input | [6:0] | |
| stretch_stop_tx_clr_o | output | hardware to deassert stretch_stop_tx bit | |
| stretch_stop_acq_clr_o | output | hardware to deassert stretch_stop_acq bit | |
| event_nak_o | output | target didn't Ack when expected | |
| event_scl_interference_o | output | other device forcing SCL low | |
| event_sda_interference_o | output | other device forcing SDA low | |
| event_stretch_timeout_o | output | target stretches clock past max time | |
| event_sda_unstable_o | output | SDA is not constant during SCL pulse | |
| event_trans_complete_o | output | Transaction is complete | |
| event_tx_empty_o | output | tx_fifo is empty but data is needed | |
| event_tx_nonempty_o | output | tx_fifo is nonempty after stop | |
| event_ack_stop_o | output | target received stop after ack | |
| event_host_timeout_o | output | host ceased sending SCL pulses during ongoing transactn |
Signals
| Name | Type | Description |
|---|---|---|
| tcount_q | logic [19:0] | current counter for setting delays |
| tcount_d | logic [19:0] | next counter for setting delays |
| load_tcount | logic | indicates counter must be loaded |
| stretch | logic [30:0] | counter for clock being stretched by target |
| bit_index | logic [2:0] | bit being transmitted to or read from the bus |
| bit_decr | logic | indicates bit_index must be decremented by 1 |
| bit_clr | logic | indicates bit_index must be reset to 7 |
| byte_num | logic [8:0] | number of bytes to read |
| byte_index | logic [8:0] | byte being read from the bus |
| byte_decr | logic | indicates byte_index must be decremented by 1 |
| byte_clr | logic | indicates byte_index must be reset to byte_num |
| scl_temp | logic | scl internal |
| sda_temp | logic | data internal |
| scl_i_q | logic | scl_i delayed by one clock |
| sda_i_q | logic | sda_i delayed by one clock |
| read_byte | logic [7:0] | register for reads from target |
| read_byte_clr | logic | clear read_byte contents |
| shift_data_en | logic | indicates data must be shifted in from the bus |
| no_stop | logic | indicates no stop has been issued before start |
| log_start | logic | indicates start is been issued |
| log_stop | logic | indicates stop is been issued |
| restart | logic | indicates repeated start state is entered into |
| start_det | logic | indicates start or repeated start is detected on the bus |
| stop_det | logic | indicates stop is detected on the bus |
| address0_match | logic | indicates target's address0 matches the one sent by host |
| address1_match | logic | indicates target's address1 matches the one sent by host |
| address_match | logic | indicates one of target's addresses matches the one sent by host |
| input_byte | logic [7:0] | register for reads from host |
| input_byte_clr | logic | clear input_byte contents |
| scl_high_cnt | logic [31:0] | counter for continuously released scl_i |
| addr_stop_tx | logic | indicates stretch_stop_tx and stretch_en_addr_tx are asserted |
| addr_stop_acq | logic | indicates stretch_stop_acq and stretch_en_addr_acq are asserted |
| stretch_stop_tx_clr | logic | |
| stretch_stop_acq_clr | logic | |
| bit_idx | logic [3:0] | bit index including ack/nack |
| bit_ack | logic | indicates ACK bit been sent or received |
| rw_bit | logic | indicates host wants to read (1) or write (0) |
| host_ack | logic | indicates host acknowledged transmitted byte |
| tcount_sel | tcount_sel_e | |
| state_q | state_e | |
| state_d | state_e |
Types
| Name | Type | Description |
|---|---|---|
| tcount_sel_e | enum logic [3:0] { tSetupStart, tHoldStart, tClockLow, tSetupBit, tClockPulse, tHoldBit, tClockStart, tClockStop, tSetupStop, tHoldStop, tNoDelay } |
Clock counter implementation |
| state_e | enum logic [5:0] { Idle, PopFmtFifo, SetupStart, HoldStart, SetupStop, HoldStop, ClockLow, SetupBit, ClockPulse, HoldBit, ClockLowAck, SetupDevAck, ClockPulseAck, HoldDevAck, ReadClockLow, ReadSetupBit, ReadClockPulse, ReadHoldBit, HostClockLowAck, HostSetupBitAck, HostClockPulseAck, HostHoldBitAck, Active, ClockStart, ClockStop, AcquireStart, AddrRead, AddrAckWait, AddrAckSetup, AddrAckPulse, AddrAckHold, TransmitWait, TransmitSetup, TransmitPulse, TransmitHold, TransmitAck, AcquireByte, AcquireAckWait, AcquireAckSetup, AcquireAckPulse, AcquireAckHold, PopTxFifo, AcquireSrP, StretchTxEmpty, StretchAcqFull, StretchAddrTransmit, StretchAddrAcquire } |
State definitions |
Processes
- counter_functions: ( )
Type: always_comb
- clk_counter: ( @ (posedge clk_i or negedge rst_ni) )
Type: always_ff
- clk_stretch: ( @ (posedge clk_i or negedge rst_ni) )
Type: always_ff
Description
Clock stretching detection
- bit_counter: ( @ (posedge clk_i or negedge rst_ni) )
Type: always_ff
Description
Bit index implementation
- read_register: ( @ (posedge clk_i or negedge rst_ni) )
Type: always_ff
Description
Deserializer for a byte read from the bus
- byte_number: ( )
Type: always_comb
Description
Number of bytes to read
- byte_counter: ( @ (posedge clk_i or negedge rst_ni) )
Type: always_ff
Description
Byte index implementation
- bus_prev: ( @ (posedge clk_i or negedge rst_ni) )
Type: always_ff
Description
SDA and SCL at the previous clock edge
- stop_state: ( @ (posedge clk_i or negedge rst_ni) )
Type: always_ff
Description
Stop issued before
- s_detect: ( @ (posedge clk_i or negedge rst_ni) )
Type: always_ff
Description
(Repeated) Start condition detection by target
- p_detect: ( @ (posedge clk_i or negedge rst_ni) )
Type: always_ff
Description
Stop condition detection by target
- tgt_bit_counter: ( @ (posedge clk_i or negedge rst_ni) )
Type: always_ff
Description
ack Increment counter on negative SCL edge
- scl_high_counter: ( @ (posedge clk_i or negedge rst_ni) )
Type: always_ff
Description
Counter for continuously released SCL state
- tgt_input_register: ( @ (posedge clk_i or negedge rst_ni) )
Type: always_ff
Description
Shift data in on positive SCL edge
- host_ack_register: ( @ (posedge clk_i or negedge rst_ni) )
Type: always_ff
Description
Detection by the target of ACK bit send by the host
- stretch_addr_sp_tx: ( @ (posedge clk_i or negedge rst_ni) )
Type: always_ff
Description
Deasserting stretch_stop_tx bit after the first target address match for transmit
- stretch_addr_sp_acq: ( @ (posedge clk_i or negedge rst_ni) )
Type: always_ff
Description
Deasserting stretch_stop_acq bit after the first target address match for acquire
- state_outputs: ( )
Type: always_comb
Description
Outputs for each state
- state_functions: ( )
Type: always_comb
Description
Conditional state transition
- state_transition: ( @ (posedge clk_i or negedge rst_ni) )
Type: always_ff
Description
Synchronous state transition