I3C 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 |
reset_n |
out |
Buses |
|
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 |
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 |
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 |
Indicate if it is a CCC transfer (1) or not (0). |
|||
[21:21] |
CMD_BCAST_HEADER |
WO |
Include broadcast header in private transfer (1) or not (0). |
|||
[20:20] |
CMD_SR |
WO |
Repeated start flag, yield a Sr (1) or P (0) at the end of the transfer. |
|||
[19:8] |
CMD_BUFFER_LENGHT |
WO |
Unsigned 12-bits payload length, direction depends on RNW value. |
|||
[7:1] |
CMD_DA |
WO |
7-bit device address (don’t care in broadcast mode). |
|||
[0:0] |
CMD_RNW |
WO |
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 |
If an error occurred during the transfer. |
|||
[19:8] |
CMDR_FIFO_BUFFER_LENGTH |
RO |
Unsigned 12-bits transferred payload length. |
|||
[7:0] |
CMDR_FIFO_SYNC |
RO |
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 |
||||
[23:16] |
SDO_FIFO_BYTE_2 |
RO |
||||
[15:8] |
SDO_FIFO_BYTE_1 |
RO |
||||
[7:0] |
SDO_FIFO_BYTE_0 |
RO |
||||
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 |
||||
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 |
IBI Dynamic address. |
|||
[15:8] |
IBI_FIFO_MDB |
RO |
IBI MDB, if the peripheral’s BCR[2] is Low, the field is ignored. |
|||
[7:0] |
IBI_FIFO_SYNC |
RO |
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 |
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.