I3C Controller Host Interface#

s_axis_axi_aclks_axi_aresetnclkoffload_triggersdiooffload_sdicmdprmapreset_nirqi3c_controller_host_interface

The I3C Controller Host Interface peripheral allows asynchronous interrupt-driven memory-mapped access to a I3C Controller Control Interface. This is typically used in combination with a software program to dynamically generate I3C transactions.

The peripheral also has support for providing memory-mapped access to one or more Offload Interface cores and change its content dynamically at runtime.

Files#

Name

Description

library/i3c_controller/i3c_controller_host_interface/i3c_controller_host_interface.v

Verilog source for the peripheral.

library/i3c_controller/i3c_controller_host_interface/i3c_controller_host_interface_ip.tcl

TCL script to generate the Vivado IP-integrator project for the peripheral.

library/i3c_controller/i3c_controller_host_interface/i3c_controller_host_interface_hw.tcl

TCL script to generate the Quartus IP-integrator project for the peripheral.

Configuration Parameters#

Name

Description

Default Value

Choices/Range

ID

Core ID.

0

From 0 to 255.

ASYNC_CLK

Asynchronous core clock.

False

OFFLOAD

Offload engine.

False

Signal and Interface Pins#

Physical Port

Logical Port

Direction

Dependency

s_axi_awaddr AWADDR

in [15:0]

s_axi_awprot AWPROT

in [2:0]

s_axi_awvalid AWVALID

in

s_axi_awready AWREADY

out

s_axi_wdata WDATA

in [31:0]

s_axi_wstrb WSTRB

in [3:0]

s_axi_wvalid WVALID

in

s_axi_wready WREADY

out

s_axi_bresp BRESP

out [1:0]

s_axi_bvalid BVALID

out

s_axi_bready BREADY

in

s_axi_araddr ARADDR

in [15:0]

s_axi_arprot ARPROT

in [2:0]

s_axi_arvalid ARVALID

in

s_axi_arready ARREADY

out

s_axi_rdata RDATA

out [31:0]

s_axi_rresp RRESP

out [1:0]

s_axi_rvalid RVALID

out

s_axi_rready RREADY

in

Physical Port

Logical Port

Direction

Dependency

s_axi_aclk CLK

in

Physical Port

Logical Port

Direction

Dependency

s_axi_aresetn RST

in

Physical Port

Logical Port

Direction

Dependency

sdo_ready sdo_ready

in

sdo_valid sdo_valid

out

sdo sdo

out [7:0]

sdi_ready sdi_ready

out

sdi_valid sdi_valid

in

sdi_last sdi_last

in

sdi sdi

in [7:0]

ibi_ready ibi_ready

out

ibi_valid ibi_valid

in

ibi ibi

in [14:0]

Physical Port

Logical Port

Direction

Dependency

offload_sdi_ready TREADY

in

OFFLOAD = 1
offload_sdi_valid TVALID

out

OFFLOAD = 1
offload_sdi TDATA

out [31:0]

OFFLOAD = 1

Physical Port

Logical Port

Direction

Dependency

cmdp_valid cmdp_valid

out

cmdp_ready cmdp_ready

in

cmdp cmdp

out [30:0]

cmdp_error cmdp_error

in [2:0]

cmdp_nop cmdp_nop

in

cmdp_daa_trigger cmdp_daa_trigger

in

Physical Port

Logical Port

Direction

Dependency

rmap_ibi_config rmap_ibi_config

out [1:0]

rmap_pp_sg rmap_pp_sg

out [1:0]

rmap_dev_char_addr rmap_dev_char_addr

in [6:0]

rmap_dev_char_data rmap_dev_char_data

out [3:0]

Physical Port

Direction

Dependency

Description

clk

in

ASYNC_CLK = 1

Buses sdio, offload_sdi, cmdp, rmap are synchronous to this clock domain.

reset_n

out

Buses sdio, offload_sdi, cmdp, rmap are synchronous to this reset signal.

irq

out

Level-High Interrupt. Interrupt output of the module. Is asserted when at least one of the modules interrupt is pending and unmasked.

offload_trigger

in

OFFLOAD = 1

On offload operation, assert to start a burst.

Register Map#

DWORD

BYTE

Reg Name

Description

BITS

Field Name

Type

Default Value

Description

0x0 0x0 VERSION

Version of the peripheral. Follows semantic versioning. Current version 0.01.00

[31:16] VERSION_MAJOR RO 0x0000

[15:8] VERSION_MINOR RO 0x01

[7:0] VERSION_PATCH RO 0x00

0x1 0x4 DEVICE_ID

[31:0] DEVICE_ID RO

‘’ID’’

Value of the ID configuration parameter.

0x2 0x8 SCRATCH

[31:0] SCRATCH RW 0x00000000

Scratch register useful for debug.

0x10 0x40 ENABLE

[0:0] ENABLE RW 0x1

Enable register. If the enable bit is set to 1 the internal state of the peripheral is reset. For proper operation, the bit needs to be set to 0.

0x20 0x80 IRQ_MASK

[7:7] DAA_PENDING RW 0x0

If set to 0 the DAA_PENDING interrupt is masked.

[6:6] IBI_PENDING RW 0x0

If set to 0 the IBI_PENDING interrupt is masked.

[5:5] CMDR_PENDING RW 0x0

If set to 0 the CMDR_PENDING interrupt is masked.

[4:4] IBI_ALMOST_FULL RW 0x0

If set to 0 the IBI_ALMOST_FULL interrupt is masked.

[3:3] SDI_ALMOST_FULL RW 0x0

If set to 0 the SDI_ALMOST_FULL interrupt is masked.

[2:2] SDO_ALMOST_EMPTY RW 0x0

If set to 0 the SDO_ALMOST_EMPTY interrupt is masked.

[1:1] CMDR_ALMOST_FULL RW 0x0

If set to 0 the CMDR_ALMOST_FULL interrupt is masked.

[0:0] CMD_ALMOST_EMPTY RW 0x0

If set to 0 the CMD_ALMOST_EMPTY interrupt is masked.

0x21 0x84 IRQ_PENDING

[31:0] IRQ_PENDING RW 0x00000000

Pending IRQs with mask. Write 1 at the CMDR_PENDING bit to clear it. For CMDR_PENDING and IBI_PENDING, will be cleared if the FIFOs are also empty. For DAA_PENDING, will be cleared if the SDO FIFO is not empty, that means, got dynamic address in the pipeline.

0x22 0x88 IRQ_SOURCE

[31:0] IRQ_SOURCE RO 0x00000000

Pending IRQs without mask.

0x30 0xc0 CMD_FIFO_ROOM

[31:0] CMD_FIFO_ROOM RO 0xXXXXXXXX

Number of free entries in the CMD FIFO.

0x31 0xc4 CMDR_FIFO_LEVEL

[31:0] CMDR_FIFO_LEVEL RO 0x00000000

Number of valid entries in the CMDR FIFO.

0x32 0xc8 SDO_FIFO_ROOM

[31:0] SDO_FIFO_ROOM RO 0xXXXXXXXX

Number of free entries in the SDO FIFO.

0x33 0xcc SDI_FIFO_LEVEL

[31:0] SDI_FIFO_LEVEL RO 0x00000000

Number of valid entries in the serial-data-in FIFO.

0x34 0xd0 IBI_FIFO_LEVEL

[31:0] IBI_FIFO_LEVEL RO 0x00000000

Number of valid entries in the in-bus-interrupt FIFO.

0x35 0xd4 CMD_FIFO

Command FIFO register. Writing to this register inserts an entry into the CMD FIFO. Writing to this register when the CMD FIFO is full has no effect and the written entry is discarded. Reading from this register always returns 0x00000000. The Software is responsive for a valid sequence of commands. If the peripheral does not ACK when required during a command, the procedure exits and the next command in the FIFO is interpreted. See Instruction Set Specification for the structure of the command.

[22:22] CMD_IS_CCC WO 0xX

Indicate if it is a CCC transfer (1) or not (0).

[21:21] CMD_BCAST_HEADER WO 0xX

Include broadcast header in private transfer (1) or not (0).

[20:20] CMD_SR WO 0xX

Repeated start flag, yield a Sr (1) or P (0) at the end of the transfer.

[19:8] CMD_BUFFER_LENGHT WO 0xXXX

Unsigned 12-bits payload length, direction depends on RNW value.

[7:1] CMD_DA WO 0xXX

7-bit device address (don’t care in broadcast mode).

[0:0] CMD_RNW WO 0xX

If should retrieve data from device (1) or not (0).

0x36 0xd8 CMDR_FIFO

CMDR FIFO register. Reading from this register removes the first entry from the CMDR FIFO. Reading this register when the CMDR FIFO is empty will return undefined data. Writing to it has no effect.

[23:0] CMDR_FIFO_ERROR RO 0x??

If an error occurred during the transfer.

[19:8] CMDR_FIFO_BUFFER_LENGTH RO 0x??

Unsigned 12-bits transferred payload length.

[7:0] CMDR_FIFO_SYNC RO 0x??

Command synchronization.

0x37 0xdc SDO_FIFO

SDO FIFO register. Writing to this register inserts an entry into the SDO FIFO. Writing to this register when the SDO FIFO is full has no effect and the written entry is discarded. Reading from this register always returns 0x00000000.

[31:24] SDO_FIFO_BYTE_3 RO 0xXX

[23:16] SDO_FIFO_BYTE_2 RO 0xXX

[15:8] SDO_FIFO_BYTE_1 RO 0xXX

[7:0] SDO_FIFO_BYTE_0 RO 0xXX

0x38 0xe0 SDI_FIFO

SDI FIFO register. Reading from this register removes the first entry from the SDI FIFO. Reading this register when the SDI FIFO is empty will return undefined data. Writing to it has no effect.

[31:0] SDI_FIFO RO 0xXXXXXXXX

0x39 0xe4 IBI_FIFO

IBI FIFO register. Reading from this register removes the first entry from the IBI FIFO. Reading this register when the IBI FIFO is empty will return undefined data. Writing to it has no effect.

[23:17] IBI_FIFO_DA RO 0xXX

IBI Dynamic address.

[15:8] IBI_FIFO_MDB RO 0xXX

IBI MDB, if the peripheral’s BCR[2] is Low, the field is ignored.

[7:0] IBI_FIFO_SYNC RO 0xXX

Synchronization number.

0x3a 0xe8 FIFO_STATUS

[2:2] SDI_EMPTY RO 0x1

If there is no element to be read in the SDI FIFO.

[1:1] IBI_EMPTY RO 0x1

If there is no element to be read in the IBI FIFO.

[0:0] CMDR_EMPTY RO 0x1

If there is no element to be read in the CMDR FIFO.

0x40 0x100 OPS

Configure the operation of the controller.

[7:7] OPS_STATUS_NOP RO 0x0

This bit is set to 1 when the bus is not executing any procedure. It is not idle bus condition since it set right after the Stop.

[6:5] OPS_SPEED_GRADE RW 0x0

Sets the speed grade in push-pull mode. Speed with 100MHz driver clock are: 00: 1.56MHz (default) 01: 3.12MHz 10: 6.25MHz 11: 12.50MHz

[4:1] OPS_OFFLOAD_LENGTH RW 0x0

Offload commands length.

[0:0] OPS_MODE RW 0x0

Set 0 to direct transfers, 1 to offload operation.

0x50 0x140 IBI_CONFIG

Configure the In-Band Interrupt (IBI) feature.

[1:1] IBI_CONFIG_LISTEN WO 0x0

Set this bit to listen for IBI requests (when a peripheral pulls SDA Low during bus available). After the IBI request is resolved, the controller returns to idle, since it is was not doing a cmd transfer. This should be set to 1 during normal operation, even if IBI_CONFIG_ENABLE is disabled.

[0:0] IBI_CONFIG_ENABLE WO 0x0

Set this bit to accept (ACK) IBI requests. If disabled, the controller will NACK IBI requests. If enabled, the controller will ACK the IBI request and receive the MDB. In both cases, the controller will proceed with the cmd transfer after resolving the IBI request, if any. Accepted IBIs fill the IBI_FIFO and generate an interrupt to the PS. IBI_CONFIG_LISTEN set to 1 and IBI_CONFIG_ENABLE set to 0 ensures that incoming IBIs are rejected as they come.

0x60 0x180 DEV_CHAR

Holds devices characteristics that are looked-up during execution. The content is written only by software. To read an address, write the address with DEV_CHAR_0_WEN 0 and then read.

[15:9] DEV_CHAR_ADDR RW 0x00

Device address to apply DEV_CHAR[3:0].

[8:8] DEV_CHAR_WEN WO 0xX

Enable write of the fields.

[3:3] DEV_CHAR_HAS_IBI_PAYLOAD RW 0x0

Indicates if the device sends at least MDB during the IBI. 0 does not, 1 does.

[2:2] DEV_CHAR_IS_IBI_CAPABLE RW 0x0

Indicates if the device can send IBI. 0 does not, 1 does.

[1:1] DEV_CHAR_IS_ATTACHED RW 0x0

Indicate if the device is attached.

0xb0 + 0x1*n 0x2c0 + 0x4*n OFFLOAD_CMD_n

Offload command memory. Write commands in sequence to these addresses and update the OFFLOAD_CMD_LENGTH register. Where n is from 0 to 15.

[31:0] OFFLOAD_CMD RW 0x00000000

The command to the I3C controller to execute.

0xc0 + 0x1*n 0x300 + 0x4*n OFFLOAD_SDO_n

Offload SDO memory. Dual access memory sector used to store the SDO payload for the offload execution. The SDO is read by the parsing the OFFLOAD_CMD commands. For example, if the first command on OFFLOAD_CMD is a write with length 3 and the next with length 2, 3 bytes from OFFLOAD_SDO_0 are sent, then 2 bytes from OFFLOAD_SDO_1 are sent. If OPS_OFFLOAD_LENGTH is 2, then the burst concludes and the “pointer” resets to OFFLOAD_SDO_0, otherwise, the execution continues until all commands are resolved, always bounded by OPS_OFFLOAD_LENGTH. Where n is from 0 to 15.

[31:24] OFFLOAD_SDO_BYTE_3 RO 0x00

[23:16] OFFLOAD_SDO_BYTE_2 RO 0x00

[15:8] OFFLOAD_SDO_BYTE_1 RO 0x00

[7:0] OFFLOAD_SDO_BYTE_0 RO 0x00

Access Type

Name

Description

RO

Read-only

Reads will return the current register value. Writes have no effect.

RW

Read-write

Reads will return the current register value. Writes will change the current register value.

WO

Write-only

Writes will change the current register value. Reads have no effect.

Interrupts#

The I3C Controller Host Interface peripheral has 8 internal interrupts, which are asserted when:

  • CMD_ALMOST_EMPTY: the level falls bellow the almost empty level.

  • CMDR_ALMOST_FULL: the level rises above the almost full level.

  • SDO_ALMOST_EMPTY: the level falls bellow the almost empty level.

  • SDI_ALMOST_FULL: the level rises above the almost full level.

  • IBI_ALMOST_FULL: the level rises above the almost full level.

  • CMDR_PENDING: a new Command Receipts event arrives.

  • IBI_PENDING: a new IBI event arrives.

  • DAA_PENDING: a peripheral requested an address during the DAA.

The peripheral has 1 external interrupt which is supposed to be connected to the upstream interrupt controller. The external interrupt is a logical OR-operation over the internal interrupts, meaning if at least one of the internal interrupts is asserted the external interrupt is asserted and only if all internal interrupts are de-asserted the external interrupt is de-asserted.

In addition, each interrupt has a mask bit which can be used to stop the propagation of the internal interrupt to the external interrupt. If an interrupt is masked it will count towards the external interrupt state as if it were not asserted.

The mask bits can be modified by writing to the IRQ_MASK register. The raw interrupt status can be read from the IRQ_SOURCE register and the combined state of the IRQ_MASK and raw interrupt state can be read from the IRQ_PENDING register:

IRQ_PENDING = IRQ_SOURCE & IRQ_MASK;
IRQ = |IRQ_PENDING;

FIFO Threshold Interrupts#

The FIFO threshold interrupts can be used by software for flow control of the streams, for example, listen to the FIFO level interrupts during data transfer to and from the FIFOs to avoid data loss.

The FIFO threshold interrupt is asserted when then FIFO level rises above the watermark and is automatically de-asserted when the level drops below the watermark.

Pending Interrupts#

The pending interrupt *_PENDING is asserted when a new sync event is received from a stream. For information about the CMDR see Command Receipts, and about the IBI see In-Band Interrupts.

An application that generated a pending interrupt instruction can use this interrupt to be notified when the instruction has been completed. For example, for a cmd instruction, it has completed when the CMDR_PENDING is received.

To de-assert the interrupt, the application needs to acknowledge its reception by writing 1 to the associated bit at the IRQ_PENDING register.