Design verification¶
This chapter presents the available models and tools which are used for I3C verification. The core is verified with the Cocotb + unit tests and the UVM test suite.
This section contains testplans for the verification.
Definitions:
testplan- an organized collection of testpointstestpoint- an actionable item, which can be turned into a test:name- typically related to the tested featuredesc- detailed description; should contain description of the feature, configuration mode, stimuli, expected behavior.stage- can be used to assign testpoints to milestones.tests- names of implemented tests, which cover the testpoint. Relation test-testpoint can be many to many.tags- additional tags that can be used to group testpoints
Full overview of tests can be found in Testplan summary.
Testplans for individual blocks¶
axi_filtering¶
Testpoints¶
axi_filtering_disabled¶
Tests:
read_hci_version_csr_id_filter_off- read_pio_section_offset_filter_off- write_to_controller_device_addr_filter_off- write_should_not_affect_ro_csr_filter_off- sequence_csr_read_filter_off- sequence_csr_write_filter_off- collision_with_write_id_filter_off- collision_with_read_id_filter_off- write_read_burst_id_filter_off- write_burst_collision_with_read_id_filter_off- read_burst_collision_with_write_id_filter_off
Verifies CSR access is granted when the AXI filtering feature is disabled. Verifies transaction response and contents.
axi_filtering_priv¶
Tests:
read_hci_version_csr_id_filter_on_priv- read_pio_section_offset_filter_on_priv- write_to_controller_device_addr_filter_on_priv- write_should_not_affect_ro_csr_filter_on_priv- sequence_csr_read_filter_on_priv- sequence_csr_write_filter_on_priv- collision_with_write_id_filter_on_priv- collision_with_read_id_filter_on_priv- write_read_burst_id_filter_on_priv- write_burst_collision_with_read_id_filter_on_priv- read_burst_collision_with_write_id_filter_on_priv
Verifies CSR access is granted when the AXI filtering is enabled and the transaction has a privileged ID. Verifies transaction response and contents.
axi_filtering_non_priv¶
Tests:
read_hci_version_csr_id_filter_on_non_priv- read_pio_section_offset_filter_on_non_priv- write_to_controller_device_addr_filter_on_non_priv- write_should_not_affect_ro_csr_filter_on_non_priv- sequence_csr_read_filter_on_non_priv- sequence_csr_write_filter_on_non_priv- collision_with_write_id_filter_on_non_priv- collision_with_read_id_filter_on_non_priv- write_read_burst_id_filter_on_non_priv- write_burst_collision_with_read_id_filter_on_non_priv- read_burst_collision_with_write_id_filter_on_non_priv
Verifies CSR access is denied when the AXI filtering feature is enabled and the transaction ID doesn’t match any of the privileged IDs.
axi_filtering_mixed_priv¶
Tests:
collision_with_write_id_filter_on_mixed- collision_with_read_id_filter_on_mixed- collision_with_write_mixed_priv- collision_with_read_mixed_priv
Issues an ID-randomized colliding read and write transactions sequence. Verifies AXI CSR access response for each separate transaction. Ensures that access errors are raised only for unprivileged transactions.
bus_monitor¶
Testpoints¶
bus_monitor¶
Test: bus_monitor
Tests operation of the bus_monitor module along with its sub-modules. Performs a number of I3C transactions between a simulated controller and a simulated target. Counts start, repeated start and stop events reported by bus_monitor. Verifies that the counts match what’s expected.
bus_rx_flow¶
Testpoints¶
multiple_bit_reads¶
Test: multiple_bit_reads
Drives SCL line with a steady clock, issues multiple bit read requests, verifies that the module returns correct data sampled from the SDA line.
multiple_byte_reads¶
Test: multiple_byte_reads
Drives SCL line with a steady clock, issues multiple byte read requests, verifies that the module returns correct data sampled from the SDA line.
Bus timers top-level¶
Testpoints¶
get_status¶
Test: bus_timers
Tests the bus_timers module responsible for tracking bus free, idle and available states. Triggers the module and verifies if the signals corresponding to bus states get asserted after the required time period.
bus_tx¶
Testpoints¶
bit_tx_negedge¶
Test: bit_tx_negedge
Requests the bus_tx module to drive SDA right after SCL falling edge. Checks if the requested bit value is driven correctly.
bit_tx_pre_posedge¶
Test: bit_tx_pre_posedge
Requests the bus_tx module to drive SDA just before SCL rising edge. Checks if the requested bit value is driven correctly.
bit_tx_high_level¶
Test: bit_tx_high_level
Requests the bus_tx module to drive SDA just before SCL falling edge. Checks if the requested bit value is driven correctly.
bit_tx_low_level¶
Test: bit_tx_low_level
Requests the bus_tx module to drive SDA when SCL in in stable low state. Checks if the requested bit value is driven correctly.
byte_tx¶
Test: byte_tx
Drives controls of the bus_tx module in a sequence which sends a data byte plus T bit to the I3C bus. For each bit sent checks if SDA is driven correctly and bus timings are met.
bus_tx_flow¶
Testpoints¶
bit_tx_negedge¶
Test: bit_tx_negedge
Requests the bus_tx_flow module to drive SDA right after SCL falling edge. Checks if the requested bit value is driven correctly.
bit_tx_pre_posedge¶
Test: bit_tx_pre_posedge
Requests the bus_tx_flow module to drive SDA just before SCL rising edge. Checks if the requested bit value is driven correctly.
bit_tx_high_level¶
Test: bit_tx_high_level
Requests the bus_tx_flow module to drive SDA just before SCL falling edge. Checks if the requested bit value is driven correctly.
bit_tx_low_level¶
Test: bit_tx_low_level
Requests the bus_tx_flow module to drive SDA when SCL in in stable low state. Checks if the requested bit value is driven correctly.
byte_tx¶
Test: byte_tx
Requests the bus_tx_flow module to transmit a data byte along with T-bit. While the transmission is in progress samples SDA on rising edges of SCL. Once the transmission finishes compares sampled data with what was requested to be sent.
ccc¶
Testpoints¶
ccc¶
Test: ccc
Instructs the ccc module to begin servicing GETSTATUS CCC. Feeds data bytes and bits to the module via its bus_tx/bus_rx interfaces to mimic actual I3C transaction. Checks if data bytes received correspond to correct GETSTATUS CCC response.
flow_active¶
Testpoints¶
immediate_write¶
Test: immediate_write
Testbench: flow_active_wrapper (DUT) -> flow_active golden model
Intent: Verify Private Write with Immediate Data Transfer Command Descriptor (7.2.2.1 TCRI Spec) to an individual I3C Target Device with known static address
Stimulus:
create a 64b CMD descriptor as per Table 16 7.2.2.1 TCRI Spec. With:
CMD_ATTR = 0x5 // ImmediateDataTransfer in Direct Format
TID: random transaction ID
I2C = 0x0 // I3C device
CMD: random this field is disregarded
CP = 0x0 // CMD field is not valid
DEV_ADDRESS: random allowed I3C address
DTT: number of bytes to be transferred
MODE = 0x0 // standard I3C SDR Speed
RNW = 0x0 // Write transfer
WROC: random
TOC: random
DATA_BYTES: random data to be sent
split the 64b descriptor into 2 32b words (DWORD) and first write the lower DWORD into the COMMAND_PORT PIO reg followed by the upper DWORD.
Check: - correct start/restart fmt_flag is generated - first fmt_byte is DEV_ADDRESS - following DTT fmt_bytes are DATA_BYTES - correct stop fmt_flag is generated
csr_sw_access¶
Testpoints¶
read_hci_version_csr¶
Test: read_hci_version_csr
Reads the HCI version CSR and verifies its content.
read_pio_section_offset¶
Test: read_pio_section_offset
Reads the PIO_SECTION_OFFSET CSR and verifies its content.
write_to_controller_device_addr¶
Test: write_to_controller_device_addr
Writes to the CONTROLLER_DEVICE_ADDR CSR and verifies if the write was successful.
write_should_not_affect_ro_csr¶
Test: write_should_not_affect_ro_csr
Writes to the HC_CAPABILITIES CSR which is read-only for software. Verifies that the write did not succeed.
sequence_csr_read¶
Test: sequence_csr_read
Performs a sequence of CSR reads. Verifies that each one succeeds.
sequence_csr_write¶
Test: sequence_csr_write
Performs a sequence of CSR writes. Verifies that each one succeeds.
descriptor_rx¶
Testpoints¶
descriptor_rx¶
Test: descriptor_rx
Tests the descriptor_rx module responsible for generating TTI RX descriptors. The test sends N bytes to the module and verifies that it emits a valid descriptor with data length set to N.
descriptor_tx¶
Testpoints¶
descriptor_tx¶
Test: descriptor_tx
Tests the descriptor_tx module responsible for processing TTI TX descriptors and controlling TTI data flow during I3C private reads. Sends a descriptor to the module followed with the right amount of data. Verifies that the module accepted the descriptor and allowed the right amount of data bytes to pass through it.
drivers¶
Testpoints¶
test_drivers¶
Test: drivers
Tests the I3C PHY module. Loops through all possible states of SDA/SCL for OD and PP mode. Checks if driven data matches the bus state.
edge_detector¶
Testpoints¶
pretrigger_with_delay¶
Test: pretrigger_with_delay
Triggers the edge_detector module before an edge on a bus line, emits the edge and counts clock cycles it takes the detector to report the presence of the edge. Verifies that the count is equal to the programmed delay.
posttrigger_with_delay¶
Test: posttrigger_with_delay
Emits an edge on the bus, triggers the edge_detector module after the edge when the bus line is high. Counts clock cycles it takes the detector to report the edge event. The output detect signal is asserted only if the bus line signal is stable for the programmed delay time since the assertion of the trigger signal. Verifies that the number of counted cycles is equal the programmed delay.
trigger_with_delay¶
Test: trigger_with_delay
Triggers the edge detector and emits a rising edge on a bus line simultaneously. Counts clock cycles it takes the detector to report the presence of the edge. Verifies that the count is equal to the programmed delay.
pretrigger_no_delay¶
Test: pretrigger_no_delay
Triggers the edge_detector module before an edge on a bus line, emits the edge and counts clock cycles it takes the detector to report the presence of the edge. Verifies that the count is zero as the configured delay is also set to 0.
posttrigger_no_delay¶
Test: posttrigger_no_delay
Triggers the edge_detector module when a bus line is high which is after an edge. Counts clock cycles it takes the detector to report the presence of the edge. Verifies that the count is zero as the configured delay is also set to 0.
trigger_no_delay¶
Test: trigger_no_delay
Triggers the edge detector and emits a rising edge on a bus line simultaneously. Counts clock cycles it takes the detector to report the presence of the edge. Verifies that the count is zero as the configured delay is also set to 0.
falling_before_delay¶
Test: falling_before_delay
Triggers the edge detector and emits a rising edge on a bus line simultaneously. After half of the programmed delay passed the line falls back to low. Verifies that the edge was not reported in this scenario.
flow_standby_i3c¶
Testpoints¶
rx¶
Test: rx
Tests basic operation of the flow_standby_i3c module. The test instantiates two tasks serving as BFMs for RX and TX queues. Then it simulates bus start condition followed by data reception ended by bus stop condition.
hci_queues¶
Testpoints¶
clear_on_nonempty_resp_queue¶
Test: clear_on_nonempty_resp_queue
Writes to the HCI queue RESET_CONTROL CSR bit which causes HCI command response queue to be cleared. Then, polls the CSR until the bit gets cleared by the hardware. To check if the queue has been cleared puts a descriptor to the queue and reads it back. It should be the same descriptor.
clear_on_nonempty_cmd_queue¶
Test: clear_on_nonempty_cmd_queue
Puts a command descriptor to the HCI command queue. Writes to the RESET_CONTROL CSR to the bit responsible for clearing the queue, polls the CSR until the bit gets cleared by hardware. Verifies that the queue got cleared by pushing and retrieving another descriptor from the queue.
clear_on_nonempty_rx_queue¶
Test: clear_on_nonempty_rx_queue
Puts 10 data words to the HCI RX data queue. Writes to the RESET_CONTROL CSR to the bit responsible for clearing the queue, polls the CSR until the bit gets cleared by hardware. Puts and gets another data word from the queue to check if it was cleared.
clear_on_nonempty_tx_queue¶
Test: clear_on_nonempty_tx_queue
Puts 10 data words to the HCI TX data queue. Writes to the RESET_CONTROL CSR to the bit responsible for clearing the queue, polls the CSR until the bit gets cleared by hardware. Puts and gets another data word from the queue to check if it was cleared.
clear_on_nonempty_ibi_queue¶
Test: clear_on_nonempty_ibi_queue
Puts 10 data words to the HCI IBI queue. Writes to the RESET_CONTROL CSR to the bit responsible for clearing the queue, polls the CSR until the bit gets cleared by hardware. Puts and gets another data word from the queue to check if it was cleared.
cmd_capacity_status¶
Test: cmd_capacity_status
Resets the HCI command queue and verifies that it is empty afterwards.
resp_capacity_status¶
Test: resp_capacity_status
Resets the HCI response queue and verifies that it is empty afterwards.
rx_capacity_status¶
Test: rx_capacity_status
Resets the HCI RX queue and verifies that it is empty afterwards.
tx_capacity_status¶
Test: tx_capacity_status
Resets the HCI TX queue and verifies that it is empty afterwards.
ibi_capacity_status¶
Test: ibi_capacity_status
Resets the HCI IBI queue and verifies that it is empty afterwards.
cmd_setup_threshold¶
Test: cmd_setup_threshold
Writes the threshold to appropriate register for the HCI command queue (QUEUE_THLD_CTRL or DATA_BUFFER_THLD_CTRL). Verifies that an appropriate value has been written to the CSR. Verifies the threshold signal assumes the correct value.
resp_setup_threshold¶
Test: resp_setup_threshold
Writes the threshold to appropriate register for the HCI response queue (QUEUE_THLD_CTRL or DATA_BUFFER_THLD_CTRL). Verifies that an appropriate value has been written to the CSR. Verifies the threshold signal assumes the correct value.
rx_setup_threshold¶
Test: rx_setup_threshold
Writes the threshold to appropriate register for the HCI data RX queue (QUEUE_THLD_CTRL or DATA_BUFFER_THLD_CTRL). Verifies that an appropriate value has been written to the CSR. Verifies the threshold signal assumes the correct value.
tx_setup_threshold¶
Test: tx_setup_threshold
Writes the threshold to appropriate register for the HCI data TX queue (QUEUE_THLD_CTRL or DATA_BUFFER_THLD_CTRL). Verifies that an appropriate value has been written to the CSR. Verifies the threshold signal assumes the correct value.
ibi_setup_threshold¶
Test: ibi_setup_threshold
Writes the threshold to appropriate register for the HCI IBI queue (QUEUE_THLD_CTRL or DATA_BUFFER_THLD_CTRL). Verifies that an appropriate value has been written to the CSR. Verifies the threshold signal assumes the correct value.
resp_should_raise_thld_trig¶
Test: resp_should_raise_thld_trig
Sets up a ready threshold of the read queue and checks whether the trigger signal is properly asserted at different levels of the queue fill.
rx_should_raise_thld_trig¶
Test: rx_should_raise_thld_trig
Sets up a ready and start thresholds of the read queue and checks whether the trigger signals are properly asserted at different levels of the queue fill.
ibi_should_raise_thld_trig¶
Test: ibi_should_raise_thld_trig
Sets up a ready threshold of the read queue and checks whether the trigger signal is properly asserted at different levels of the queue fill.
cmd_should_raise_thld_trig¶
Test: cmd_should_raise_thld_trig
Sets up a ready threshold of the write queue and checks whether the trigger is properly asserted at different levels of the queue fill.
tx_should_raise_thld_trig¶
Test: tx_should_raise_thld_trig
Sets up a ready and start threshold of the write queue and checks whether the trigger is properly asserted at different levels of the queue fill.
i3c_bus_monitor¶
Testpoints¶
bus_monitor_hdr_exit¶
Test: bus_monitor_hdr_exit
Verifies that the i3c_bus_monitor module correctly detects HDR exit pattern. Sends the HDR exit pattern and verifies that the module does not react - initially the bus is in SDR mode. Instructs the module that the bus has entered HDR mode, issues the HDR exit pattern and counts the number of times the module reported HDR exit. Checks if it reported exactly one HDR exit event.
target_reset_detection¶
Test: target_reset_detection
Issues a target reset pattern to the I3C bus, verifies that the i3c_bus_monitor correctly report it detected.
pec¶
Testpoints¶
pec¶
Test: pec
Pushes random bytes through the recovery_pec module, compares its computed checksum with its correspondent computed in software.
tti_queues¶
Testpoints¶
tti_tx_capacity_status¶
Test: tti_tx_capacity_status
Resets the TTI TX queue and verifies that it is empty afterwards.
tti_tx_desc_capacity_status¶
Test: tti_tx_desc_capacity_status
Resets the TTI TX descriptor queue and verifies that it is empty afterwards.
tti_rx_capacity_status¶
Test: tti_rx_capacity_status
Resets the TTI RX queue and verifies that it is empty afterwards.
tti_rx_desc_capacity_status¶
Test: tti_rx_desc_capacity_status
Resets the TTI RX descriptor queue and verifies that it is empty afterwards.
tti_tx_setup_threshold¶
Test: tti_tx_setup_threshold
Writes the threshold to appropriate register for the TTI data TX queue (QUEUE_THLD_CTRL or DATA_BUFFER_THLD_CTRL). Verifies that an appropriate value has been written to the CSR. Verifies the threshold signal assumes the correct value.
tti_tx_desc_setup_threshold¶
Test: tti_tx_desc_setup_threshold
Writes the threshold to appropriate register for the TTI descriptor TX queue (QUEUE_THLD_CTRL or DATA_BUFFER_THLD_CTRL). Verifies that an appropriate value has been written to the CSR. Verifies the threshold signal assumes the correct value.
tti_rx_setup_threshold¶
Test: tti_rx_setup_threshold
Writes the threshold to appropriate register for the TTI data RX queue (QUEUE_THLD_CTRL or DATA_BUFFER_THLD_CTRL). Verifies that an appropriate value has been written to the CSR. Verifies the threshold signal assumes the correct value.
tti_rx_desc_setup_threshold¶
Test: tti_rx_desc_setup_threshold
Writes the threshold to appropriate register for the TTI descriptor RX queue (QUEUE_THLD_CTRL or DATA_BUFFER_THLD_CTRL). Verifies that an appropriate value has been written to the CSR. Verifies the threshold signal assumes the correct value.
tti_ibi_setup_threshold¶
Test: tti_ibi_setup_threshold
Writes the threshold to appropriate register for the TTI IBI queue (QUEUE_THLD_CTRL or DATA_BUFFER_THLD_CTRL). Verifies that an appropriate value has been written to the CSR. Verifies the threshold signal assumes the correct value.
tti_ibi_should_raise_thld_trig¶
Test: tti_ibi_should_raise_thld_trig
Sets up a ready threshold of the TTI queue and checks whether the trigger signal is properly asserted at different levels of the queue fill.
tti_rx_desc_should_raise_thld_trig¶
Test: tti_rx_desc_should_raise_thld_trig
Sets up a ready threshold of the read queue and checks whether the trigger signal is properly asserted at different levels of the queue fill.
rx_should_raise_thld_trig¶
Test: rx_should_raise_thld_trig
Sets up a ready and start thresholds of the read queue and checks whether the trigger signals are properly asserted at different levels of the queue fill.
tx_desc_should_raise_thld_trig¶
Test: tti_tx_desc_should_raise_thld_trig
Sets up a ready and start threshold of the write queue and checks whether the trigger is properly asserted at different levels of the queue fill.
tx_should_raise_thld_trig¶
Test: tx_should_raise_thld_trig
Sets up a ready and start threshold of the write queue and checks whether the trigger is properly asserted at different levels of the queue fill.
ibi_should_raise_thld_trig¶
Test: ibi_should_raise_thld_trig
Sets up a ready and start threshold of the write queue and checks whether the trigger is properly asserted at different levels of the queue fill.
tti_ibi_capacity_status¶
Test: tti_ibi_capacity_status
Resets the TTI TX IBI queue and verifies that it is empty afterwards.
width_converter_8toN¶
Testpoints¶
converter¶
Test: width_converter_8ton_converter
Pushes random byte stream to the converter module. After each byte waits at random. Simultaneously receives N-bit data words and generates pushback (deasserts ready) at random. Verifies if the output data matches the input.
flush¶
Test: width_converter_8ton_flush
Feeds M bytes to the module where M is in [1, 2, 3]. Asserts the sink_flush_i signal, receives the output word and checks if it matches the input data.
width_converter_Nto8¶
Testpoints¶
converter¶
Test: width_converter_nto8_converter
Pushes random N-bit word stream to the converter module. After each word waits at random. Simultaneously receives bytes and generates pushback (deasserts ready) at random. Verifies if the output data matches the input.
flush¶
Test: width_converter_nto8_flush
Feeds an N-bit word to the module. Receives M bytes where M is in [1, 2, 3] and asserts source_flush_i. Verifies that the module ceases to output data as expected.
Controller I3C flow¶
Testpoints¶
Typical I3C operation¶
Test: controller_typical_operation
Configure the bus using CCC to assign dynamic addresses
perform writes to multiple targets
read from multiple targets
service IBI
issue restart of a target
hot join a new target
service errors
multiple_interleaved_transaction_sequences¶
Test: multiple_interleaved_transaction_sequences
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify Chaining Private Writes and Private Reads with Immediate and Regular Data Transfer Command (7.2.2.1 / 7.2.2.2 TCRI Spec) to an individual I3C Target Device with known static address using Sr condition.
Stimulus:
create random amount of 64b CMD descriptors as per Table 16/18 7.2.2.1 / 7.2.2.2 TCRI Spec. With:
TOC: random we want to test repeated start
split the 64b descriptors into 2 32b words (DWORD) and first write the lower DWORD into the COMMAND_PORT PIO reg followed by the upper DWORD.
we want to test a random sequence of reads / writes chained together by either Sr or P.
For example: S->W->Sr->W->…->R->P->S->R->Sr->…->W->P
Check: Verify that:
data being sent via TX_DATA_PORT is equal to data on the target I3C_EC.TTI.RX_DATA_PORT CSR.
controller_flow_simple¶
Test: controller_flow_simple
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify simple I3C operation including SETDASA CCC to assign dynamic address, I3C private read and I3C private write.
Stimulus:
Issue a SETDASA CCC using an address assignment command descriptor with a random (valid) I3C dynamic address.
Generate random data (length: 1 < DATA_LENGTH < TX_QUEUE_DEPTH*4 bytes)
Write data using the dynamic address in an I3C private write.
Generate random data (length: 1 < DATA_LENGTH < TX_QUEUE_DEPTH*4 bytes)
Write data to the I3C target using the TTI_TX_DATA_PORT.
Read data using the dynamic address in an I3C private read.
Check:
SETDASA: the targets I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR CSR contains the dynamic address which was set.
I3C private write: data being sent via TX_DATA_PORT is equal to data on the target I3C_EC.TTI.RX_DATA_PORT CSR.
I3C private read: data read from controller RX_DATA_PORT matches data sent to TTI_TX_DATA_PORT
For all transactions: response descriptor data length matches data bytes specified in CMD desc, resp desc TID matches TID form CMD desc and resp error status is SUCCESS.
Controller Data over-/underflow handling¶
Testpoints¶
Controller Reading from empty IBI FIFO¶
Test: controller_empty_rx_desc_read
Perform read bus access to the empty IBI queue, verify that response comes back and it holds value of ?.
Controller Reading from empty RX data FIFO¶
Test: controller_empty_rx_data_read
Perform read bus access to the empty RX data queue, verify that response comes back and it holds value of ).
Controller Reading from empty resp FIFO¶
Test: controller_empty_indirect_fifo_read
Perform read bus access to the empty resp queue, verify that response comes back and it holds value of ?.
Controller Writing to full cmd FIFO¶
Test: controller_full_tx_desc_write
Perform multiple write bus accesses to the cmd queue, verify that all transactions have finished.
Controller Writing to full TX data FIFO¶
Test: controller_full_tx_data_write
Perform multiple write bus accesses to the TX data queue, verify that all transactions have finished.
Controller CCC generation¶
Testpoints¶
controller_ccc_enec_disec_bcast¶
Test: controller_ccc_enec_disec_bcast
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify 5.1.9.3.1 Enable/Disable Target Events Command (ENEC/DISEC) from I3C Basic Spec. Using Broadcast mode. The test first disables events from the target with the DISEC CCC and then enables them again with ENEC.
Stimulus:
randomly create a regular or immediate 64b CMD descriptor. With:
CMD_ATTR = 0x4 or 0x5// RegularDataTransfer or ImmediateDataTransfer in Direct Format
CMD: 0x1 / 0x0 // DISEC / ENEC BCAST
CP = 0x1 // CMD field is valid
DEV_ADDRESS: random allowed I3C address
DTT/DATA_LENGTH = 1 // One byte of Payload
RNW = 0x0 // Write transfer
WROC = random // randomly generate response descriptor
TOC = 0x1 // want to generate a stop signal after first transfer
DATA_BYTE1 = 0x0b // Enable/Disable all Target Events (See Table 18 & Table 19 I3C Basic Spec)
send CMD descriptor
generate a second CMD descriptor with CMD = 0x0 (ENEC).
Check:
Initially the I3C_EC.TTI.CONTROL.IBI_EN and I3C_EC.TTI.CONTROL.HJ_EN CSRs should be set to 1 and I3C_EC.TTI.CONTROL.CRR_EN should be set to 0.
After sending the first CCC (DISEC) all CSRs should be set to 0.
After sending the second CCC (ENEC) all CSRs should be set to 1.
controller_ccc_enec_disec_direct_one_target¶
Test: controller_ccc_enec_disec_direct_one_target
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify 5.1.9.3.1 Enable/Disable Target Events Command (ENEC/DISEC) from I3C Basic Spec. Using Direct mode. The test first disables events from the target with the DISEC CCC and then enables them again with ENEC.
Stimulus:
randomly create a regular or immediate 64b CMD descriptor. With:
CMD_ATTR = 0x4 or 0x5// RegularDataTransfer or ImmediateDataTransfer in Direct Format
CMD: 0x81 / 0x80 // DISEC / ENEC DIRECT
CP = 0x1 // CMD field is valid
DEV_ADDRESS = Target Address
DTT/DATA_LENGTH = 1 // One byte of Payload
RNW = 0x0 // Write transfer
WROC = random // randomly generate response descriptor
TOC = 0x1 // want to generate a stop signal after first transfer
DATA_BYTE1 = 0x0b // Enable/Disable all Target Events (See Table 18 & Table 19 I3C Basic Spec)
send CMD descriptor
generate a second CMD descriptor with CMD = 0x80 (ENEC).
Check:
Initially the I3C_EC.TTI.CONTROL.IBI_EN, I3C_EC.TTI.CONTROL.CRR_EN and I3C_EC.TTI.CONTROL.HJ_EN CSRs should all be set to one.
After sending the first CCC (DISEC) the CSRs should be set to 0.
After sending the second CCC (ENEC) the CSRs should again all be set to 1.
controller_ccc_enec_disec_direct_multiple_targets¶
Test: controller_ccc_enec_disec_direct_multiple_targets
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify 5.1.9.3.1 Enable/Disable Target Events Command (ENEC/DISEC) from I3C Basic Spec. Using Direct mode. The test first disables events from the targets with the DISEC CCC and then enables them again with ENEC. The goal is to see if the Direct Frame is correctly generated for multiple cmd descriptors where the CCC stays the same. (Figure 31 I3C Basic Spec)
Stimulus:
randomly create num_targets regular or immediate 64b CMD descriptor. With:
CMD_ATTR = 0x4 or 0x5// RegularDataTransfer or ImmediateDataTransfer in Direct Format
CMD: 0x81 / 0x80 // DISEC / ENEC DIRECT
CP = 0x1 // CMD field is valid
DEV_ADDRESS = Target Address (For now the target address is kept constant since we only have one target to test on the I3C Bus)
DTT/DATA_LENGTH = 1 // One byte of Payload
RNW = 0x0 // Write transfer
WROC = random // randomly generate response descriptor
TOC = 0x1 // want to generate a stop signal after first transfer
DATA_BYTE1 = 0x0b // Enable/Disable all Target Events (See Table 18 & Table 19 I3C Basic Spec)
send CMD descriptor
generate a second CMD descriptor with CMD = 0x80 (ENEC).
Check:
Initially the I3C_EC.TTI.CONTROL.IBI_EN, I3C_EC.TTI.CONTROL.CRR_EN and I3C_EC.TTI.CONTROL.HJ_EN CSRs should all be set to one.
After sending the first CCC (DISEC) the CSRs should be set to 0.
After sending the second CCC (ENEC) the CSRs should again all be set to 1.
controller_ccc_rstdaa¶
Test: controller_ccc_rstdaa
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify 5.1.9.3.3 Reset Dynamic Address Assignment (RSTDAA) from I3C Basic Spec. Using Broadcast mode. The test resets the dynamic addresses of the target and virtual target device.
Stimulus:
assign DYNAMIC_ADDR and VIRT_DYNAMIC_ADDR during boot by writing to the I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR and I3C_EC.STDBYCTRLMODE.STBY_CR_VIRT_DEVICE_ADDR.VIRT_DYNAMIC_ADDR CSRs
randomly create a regular or immediate 64b CMD descriptor. With:
CMD_ATTR = 0x4 or 0x5// RegularDataTransfer or ImmediateDataTransfer in Direct Format
CMD: 0x06 // RSTDAA BCAST
CP = 0x1 // CMD field is valid
DTT/DATA_LENGTH = 0 // No Payload
send CMD descriptor
Check:
Verify that I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR_VALID is 0x0 after RSTDAA
Verify that I3C_EC.STDBYCTRLMODE.STBY_CR_VIRT_DEVICE_ADDR.VIRT_DYNAMIC_ADDR_VALID is 0x0 after RSTDAA
controller_ccc_entdaa¶
Test: controller_ccc_entdaa
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify 5.1.4.2 Bus Initialization Sequence with Dynamic Address Assignment from I3C Basic Spec. Using ENTDAA CCC in Broadcast mode. The test sets the dynamic address of the i3c target as well as the dynamic address of the virtual target to predefined values in the DAT.
Stimulus:
Create a valid DYNAMIC_ADDR and VIRTUAL_DYNAMIC_ADDR to be assigned to the target by the controller.
Write DAT entries including the (VIRTUAL) DYNAMIC_ADDR
Generate ENTDAA CCC to enter the dynamic address assignment mode and assign the DYNAMIC_ADDR and VIRTUAL_DYNAMIC_ADDR respectively (simulates ENTDAA for multiple targets).
create a address assignment 64b CMD descriptor. With:
CMD_ATTR = 0x2 // Address Assignment Command
CMD: 0x07 // ENTDAA BCAST
DEV_INDEX: DAT Table Entry Containing the STATIC_ADDR and DYNAMIC_ADDR
send CMD descriptor
Check:
After sending the ENTDAA CCC the response descriptor returns SUCCESS
After sending the ENTDAA CCC verify that the I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR holds the dynamic addresses specified in the DAT.
Verify that the DCT entries (starting at the index specified in the TABLE_INDEX field of the DCT_SECTION_OFFSET register) contain the PID, BCR, DCR and dynamic address of the (Virtual) target.
controller_ccc_setaasa¶
Test: controller_ccc_setaasa
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify 5.1.9.3.23 Set All Addresses to Static Address (SETAASA) from I3C Basic Spec. Using Broadcast mode. The test sets the dynamic address of the i3c target to the static target address.
Stimulus:
randomly create a regular or immediate 64b CMD descriptor. With:
CMD_ATTR = 0x4 or 0x5// RegularDataTransfer or ImmediateDataTransfer in Direct Format
CMD: 0x29 // SETAASA BCAST
CP = 0x1 // CMD field is valid
DEV_ADDRESS: random allowed I3C address
DTT/DATA_LENGTH = 0 // No Payload
RNW = 0x0 // Write transfer
WROC = random // randomly generate response descriptor
TOC = 0x1 // want to generate a stop signal after first transfer
DATA_BYTE1 = 0x0 // is ignored
send CMD descriptor
Check:
Read the I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_ADDR.STATIC_ADDR CSR to get the target’s static address.
Read the I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR CSR to get the target’s dynamic address.
After sending the SETAASA CCC verify that the I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR holds the target’s static address.
controller_ccc_setdasa¶
Test: controller_ccc_setdasa_direct
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify 5.1.9.3.10 Set Dynamic Address from Static Address (SETDASA) from I3C Basic Spec. Using Direct mode. The test sets the dynamic address of the i3c target using the I2C static target address.
Stimulus:
Randomly generate a STATIC_ADDR and VIRTUAL_STATIC_ADDR and write them to the i3c target CSR.
Create a valid DYNAMIC_ADDR and VIRTUAL_DYNAMIC_ADDR to be assigned to the target by the controller.
Write DAT entries including the (VIRTUAL) STATIC_ADDR and (VIRTUAL) DYNAMIC_ADDR
Generate 2 SETDASA CCCs to assign the DYNAMIC_ADDR and VIRTUAL_DYNAMIC_ADDR using STATIC_ADDR and VIRTUAL_STATIC_ADDR respectively (simulates SETDASA for multiple targets).
create a address assignment 64b CMD descriptor. With:
CMD_ATTR = 0x2 // Address Assignment Command
CMD: 0x87 // SETDASA Direct
DEV_INDEX: DAT Table Entry Containing the STATIC_ADDR and DYNAMIC_ADDR
send CMD descriptor
Check:
Read the I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_ADDR.STATIC_ADDR CSR to get the target’s static address.
Read the I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR CSR to get the target’s dynamic address.
After sending the SETDASA CCC verify that the I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR holds the dynamic address that was sent.
controller_ccc_setnewda¶
Test: controller_ccc_setnewda
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify 5.1.9.3.11 Set New Dynamic Address (SETNEWDA) from I3C Basic Spec. Using Direct mode. The test sets a new dynamic address, using the old target dynamic address of the I3C target.
Stimulus:
Initialize the target and virtual target with valid dynamic addressses.
Create new valid DYNAMIC_ADDR and VIRTUAL_DYNAMIC_ADDR to be assigned to the target by the controller.
Generate 2 SETNEWDA CCCs using the old DYNAMIC_ADDR and old VIRTUAL_DYNAMIC_ADDR and the new DYNAMIC_ADDR and VIRT_DYNAMIC_ADDR as payload.
Check:
Read the I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR CSR to get the target’s dynamic address.
After sending the SETNEWDA CCC verify that the I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_ADDR.DYNAMIC_ADDR holds the new dynamic address that was sent.
controller_ccc_getpid¶
Test: controller_ccc_getpid
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify 5.1.9.3.12 Get Provisioned ID (GETPID) from I3C Basic Spec. Using Direct mode. The test reads the targets PID.
Stimulus:
Issue a GETPID CCC to the targets dynamic address.
Check:
Read the targets I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_CHAR.PID_HI and I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_PID_LO.PID_LO CSRs to get the full PID
Read the RX_PORT and verify that the data received by the controller matches the PID from the targets PID CSRs.
controller_ccc_getbcr¶
Test: controller_ccc_getbcr
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify 5.1.9.3.13 Get Bus Characteristics Register (GETBCR) from I3C Basic Spec. Using Direct mode. The test reads the targets BCR.
Stimulus:
Issue a GETBCR CCC to the targets dynamic address.
Check:
Read the targets I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_CHAR.BCR_VAR and I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_CHAR.BCR_FIXED CSRs to get the full BCR
Read the RX_PORT and verify that the data received by the controller matches the BCR from the targets BCR CSRs.
controller_ccc_getdcr¶
Test: controller_ccc_getdcr
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify 5.1.9.3.14 Get Device Characteristics Register (GETDCR) from I3C Basic Spec. Using Direct mode. The test reads the targets DCR.
Stimulus:
Issue a GETDCR CCC to the targets dynamic address.
Check:
Read the targets I3C_EC.STDBYCTRLMODE.STBY_CR_DEVICE_CHAR.DCR CSR to get the DCR
Read the RX_PORT and verify that the data received by the controller matches the DCR from the targets DCR CSR.
Controller-specific CSR access check¶
Testpoints¶
Test controller-specific CSR accesses¶
Tests:
Walks over all CSRs, write random value using AHB/AXI, reads it back, and compares with expected output.
Write to configuration register¶
Test: ec_stdby_cr_enable_init
Writes to the I3C_EC.StdbyCtrlMode.STBY_CR_CONTROL.STBY_CR_ENABLE_INIT register to enable controller mode or target mode. The DUT has 3 AXI ports for its 3 instantiations of the i3c core. Port 0 is for the expected target. Port 1 is for the actual controller and Port 2 is for the actual target. This test writes only to the above mentioned CSR for each of the ports. This will be used to configure the i3c cores in their operation mode. To verify the test reads the ports back and checks if it matches.
Configure Target and Controller¶
Test: configure_target_and_controller
Writes to the I3C_EC.StdbyCtrlMode.STBY_CR_CONTROL.STBY_CR_ENABLE_INIT register to enable controller mode or target mode. The DUT has 3 AXI ports for its 3 instantiations of the i3c core. Port 0 is for the expected target. Port 1 is for the actual controller and Port 2 is for the actual target. This test writes only to the above mentioned CSR for each of the ports. This will be used to configure the i3c cores in their operation mode. To verify the test reads the ports back and checks if it matches. Write 0’b10 to Port 0 and Port 2. Write 0’b11 to Port 1.
Timing CSR checks¶
Test: check_timing_csr
Testbench: I3C Controller (RTL)
Intent: Read the CSRs holding the timing values specified in 6.2 Timing Specification (I3C Basic Spec) and check that they are in the limits of the Spec.
Stimulus:
Provide the I3C controller clk frequency.
Write timing parameters into the I3C_EC.SOCMGMTIF.T_* CSRs.
Check:
Read each timing CSR and verify that the time adheres to the limits in the spec.
Controller error generation¶
Testpoints¶
Controller Error 2: No response to Broadcast Address (7'h7E)¶
Test: controller_error_nack_on_bcast
Testbench: I3C Controller (RTL) <-> I3C Target (Cocotbext)
Intent: Handle 5.1.10.2.3 Error Type CE2 I3C Basic Spec.
Stimulus:
send a SETDASA CCC to assign a dynamic address to the i3c target
enable bcast nack error injection on the Cocotbext Target
send an ENEC CCC (this will get NACKed)
Clear HC_CONTROL.RESUME and PIO_INTR_STATUS.TRANSFER_ERR_STAT to resume normal operation.
send an ENEC CCC
Check:
Observe a NACK for the ENEC CCC.
After NACK the Controller should generate a HDR Exit Pattern.
Check if the target recognizes the HDR Exit Pattern by monitoring the cocotbext targets
hdr_exit_detectedvariable.After the Broadcast Address NACK the controller should return a response descriptor with Error Status: ADDRESS_HEADER.
Check if subsequent ENEC CCC finishes as expected.
Controller TX Queue Underflow¶
Test: controller_tx_queue_underflow
Testbench: I3C Controller (RTL) <-> I3C Target (Cocotbext)
Intent: Handle 6.13.1.2 Underflow Error I3C HCI Spec.
Stimulus:
send a SETDASA CCC to assign a dynamic address to the i3c target
Write an I3C Write CMD desc specifying the write length to be i3c_target_len
generate act_len < i3c_target_len bytes of data and write into TX Queue
Clear HC_CONTROL.RESUME and PIO_INTR_STATUS.TRANSFER_ERR_STAT to resume normal operation.
send a regular I3C Write
Check:
After the TX Queue underflow the controller should return a response descriptor with Error Status: OVL.
After the regular I3C Write the controller should return a response descriptor with Error Status: SUCCESS.
Controller RX Queue Overflow¶
Test: controller_rx_queue_overflow
Testbench: I3C Controller (RTL) <-> I3C Target (Cocotbext)
Intent: Handle 6.13.1.2 Overflow Error I3C HCI Spec.
Stimulus:
send a SETDASA CCC to assign a dynamic address to the i3c target
Write an I3C Read CMD desc specifying the write length to be i3c_target_len > RX_QUEUE_DEPTH * 4
don’t read any data from the RX Queue
Clear HC_CONTROL.RESUME and PIO_INTR_STATUS.TRANSFER_ERR_STAT to resume normal operation.
Flush the RX Queue by setting the I3CBASE.RESET_CONTROL.RX_FIFO_RST CSR
send a regular I3C Read
Check:
After the RX Queue overflow the controller should return a response descriptor with Error Status: OVL.
After the regular I3C Read the controller should return a response descriptor with Error Status: SUCCESS.
Controller CE0 Handling (illegally formatted CCC)¶
Test: controller_error_short_ccc_ce0
Testbench: I3C Controller (RTL) <-> I3C Target (Cocotbext)
Intent: Handle 5.1.10.2.1 Error Type CE0 I3C Basic Spec (illegally formatted CCC).
Stimulus:
send a SETDASA CCC to assign a dynamic address to the i3c target
send a GETPID CCC with the data length field set to 6 bytes.
target returns less than 6 bytes. After the controller retries the CCC, the target should return the correct PID (6 bytes).
send another GETPID CCC with the data length field set to 6 bytes.
target returns less than 6 bytes. After the controller retries the CCC, the target should still return less than 6 bytes.
Clear HC_CONTROL.RESUME and PIO_INTR_STATUS.TRANSFER_ERR_STAT to resume normal operation.
send another GETPID CCC with the data length field set to 6 bytes.
target returns the correct PID (6 bytes).
send a private i3c Write.
Check:
after the first GETPID CCC the response descriptor should report SUCCESS (the controller should automatically recover the error by retrying, this is transparent to SW).
after the second GETPID CCC the response descriptor should report I3C_SHORT_READ.
after the third GETPID CCC the response descriptor should report SUCCESS.
after the private i3c write the response descriptor should report SUCCESS.
Controller Abort Transaction¶
Test: hc_abort
Testbench: I3C Controller (RTL) <-> I3C Target (Cocotbext)
Intent: Handle 6.8.4 Host Controller Abort Operation I3C HCI Spec.
Stimulus:
send a SETDASA CCC to assign a dynamic address to the i3c target
set PIO_CONTROL.RS CSR field to 1’b0
enqueue 2 private i3c write command descriptors with their respective TX data into the CMD/TX Queues.
set PIO_CONTROL.RS CSR field to 1’b1 to start execution.
set HC_CONTROL.ABORT CSR field to 1’b1 to abort current transaction.
set HC_CONTROL.ABORT and PIO_CONTROL.ABORT CSR fields to 1’b0 and HC_CONTROL.RESUME CSR field to 1’b1 to resume operation.
set RESET_CONTROL.TX_FIFO_RST CSR field to 1’b1 to flush TX Queue.
requeue the data for the 2nd i3c write into the TX Queue.
Check:
the response descriptor for the first private write cmd should report HC_ABORTED as an error status.
the response descriptor for the second private write cmd should report SUCCESS and the data received by the target should match the data sent by the controller.
Command Sequence Timeout (no halt)¶
Test: cmd_seq_timeout_no_halt
Testbench: I3C Controller (RTL) <-> I3C Target (Cocotbext)
Intent: Handle 6.13.2 Errors Due to Command Sequence Stall or Timeout I3C HCI Spec without halting execution.
Stimulus:
send a SETDASA CCC to assign a dynamic address to the i3c target.
set HC_CONTROL.HALT_ON_CMD_SEQ_TIMEOUT CSR field to 1’b0 to enable auto-resume on cmd seq timeout.
send a private write cmd descriptor with the TOC field set to 1’b0.
read the INTR_STATUS.HC_ERR_CMD_SEQ_TIMEOUT_STAT & INTR_STATUS.HC_SEQ_CANCEL_STAT interrupt CSRs.
clear the interrupts by writing 1’b1 to INTR_STATUS.HC_ERR_CMD_SEQ_TIMEOUT_STAT & INTR_STATUS.HC_SEQ_CANCEL_STAT CSR fields.
send a second private write cmd descriptor with the TOC field set to 1’b1.
Check:
the response descriptor for the first private write cmd should report SUCCESS and the data received by the target should match the data sent by the controller.
the INTR_STATUS.HC_ERR_CMD_SEQ_TIMEOUT_STAT & INTR_STATUS.HC_SEQ_CANCEL_STAT interrupt CSRs should both be set to 1’b1.
the response descriptor for the second private write cmd should report SUCCESS and the data received by the target should match the data sent by the controller.
Command Sequence Timeout (halt)¶
Test: cmd_seq_timeout_halt
Testbench: I3C Controller (RTL) <-> I3C Target (Cocotbext)
Intent: Handle 6.13.2 Errors Due to Command Sequence Stall or Timeout I3C HCI Spec with halting the execution.
Stimulus:
send a SETDASA CCC to assign a dynamic address to the i3c target.
set HC_CONTROL.HALT_ON_CMD_SEQ_TIMEOUT CSR field to 1’b1 to enable halting on cmd seq timeout.
send a private write cmd descriptor with the TOC field set to 1’b0.
read the INTR_STATUS.HC_ERR_CMD_SEQ_TIMEOUT_STAT & INTR_STATUS.HC_SEQ_CANCEL_STAT interrupt CSRs.
clear the interrupts by writing 1’b1 to INTR_STATUS.HC_ERR_CMD_SEQ_TIMEOUT_STAT & INTR_STATUS.HC_SEQ_CANCEL_STAT CSR fields.
resume operation by writing 1’b1 to the HC_CONTROL.RESUME CSR field.
send a second private write cmd descriptor with the TOC field set to 1’b1.
Check:
the response descriptor for the first private write cmd should report SUCCESS and the data received by the target should match the data sent by the controller.
the INTR_STATUS.HC_ERR_CMD_SEQ_TIMEOUT_STAT & INTR_STATUS.HC_SEQ_CANCEL_STAT interrupt CSRs should both be set to 1’b1.
the response descriptor for the second private write cmd should report SUCCESS and the data received by the target should match the data sent by the controller.
Interrupt Routing and Masking¶
Test: interrupt_routing_and_masking
Testbench: I3C Controller (RTL) <-> I3C Target (Cocotbext)
Intent: Systematically verify the two-tier interrupt masking architecture (STATUS_ENABLE and SIGNAL_ENABLE) 6.14 Interrupts I3C HCI Spec.
Stimulus: Loop through a predefined list of all interrupt fields. For each field:
Write 1’b0 to both the STATUS_ENABLE and SIGNAL_ENABLE CSR fields.
Write 1’b1 to the corresponding FORCE CSR field.
Write 1’b1 to the STATUS_ENABLE CSR field, then write 1’b1 to the FORCE CSR field again.
Write 1’b1 to the SIGNAL_ENABLE CSR field.
Write 1’b1 to the STATUS CSR field to clear the interrupt.
Check: For each interrupt field in the loop:
After the first force, the STATUS CSR field should remain 1’b0 (verifies STATUS_ENABLE masking).
After the second force, the STATUS CSR field should be 1’b1, but the physical
irq_opin should remain 1’b0 (verifies SIGNAL_ENABLE masking).After setting SIGNAL_ENABLE, the physical
irq_opin should assert to 1’b1 (verifies hardware signal routing).After writing to the STATUS CSR field, both the STATUS CSR field and the physical
irq_opin should de-assert to 1’b0 (verifies W1C clearing).
Controller Generate HDR Exit Pattern¶
Testpoints¶
Controller Generate HDR Exit Pattern¶
Test: controller_gen_hdr_exit_pattern
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Generate HDR exit pattern, as per 5.2.1.1.1 I3C Basic Spec.
Stimulus:
Send an Internal Control Command (Table 140 I3C HCI Spec) with:
MIPI_CMD: 0x5 // Controller SDA Recovery or Bus Reset Procedure
REC_RESET_PROC: 0x5 // Use CE2 error handling for a non-responsive I3C Target, by sending HDR Exit Pattern after NACK of Private read/write.
Send an I3C private read or private write to an unassigned target address.
Send an I3C private private write to the correct target address.
Check:
Observe a NACK for the I3C private Read or Write.
After NACK the Controller should generate a HDR Exit Pattern.
Check if the target recognizes the HDR Exit Pattern by monitoring the cocotbext targets
hdr_exit_detectedvariable.Check if subsequent private write finishes as expected.
Controller Hot-Join procedure for a new target¶
Testpoints¶
Controller Handle a Hot-Join Request from the target¶
Test: controller_hot_join
Recognize the Hot-Join pattern as specified in 5.1.5 I3C Basic Spec and eventually initiate a ENTDAA CCC to assign a dynamic address to the new target. Perform simple write/read to from target to verify target has joined correctly.
Controller I2C Transaction¶
Testpoints¶
i2c_private_write¶
Test: i2c_private_write
Testbench: I3C Controller (RTL) <-> I2C Target (Cocotbext)
Intent: Verify Private Write with Immediate Data Transfer Command Descriptor (7.2.2.1 TCRI Spec) or Regular Data Transfer Command Descriptor (7.2.2.2 TCRI Spec) to an individual I2C Target Device with known address
Stimulus:
create a CMD descriptor setting the I2C field to 0x1. The first data byte is the internal memory address (from which the monitor will read the data received by the target) the remaining data bytes are randomized. Check:
Read data from the I2C target memory by reading from the memory address specified in the first data byte.
Assert that the received data matches the sent data.
Assert that the response descriptor returns the correct data length (including first memory address byte) and a SUCCESS status.
i2c_private_read¶
Test: i2c_private_read
Testbench: I3C Controller (RTL) <-> I2C Target (Cocotbext)
Intent: Verify Private Read with Immediate Data Transfer Command Descriptor (7.2.2.1 TCRI Spec) or Regular Data Transfer Command Descriptor (7.2.2.2 TCRI Spec) to an individual I2C Target Device with known address
Stimulus:
Write
target_lenrandom bytes to the cocotbext I2C memory.create a CMD descriptor setting the I2C field to 0x1. Write a data byte for the internal memory address (from which the target will send the data), set the TOC field to 0x0 to issue a repeated Start.
create a second CMD descriptor setting the I2C field to 0x1. Set the data_length to
target_lenand the RnW field to 0x1 for a Read transaction. Check:Read received data from the Controller RX Queue and verify it matches the data written to the I2C target.
Assert that the response descriptors return the correct data length (including first memory address byte) and a SUCCESS status.
i2c_handle_nack¶
Test: i2c_handle_nack
Testbench: I3C Controller (RTL) <-> I2C Target (Cocotbext)
Intent: Handle a NACK by the I2C target during a private write.
Stimulus:
set the I2C target memory length to be less than the data length to be written (such that we can generate a NACK condition)
create a CMD descriptor setting the I2C field to 0x1. The first data byte is the internal memory address (from which the monitor will read the data received by the target) the remaining data bytes are randomized. Check:
Assert that the response descriptor returns a NACK Error State.
Controller IBI Handling¶
Testpoints¶
controller_ibi_accepted¶
Test: controller_ibi_accepted
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify 5.1.6 In-Band Interrupt from I3C Basic Spec. Using Broadcast mode. The target sends an IBI request with a mandatory data byte as well as optional data bytes and the controller accepts the request and pushes the results to the IBI_PORT.
Stimulus:
write a Target IBI Descriptor to the Targets TTI.IBI_PORT register containing the MDB and optional IBI payload.
Enable generation of the I3C Broadcast Header before private reads and writes using the internal control command descriptor with the following fields set:
mipi_cmd=0x2 // Broadcast Address Enable/Disable
mipi_rsvd=0x1 // Broadcast Address Enable
send a private i3c write.
Check:
The private write should finish correctly.
Read the PIOCONTROL.IBI_PORT CSR to retreive the IBI Status Descriptor as well as the IBI Payload.
IBI Status Descriptor Error should be 1’b0 (not aborted by controller).
The IBI Payload should match the MDB sent to the target as well as the optional IBI data bytes sent by the target.
controller_ibi_buffer_overflow¶
Test: controller_ibi_buffer_overflow
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify 5.1.6 In-Band Interrupt from I3C Basic Spec. Using Broadcast mode. The target sends an IBI request with a mandatory data byte as well as optional data bytes and the controller rejects the request (due to an internal buffer overflow) and pushes the results to the IBI_PORT.
Stimulus:
write a Target IBI Descriptor to the Targets TTI.IBI_PORT register containing the MDB and optional IBI payloads with total byte length larger than IBIDataBuffer.
Enable generation of the I3C Broadcast Header before private reads and writes using the internal control command descriptor with the following fields set:
mipi_cmd=0x2 // Broadcast Address Enable/Disable
mipi_rsvd=0x1 // Broadcast Address Enable
send a private i3c write.
Check:
The private write should finish correctly.
Read the PIOCONTROL.IBI_PORT CSR to retreive the IBI Status Descriptor as well as the IBI Payload.
IBI Status Descriptor Error should be 1’b1 (aborted by controller).
The first IBIDataBuffer bytes of IBI Payload should match the MDB sent to the target as well as the optional IBI data bytes sent by the target.
controller_ibi_rejected¶
Test: controller_ibi_rejected
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify rejecting IBI as per 5.1.6.2 I3C Target Interrupt Request from I3C Basic Spec.
Stimulus:
write a DAT entry for the target, setting the IBI_REJECT and IBI_PAYLOAD fields to 1’b1.
write a Target IBI Descriptor to the Targets TTI.IBI_PORT register containing the MDB and optional IBI payloads.
Enable generation of the I3C Broadcast Header before private reads and writes using the internal control command descriptor with the following fields set:
mipi_cmd=0x2 // Broadcast Address Enable/Disable
mipi_rsvd=0x1 // Broadcast Address Enable
Check:
Read the PIOCONTROL.IBI_PORT CSR to retreive the IBI Status Descriptor as well as the IBI Payload.
IBI Status Descriptor ID should contain the targets dynamic address.
IBI Status Descriptor Error should be 1’b0.
IBI Status Descriptor Status should be 1’b1 (NACK by Controller).
Controller Private Read¶
Testpoints¶
i3c_private_read_no_edge_case¶
Test: i3c_private_read_no_edge_case
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify Private Read with Regular Data Transfer Command (7.2.2.2 TCRI Spec) from an individual I3C Target Device with known static address Data Length should be between RX_STAT_THLD4 and RX_QUEUE_DEPTH4 and target provides exactly the requested amount of data.
Stimulus:
create a 64b CMD descriptor as per Table 18 7.2.2.2 TCRI Spec. With:
CMD_ATTR = 0x4 // RegularDataTransfer in Direct Format
TID: random transaction ID
I2C = 0x0 // I3C device
CMD: random this field is disregarded
CP = 0x0 // CMD field is not valid
DEV_ADDRESS: random allowed I3C address
DTT: number of bytes to be transferred
MODE = 0x0 // standard I3C SDR Speed
RNW = 0x1 // Read transfer
WROC = 0x1 // generate response descriptor
TOC = 0x1 // want to generate a stop signal after first transfer
DATA_BYTES: random between RX_STAT_THLD4 and RX_QUEUE_DEPTH4 (no edge cases)
split the 64b descriptor into 2 32b words (DWORD) and first write the lower DWORD into the COMMAND_PORT PIO reg followed by the upper DWORD.
Generate Random Data and send it via the TTI TX_DATA_PORT to the target.
Send a TTI_TX_DESC to the target specifying the data length.
Check:
data read from controller RX_DATA_PORT matches data sent to TX_DATA_PORT
if WROC = 1: response descriptor data length matches data bytes specified in CMD desc, and resp desc TID matches TID form CMD desc.
i3c_private_read_short_read¶
Test: i3c_private_read_short_read
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify Private Read with Regular Data Transfer Command (7.2.2.2 TCRI Spec) from an individual I3C Target Device with known static address Data Length should be between RX_STAT_THLD4 and RX_QUEUE_DEPTH4 and target provides less than the requested amount of data.
Stimulus:
create a 64b CMD descriptor as per Table 18 7.2.2.2 TCRI Spec. With:
CMD_ATTR = 0x4 // RegularDataTransfer in Direct Format
TID: random transaction ID
I2C = 0x0 // I3C device
CMD: random this field is disregarded
CP = 0x0 // CMD field is not valid
DEV_ADDRESS: random allowed I3C address
DTT: number of bytes to be transferred
SRE = 0x1 // should give an error when target aborts read too early
MODE = 0x0 // standard I3C SDR Speed
RNW = 0x1 // Read transfer
WROC = 0x1 // generate response descriptor
TOC = 0x1 // want to generate a stop signal after first transfer
DATA_BYTES: random between RX_STAT_THLD4 and RX_QUEUE_DEPTH4 (no edge cases)
split the 64b descriptor into 2 32b words (DWORD) and first write the lower DWORD into the COMMAND_PORT PIO reg followed by the upper DWORD.
Generate Random Data and send it via the TTI TX_DATA_PORT to the target.
Send a TTI_TX_DESC to the target specifying the data length to be less than DATA_BYTES (still more than RX_STAT_THLD).
Check:
data read from controller RX_DATA_PORT matches data sent to TX_DATA_PORT
if WROC = 1: response descriptor data length matches data bytes specified in CMD desc, and resp desc TID matches TID form CMD desc.
response descriptor error should be I3C short read status.
i3c_private_read_repeated_start¶
Test: i3c_private_read_repeated_start
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify Chaining multiple Private Reads with Regular Data Transfer Command (7.2.2.2 TCRI Spec) from an individual I3C Target Device with known static address using repeated start condition. Data Length should be between RX_STAT_THLD4 and RX_QUEUE_DEPTH4.
Stimulus:
create a 64b CMD descriptor as per Table 18 7.2.2.2 TCRI Spec. With:
CMD_ATTR = 0x4 // RegularDataTransfer in Direct Format
TID: random transaction ID
I2C = 0x0 // I3C device
CMD: random this field is disregarded
CP = 0x0 // CMD field is not valid
DEV_ADDRESS: random allowed I3C address
DTT: number of bytes to be transferred
SRE: random // randomly either generate error on short read or not
MODE = 0x0 // standard I3C SDR Speed
RNW = 0x1 // Read transfer
WROC = random // randomly generate response descriptor
TOC = 0x0 // want to use repeated start
DATA_BYTES: random between RX_STAT_THLD4 and RX_QUEUE_DEPTH4 (no edge cases)
split the 64b descriptor into 2 32b words (DWORD) and first write the lower DWORD into the COMMAND_PORT PIO reg followed by the upper DWORD.
Generate Random Data and send it via the TTI TX_DATA_PORT to the target.
Check:
data read from controller RX_DATA_PORT matches data sent to TX_DATA_PORT
Controller resets target¶
Testpoints¶
Reset target¶
Test: controller_resets_target
Reset a target according to 5.1.11 I3C Basic Spec. (using RSTACT CCC)
Controller Private Write¶
Testpoints¶
i3c_private_write_correct_bus_condition¶
Test: i3c_private_write_correct_bus_condition
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify Private Write with Immediate Data Transfer Command Descriptor (7.2.2.1 TCRI Spec) to an individual I3C Target Device with known static address
Stimulus:
create a CMD 64b descriptor as per Table 16 7.2.2.1 TCRI Spec. With:
CMD_ATTR = 0x5 // ImmediateDataTransfer in Direct Format
TID: random transaction ID
I2C = 0x0 // I3C device
CMD: random this field is disregarded
CP = 0x0 // CMD field is not valid
DEV_ADDRESS: random allowed I3C address
DTT: number of bytes to be transferred
MODE = 0x0 // standard I3C SDR Speed
RNW = 0x0 // Write transfer
WROC = 0x0 // no response
TOC = 0x1 // want to generate a stop signal after first transfer
DATA_BYTES: random data to be sent
split the 64b descriptor into 2 32b words (DWORD) and first write the lower DWORD into the COMMAND_PORT PIO reg followed by the upper DWORD.
Check: - correct start/restart condition is generated - check that following data bytes are correctly serialized (from MSB to LSB) - check that T bit is correctly generated - first byte is DEV_ADDRESS - following DTT bytes is DATA_BYTES - correct stop condition is generated
i3c_private_write_target_read¶
Test: i3c_private_write_target_read
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify Private Write with Immediate Data Transfer Command Descriptor (7.2.2.1 TCRI Spec) to an individual I3C Target Device with known static address
Stimulus:
create a CMD 64b descriptor as per Table 16 7.2.2.1 TCRI Spec. With:
CMD_ATTR = 0x5 // ImmediateDataTransfer in Direct Format
TID: random transaction ID
I2C = 0x0 // I3C device
CMD: random this field is disregarded
CP = 0x0 // CMD field is not valid
DEV_ADDRESS: random allowed I3C address
DTT: number of bytes to be transferred
MODE = 0x0 // standard I3C SDR Speed
RNW = 0x0 // Write transfer
WROC = 0x0 // no response
TOC = 0x1 // want to generate a stop signal after first transfer
DATA_BYTES: random data to be sent
split the 64b descriptor into 2 32b words (DWORD) and first write the lower DWORD into the COMMAND_PORT PIO reg followed by the upper DWORD.
Check:
DATA_BYTES are equal to recv data from the target I3C_EC.TTI.RX_DATA_PORT CSR.
i3c_private_write_target_read_resp_desc¶
Test: i3c_private_write_target_read_resp_desc
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify Private Write with Immediate Data Transfer Command Descriptor (7.2.2.1 TCRI Spec) to an individual I3C Target Device with known static address
Stimulus:
create a CMD 64b descriptor as per Table 16 7.2.2.1 TCRI Spec. With:
CMD_ATTR = 0x5 // ImmediateDataTransfer in Direct Format
TID: random transaction ID
I2C = 0x0 // I3C device
CMD: random this field is disregarded
CP = 0x0 // CMD field is not valid
DEV_ADDRESS: random allowed I3C address
DTT: number of bytes to be transferred
MODE = 0x0 // standard I3C SDR Speed
RNW = 0x0 // Write transfer
WROC = 0x1 // write response descriptor
TOC = 0x1 // want to generate a stop signal after first transfer
DATA_BYTES: random data to be sent
split the 64b descriptor into 2 32b words (DWORD) and first write the lower DWORD into the COMMAND_PORT PIO reg followed by the upper DWORD.
Check:
DATA_BYTES are equal to recv data from the target I3C_EC.TTI.RX_DATA_PORT CSR.
Read Response Descriptor to verify TID and Data Length match the CMD Descriptor and Error Status is Success.
i3c_private_write_wrong_target_addr¶
Test: i3c_private_write_wrong_target_addr
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify that Private Write to a non existing target address generates a NACK Response Descriptor.
Stimulus:
create a CMD 64b descriptor as per Table 16 7.2.2.1 TCRI Spec. With:
CMD_ATTR = 0x5 // ImmediateDataTransfer in Direct Format
TID: random transaction ID
I2C = 0x0 // I3C device
CMD: random this field is disregarded
CP = 0x0 // CMD field is not valid
DEV_ADDRESS: random allowed I3C address
DTT: number of bytes to be transferred
MODE = 0x0 // standard I3C SDR Speed
RNW = 0x0 // Write transfer
WROC = 0x1 // write response descriptor
TOC = 0x1 // want to generate a stop signal after first transfer
DATA_BYTES: random data to be sent
split the 64b descriptor into 2 32b words (DWORD) and first write the lower DWORD into the COMMAND_PORT PIO reg followed by the upper DWORD.
Check:
DATA_BYTES are equal to recv data from the target I3C_EC.TTI.RX_DATA_PORT CSR.
Read Response Descriptor to verify TID matches the CMD Descriptor and Data Length is 0 and Error Status is NACK.
i3c_private_write_tx_queue_target_read¶
Test: i3c_private_write_tx_queue_target_read
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify Private Write with Regular Data Transfer Command (7.2.2.2 TCRI Spec) to an individual I3C Target Device with known static address
Stimulus:
create a 64b descriptor as per Table 18 7.2.2.2 TCRI Spec. With:
CMD_ATTR = 0x4 // RegularDataTransfer in Direct Format
TID: random transaction ID
I2C = 0x0 // I3C device
CMD: random this field is disregarded
CP = 0x0 // CMD field is not valid
DEV_ADDRESS: random allowed I3C address
SHORT_READ_ERR = 0 // no read
DBP = 0 // no def byte
MODE = 0x0 // standard I3C SDR Speed
RNW = 0x0 // Write transfer
WROC: random // randomly generate response descriptor
TOC = 0x1 // want to generate a stop signal after first transfer
DEF_BYTE: random // this is disregarded
DATA_LENGTH: length of data transfer (1 < DATA_LENGTH < TX_QUEUE_DEPTH*4) // Indicates the number of bytes to be transferred
split the 64b descriptor into 2 32b words (DWORD) and first write the lower DWORD into the COMMAND_PORT PIO reg followed by the upper DWORD.
Check:
data being sent via TX_DATA_PORT is equal to data on the target I3C_EC.TTI.RX_DATA_PORT CSR.
i3c_private_write_tx_queue_target_read_fifo_full¶
Test: i3c_private_write_tx_queue_target_read_fifo_full
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify Private Write with Regular Data Transfer Command (7.2.2.2 TCRI Spec) to an individual I3C Target Device with known static address
Stimulus:
create a 64b descriptor as per Table 18 7.2.2.2 TCRI Spec. With:
CMD_ATTR = 0x4 // RegularDataTransfer in Direct Format
TID: random transaction ID
I2C = 0x0 // I3C device
CMD: random this field is disregarded
CP = 0x0 // CMD field is not valid
DEV_ADDRESS: random allowed I3C address
SHORT_READ_ERR = 0 // no read
DBP = 0 // no def byte
MODE = 0x0 // standard I3C SDR Speed
RNW = 0x0 // Write transfer
WROC = 0x1 // write response descriptor
TOC = 0x1 // want to generate a stop signal after first transfer
DEF_BYTE: random // this is disregarded
DATA_LENGTH: length of data transfer (TX_QUEUE_DEPTH4 < DATA_LENGTH < TX_QUEUE_DEPTH4*3) // Indicates the number of bytes to be transferred
split the 64b descriptor into 2 32b words (DWORD) and first write the lower DWORD into the COMMAND_PORT PIO reg followed by the upper DWORD.
Check:
data being sent via TX_DATA_PORT is equal to data on the target I3C_EC.TTI.RX_DATA_PORT CSR.
i3c_private_write_repeated_start¶
Test: i3c_private_write_repeated_start
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify Chaining Private Writes with Regular Data Transfer Command (7.2.2.2 TCRI Spec) to an individual I3C Target Device with known static address using Sr condition.
Stimulus:
create 5 64b CMD descriptors as per Table 18 7.2.2.2 TCRI Spec. With:
CMD_ATTR = 0x4 // RegularDataTransfer in Direct Format
TID: random transaction ID
I2C = 0x0 // I3C device
CMD: random this field is disregarded
CP = 0x0 // CMD field is not valid
DEV_ADDRESS: random allowed I3C address
SHORT_READ_ERR = 0 // no read
DBP = 0 // no def byte
MODE = 0x0 // standard I3C SDR Speed
RNW = 0x0 // Write transfer
WROC: random // randomly generate response descriptor
TOC = 0x0 // we want to test repeated start
DEF_BYTE: random // this is disregarded
DATA_LENGTH: length of data transfer (1 < DATA_LENGTH < TX_QUEUE_DEPTH43) // Indicates the number of bytes to be transferred
split the 64b descriptor into 2 32b words (DWORD) and first write the lower DWORD into the COMMAND_PORT PIO reg followed by the upper DWORD.
Check:
data being sent via TX_DATA_PORT is equal to data on the target I3C_EC.TTI.RX_DATA_PORT CSR.
i3c_private_write_dat¶
Test: i3c_private_write_dat
Testbench: I3C Controller (RTL) <-> I3C Target (RTL)
Intent: Verify Private Write as per 7.1.2.1 / 7.1.2.2 TCRI Spec to an individual I3C Target Device with known DAT index
Stimulus:
Assign dynamic address of device to DAT index
create a CMD 64bit descriptor as per Table 7 7.1.2.1 TCRI Spec. With:
CMD_ATTR = 0x1 / 0x0 // ImmediateDataTransfer in DAT Format / Regular Transfer Command in DAT Format
DEV_INDEX: random 5 bit number
RNW = 0x0 // Write transfer
DATA_BYTES: random data to be sent
split the 64bit descriptor into 2 32bit words (DWORD) and first write the lower DWORD into the COMMAND_PORT PIO reg followed by the upper DWORD.
Check:
data being sent via TX_DATA_PORT is equal to data on the target I3C_EC.TTI.RX_DATA_PORT CSR.
response descriptor data length matches data bytes specified in CMD desc, resp desc TID matches TID form CMD desc and resp error status is SUCCESS.
Testplans for the core¶
Target¶
Testpoints¶
i3c_target_write¶
Test: i3c_target_write
Spawns a TTI agent that reads from TTI descriptor and data queues and stores received data.
While the agent is running the test issues several private writes over I3C. Data sent over I3C is compared with data received by the agent.
The test runs at core clock of 100 and 200 MHz. The slowest clock that does not result in a tSCO violation is 166 MHz. The I3C bus clock is set to 12.5 MHz.
i3c_target_write_long¶
Tests:
Verifies the handling of long private writes (255 and 256 bytes) that are not issued in any other test, in order to cover upper bits of transaction length signals in the design.
Uses the same flow as i3c_target_write.
i3c_target_read¶
Test: i3c_target_read
Writes a data chunk and its descriptor to TTI TX queues, issues an I3C private read transfer. Verifies that the data matches. Repeats the two steps N times.
Writes N data chunks and their descriptors to TTI TX queues, issues N private read transfers over I3C. For each one verifies that data matches.
Writes a data chunk and its descriptor to TTI TX queues, issues an I3C private read transfer which is shorter than the length of the chunk. Verifies that the received data matches with the chunk. Repeats the steps N times.
The test runs at core clock of 100 and 200 MHz. The slowest clock that does not result in a tSCO violation is 166 MHz. The I3C bus clock is set to 12.5 MHz.
i3c_target_read_long¶
Test: i3c_target_read_long
Verifies the correct handling of long private reads (255 and 256 bytes) that are not issued in any other tests, in order to cover upper bits of transaction length signals in the design.
i3c_target_read_empty¶
Test: i3c_target_read_empty
Issues multiple read transactions to the target and randomly selects whether each transaction has data.
If transaction is selected to contain data, writes a data chunk and its descriptor to TTI TX queues, and verifies that the data matches.
If transaction doesn’t contain data, checks that request is NACKed.
i3c_target_read_to_multiple_targets¶
Test: i3c_target_read_to_multiple_targets
Sends multiple I3C frame, each containing multiple read transactions with randomly selected addresses. If transaction addresses I3C target, randomly selects if transaction returns data or is NACked. Compares returned data if available.
If transaction doesn’t address I3C target, expects NACK to be returned.
i3c_target_ibi¶
Test: i3c_target_ibi
Writes an IBI descriptor to the TTI IBI queue. Waits until the controller services the IBI. Checks if the mandatory byte (MDB) matches on both sides.
Reads the LAST_IBI_STATUS fields of the TTI STATUS CSR. Ensures that it is equal to 0 (no error).
Writes an IBI descriptor followed by N bytes of data to the TTI IBI queue. Waits until the controller services the IBI. Checks if the mandatory byte (MDB) and data matches on both sides.
Repeats the LAST_IBI_STATUS check.
The test runs at core clock of 100 and 200 MHz. The slowest clock that does not result in a tSCO violation is 166 MHz. The I3C bus clock is set to 12.5 MHz.
i3c_target_ibi_retry¶
Test: i3c_target_ibi_retry
Disables ACK-ing IBIs in the I3C controller model, issues an IBI from the target by writing to TTI IBI queue. Waits for a fixed time period - sufficiently long for the target to retry sending the IBI, reads LAST_IBI_STATUS from the TTI STATUS CSR, check if it is set to 3 (IBI retry).
Re-enables ACK-ing of IBIs in the controller model, waits for the model to service the IBI, compares the IBI mandatory byte (MDB) with the one written to the TTI queue. Reads LAST_IBI_STATUS from the TTI STATUS CSR, check if it is set to 0 (no error).
The test runs at core clock of 100 and 200 MHz. The slowest clock that does not result in a tSCO violation is 166 MHz. The I3C bus clock is set to 12.5 MHz.
i3c_target_ibi_data¶
Test: i3c_target_ibi_data
Sets a limit on how many IBI data bytes may be accepted in the controller model. Issues an IBI with more data bytes by writing to the TTI IBI queue, checks if the IBI gets serviced correctly, compares data.
Issues another IBI with data payload within the set limit, checks if it gets serviced correctly, compares data.
The test runs at core clock of 100 and 200 MHz. The slowest clock that does not result in a tSCO violation is 166 MHz. The I3C bus clock is set to 12.5 MHz.
i3c_target_ibi_data_long¶
Test: i3c_target_ibi_data_long
Verifies issuing an IBI of a maximum length obtained via the GETMRL CCC. Also covers upper bits of the IBI descriptor data length.
i3c_target_writes_and_reads¶
Test: i3c_target_writes_and_reads
Writes a randomized data chunk to the TTI TX data queue, writes a corresponding descriptor to the TTI TX descriptor queue.
Issues private write transfers to the target with randomized payloads, waits until a TTI interrupt is set by polling TTI INTERRUPT_STATUS CSR. Reads received data from TTI RX queues, compares it with what has been sent.
Does a private read transfer, compares if the received data equals the data written to TTI TX queue in the beginning of the test.
The test runs at core clock of 100 and 200 MHz. The slowest clock that does not result in a tSCO violation is 166 MHz. The I3C bus clock is set to 12.5 MHz.
i3c_target_pwrite_err_detection¶
Test: i3c_target_pwrite_err_detection
Verifies target reports no error conditions using CSR and GETSTATUS CCC. Sends I3C private write with incorrect T-bit value. Checks that the CSR reports protocol error condition and checks that RX descriptor has error condition flag set. Sends GETSTATUS CCC and checks that it also reports protocol error.
i3c_target_pwrite_overflow_detection¶
Test: i3c_target_pwrite_overflow_detection
Verifies target reports no error conditions using CSR and GETSTATUS CCC. Sends I3C private write with more data than target can receive. Checks that the CSR doesn’t report protocol error condition and checks that RX descriptor has error condition flag set. Sends GETSTATUS CCC and checks that it also doesn’t report protocol error.
i3c_target_private_read_sizes_and_abort¶
Test: i3c_target_private_read_sizes_and_abort
Tests private read transfers with specific sizes and controller-initiated aborts.
Performs private reads of exactly 256 bytes, 8 bytes, 11 bytes (non-word- aligned), and a controller-abort scenario where the read is terminated early. Verifies data matches and the target recovers cleanly after abort.
i3c_target_tx_flush_clears_converter¶
Test: i3c_target_tx_flush_clears_converter
Verifies that TTI RESET_CONTROL.TX_DATA_RST flushes both the TX FIFO and the width_converter_Nto8 shift register.
Writes data to the TX FIFO without a descriptor, asserts TX_DATA_RST, then writes new data with a descriptor and performs a private read. Verifies only the post-flush data is returned.
i3c_target_rx_flush_clears_converter¶
Test: i3c_target_rx_flush_clears_converter
Verifies that TTI RESET_CONTROL.RX_DATA_RST flushes both the RX FIFO and the width_converter_8toN shift register.
Writes data to the RX FIFO via Private Write to overflow the queue, asserts RX_DATA_RST, then writes new data via Private Write. Verifies that data from first transfer does not corrupt second transfer.
priv_write_normal_stop_baseline¶
Test: priv_write_normal_stop_baseline
Baseline: 8-byte private write completes normally with STOP. Verifies RX descriptor byte count equals 8 and data matches.
priv_write_stop_mid_byte¶
Test: priv_write_stop_mid_byte
8-byte private write. After 5 complete bytes and T-bits, sends 4 bits of byte 6, then STOP. Verifies RX descriptor reports 5 bytes and data matches. Also verifies clean recovery with a subsequent normal write.
priv_write_sr_mid_byte¶
Test: priv_write_sr_mid_byte
8-byte private write. After 5 complete bytes, sends 4 bits of byte 6, then Repeated Start followed by STOP. Verifies RX descriptor reports 5 bytes. Also verifies clean recovery.
priv_write_stop_during_tbit¶
Test: priv_write_stop_during_tbit
8-byte private write. After 5 complete bytes and T-bits, sends 8 data bits of byte 6 (no T-bit), then STOP fires while FSM is in RxPWriteTbit. Tests correct handling of STOP during T-bit phase.
BLOCKED BY DESIGN BUG: rx_fifo_wvalid_raw fires but rx_last_byte_o does not, resulting in data pushed without a descriptor.
priv_write_sr_during_tbit¶
Test: priv_write_sr_during_tbit
8-byte private write. After 5 complete bytes and T-bits, sends 8 data bits of byte 6, then Sr fires while FSM is in RxPWriteTbit. Tests correct handling of Repeated Start during T-bit phase.
BLOCKED BY DESIGN BUG: rx_fifo_wvalid_raw fires but rx_last_byte_o does not, resulting in data pushed without a descriptor.
priv_write_tight_timing_sr¶
Test: priv_write_tight_timing_sr
5-byte private write. All bytes and T-bits complete normally. Sr issued immediately after the last T-bit (tight timing). Verifies descriptor reports exactly 5 bytes (not 4 due to off-by-one).
Data over-/underflow handling¶
Testpoints¶
Reading from empty RX descriptor FIFO¶
Test: empty_rx_desc_read
Perform read bus access to the empty RX descriptor queue, verify that response comes back and it holds value of 0.
Reading from empty RX data FIFO¶
Test: empty_rx_data_read
Perform read bus access to the empty RX descriptor queue, verify that response comes back and it holds value of 0.
Reading from empty indirect FIFO¶
Test: empty_indirect_fifo_read
Perform read bus access to the empty RX descriptor queue, verify that response comes back and it holds value of 0.
Writing to full TX descriptor FIFO¶
Test: full_tx_desc_write
Perform multiple write bus accesses to the TX descriptor queue, verify that all transactions has finished.
Writing to full TX data FIFO¶
Test: full_tx_data_write
Perform multiple write bus accesses to the TX data queue, verify that all transactions has finished.
Writing to full IBI FIFO¶
Test: full_ibi_write
Perform multiple write bus accesses to the IBI queue, verify that all transactions has finished.
Bus timers top-level¶
Testpoints¶
STOP condition starts the counter¶
Test: bus_timers_stop_starts_counter
Verifies that detecting a STOP condition on the I3C bus starts the bus_timers counter and that the counter progresses through the bus busy, free, available and idle states in the correct order with the expected timing.
START condition resets the counter¶
Test: bus_timers_reset_on_start
Verifies that a START condition detected after a STOP resets the bus_timers counter back to 0 and deasserts all timer-state outputs (bus_free, bus_available, bus_idle), leaving bus_busy asserted.
HDR mode entry holds the counter at 0¶
Test: bus_timers_reset_on_hdr_entry
Verifies that entering HDR mode (in_hdr_mode_i asserted) continuously holds the bus_timers counter at 0 for the duration of HDR mode. After HDR exit the counter stays at 0 until the next STOP condition, which must then restart normal timer operation.
bus_idle¶
Test: bus_idle
Generate STOP condition, wait for over 200us and ensure the target entered idle state. Then generate START condition and ensure target left idle state.
exotic_idle_timings¶
Test: exotic_idle_timings
The bus conditions in the bus_timers module operate independently from each other with each one configured by its own CSR. This introduces the unlikely possibility of T_AVAL < T_FREE and T_IDLE < T_AVAL. This test exists to cover these conditions.
bus_edge_detectors¶
Test: bus_edge_detectors
Sets up different values of T_R and T_F timings and for each detector (SDA posedge, SDA negedge, SCL posedge, SCL negedge) verifies both whether the edge is correctly detected when held for appropriate duration and whether it doesn’t get detected when deasserted before the timing duration.
CCC handling¶
Testpoints¶
ccc_getstatus¶
Test: ccc_getstatus
The test reads PENDING_INTERRUPT field from the TTI INTERRUPT status CSR. Next, it issues the GETSTATUS directed CCC to the target. Finally it compares the interrupt status returned by the CCC with the one read from the register.
ccc_setdasa¶
Test: ccc_setdasa
The test sets dynamic address and virtual dynamic address by sending SETDASA CCC. Then it verifies that correct addresses have been set by reading STBY_CR_DEVICE_ADDR CSR. The test also sends a random number of CCCs targeting devices other than DUT, and checks if the dynamic address was not accepted.
ccc_setdasa_nack¶
Test: ccc_setdasa_nack
The test sets dynamic address and virtual dynamic address by sending SETDASA CCC. Then it sends second SETDASA command and checks that targets NACKed them.
ccc_setnewda¶
Test: ccc_setnewda
The test sets dynamic address and virtual dynamic address directly using CSR accesses. Then it sends SETNEWDA commands to both targets and checks their dynamic addresses got updated.
ccc_rstdaa¶
Test: ccc_rstdaa
Sets dynamic address via STBY_CR_DEVICE_ADDR CSR, then sends RSTDAA CCC and verifies that the address got cleared.
ccc_getbcr¶
Test: ccc_getbcr
Reads BCR register content by sending GETBCR CCC and examining returned data.
ccc_getdcr¶
Test: ccc_getdcr
Reads DCR register content by sending GETDCR CCC and examining returned data.
ccc_getmwl¶
Test: ccc_getmwl
Reads MWL register content by sending GETMWL CCC and examining returned data.
ccc_getmrl¶
Test: ccc_getmrl
Reads MRL register content by sending GETMWL CCC and examining returned data.
ccc_setaasa¶
Test: ccc_setaasa
Issues the broadcast SETAASA CCC and checks if the target uses its static address as dynamic by examining STBY_CR_DEVICE_ADDR CSR.
ccc_setaasa_ignore¶
Test: ccc_setaasa_ignore
Assigns dynamic address different to static address using CSR. Issues the broadcast SETAASA CCC and checks if the target ignores this command by examining STBY_CR_DEVICE_ADDR CSR.
ccc_setaasa_single¶
Test: ccc_setaasa_single
Pre-configures the dynamic address of either the regular or the virtual device via CSR (with valid=1), then sends SETAASA. Verifies that the pre-configured device retains its CSR-set address while the other device receives its static address as the new dynamic address.
ccc_getpid¶
Test: ccc_getpid
Sends the CCC to the target and examines if the returned PID matches the expected.
ccc_enec_disec_direct¶
Test: ccc_enec_disec_direct
Sends DISEC CCC to the target and verifies that events are disabled. Then, sends ENEC CCC to the target and checks that events are enabled.
ccc_enec_disec_bcast¶
Test: ccc_enec_disec_bcast
Sends broadcast DISEC CCC and verifies that events are disabled. Then, sends broadcast ENEC CCC and checks that events are enabled.
ccc_setmwl_direct¶
Test: ccc_setmwl_direct
Sends directed SETMWL CCC to the target and verifies that the register got correctly set. The check is performed by examining relevant wires in the target DUT.
ccc_setmrl_direct¶
Test: ccc_setmrl_direct
Sends directed SETMRL CCC to the target and verifies that the register got correctly set. The check is performed by examining relevant wires in the target DUT.
ccc_setmwl_bcast¶
Test: ccc_setmwl_bcast
Sends broadcast SETMWL CCC and verifies that the register got correctly set. The check is performed by examining relevant wires in the target DUT.
ccc_setmrl_bcast¶
Test: ccc_setmrl_bcast
Sends SETMRL CCC and verifies that the register got correctly set. The check is performed by examining relevant wires in the target DUT.
ccc_rstact¶
Test: ccc_rstact
Sends directed/broadcast RSTACT CCC to the target followed by reset pattern and checks if reset action was stored correctly. The check is done by examining DUT wires. Then, triggers target reset and verifies that the peripheral_reset_o signal gets asserted.
ccc_direct_multiple_wr¶
Test: ccc_direct_multiple_wr
Sends a sequence of multiple directed SETMWL CCCs. The first and the last have non-matching address. The two middle ones set MWL to different values. Verify that the target responded to correct addresses and executed both CCCs.
ccc_direct_multiple_rd¶
Test: ccc_direct_multiple_rd
Sends SETMWL CCC. Then sends multiple directed GETMWL CCCs to thee different addresses. Only the one for the target should be ACK-ed with the correct MWL content.
ccc_entdaa¶
Test: ccc_entdaa
Verifies ENTDAA procedure: controller issues ENTDAA CCC, target responds with 64-bit device ID, controller assigns dynamic address. Checks address is set correctly in STBY_CR_DEVICE_ADDR CSR.
ccc_entdaa_arb_lost¶
Test: ccc_entdaa_arb_lost
Verifies ENTDAA arbitration-lost path: when arbitration_lost_i is asserted during ID bit transmission, the DUT enters LostArbitration state and retries on the next ENTDAA round.
ccc_entdaa_early_stop¶
Test: ccc_entdaa_early_stop
Verifies ENTDAA with early STOP after assigning only the main target. The virtual target should remain unaddressed.
ccc_entdaa_te3_te4¶
Test: ccc_entdaa_te3_te4
Verifies TE3 and TE4 error handling during ENTDAA.
TE3: Parity error on assigned address causes target to NACK, retries on next ENTDAA round. TE4: Controller assigns same address to two targets, causes error.
Ensures that CSR with error counter does not overflow.
ccc_enthdr_all_codes¶
Test: ccc_enthdr_all_codes
Verifies all ENTHDR codes (0x20-0x27) cause the target to enter HDR mode. After each ENTHDR, verifies clean recovery with HDR exit pattern.
ccc_error_det_enable¶
Test: ccc_error_det_enable
Verifies TE0-TE5 error detection enable CSR bits can be toggled. When TE0 is disabled, unsupported CCC should not trigger error. When TE0 is re-enabled, error detection resumes.
ccc_getcaps¶
Test: ccc_getcaps
Tests GETCAPS (0x95) direct GET CCC with various defining bytes, targeting both main and virtual targets.
ccc_setdasa_padding_err¶
Tests:
Verifies that SETDASA/SETNEWDA with padding bit[0]=1 triggers a framing error and does NOT apply the address.
ccc_te2_parity¶
Test: ccc_te2_parity
Verifies TE2 error detection: bad T-bit parity on CCC defining byte causes the target to abort the CCC and signal TE2.
ccc_te5_wrong_direction¶
Test: ccc_te5_wrong_direction
TE5 error: wrong R/W direction for direct CCC. GET CCC sent with W direction causes NACK. SET CCC sent with R direction causes NACK.
ccc_unknown_broadcast¶
Test: ccc_unknown_broadcast
Unknown broadcast CCCs should be silently ignored (target accepts data but takes no action). Verifies no crash and clean recovery.
ccc_unsupported_direct_nack¶
Test: ccc_unsupported_direct_nack
Verifies that unsupported direct CCCs are NACKed by the target. Tests deprecated, unsupported, and vendor-specific CCC codes.
ccc_vendor_codes¶
Test: ccc_vendor_codes
Verifies vendor-specific CCC codes: Broadcast vendor CCCs (0x61-0x7F): target ignores data silently. Direct vendor CCCs: target NACKs.
ccc_abort_bcast_stop¶
Test: ccc_abort_bcast_stop
Controller STOP during CCC at various phases: STOP during broadcast SET data (incomplete data). Verifies clean recovery.
ccc_abort_get_sr¶
Test: ccc_abort_get_sr
Controller Sr abort during multi-byte GET CCC reads. Reads fewer bytes than expected, then sends Sr to abort. Verifies clean recovery and correct subsequent CCC processing.
ccc_addr_lifecycle¶
Test: ccc_addr_lifecycle
Full address lifecycle: RSTDAA -> SETDASA -> verify -> SETNEWDA -> verify -> RSTDAA -> verify cleared. Tests both main and virtual targets.
ccc_back_to_back¶
Test: ccc_back_to_back
Back-to-back CCCs with no idle gap between transactions. Verifies all CCCs process correctly.
ccc_chain_bcast¶
Test: ccc_chain_bcast
Chain multiple broadcast CCCs via Sr+7E/W within a single frame. Verifies each CCC takes effect.
ccc_chain_direct¶
Test: ccc_chain_direct
Chain multiple direct CCCs within a single frame. Verifies correct target address matching across chained CCCs.
ccc_random_interleave¶
Test: ccc_random_interleave
Random sequence of SET/GET CCCs to random targets. Stress tests the CCC FSM state machine with varied patterns.
ccc_rstact_arm_clear_on_start¶
Test: ccc_rstact_arm_clear_on_start
Verifies RSTACT arm is cleared by START (not Sr). After arming with whole-target reset, a private transfer (START) clears the arm state.
ccc_rstact_escalation_clear¶
Test: ccc_rstact_escalation_clear
Verifies that RSTACT CCC and GETSTATUS CCC clear the escalation counter, preventing escalated reset on the next target reset pattern.
ccc_rstact_read_action¶
Test: ccc_rstact_read_action
Verifies RSTACT internal state after arming. Per spec, rstact_armed is cleared by the next START (not Sr), so a subsequent read may return the armed action.
ccc_rstact_unsupported_db¶
Test: ccc_rstact_unsupported_db
Verifies RSTACT with unsupported defining bytes is NACKed.
ccc_rstact_vt_detect¶
Test: ccc_rstact_vt_detect
Verifies RSTACT Defining Byte 0x04 (Virtual Target Detect) flag set/clear and Defining Byte 0x84 (Virtual Target Indication) behavior.
ccc_rstact_vt_detect_no_reset_arm¶
Test: ccc_rstact_vt_detect_no_reset_arm
Verifies DB=0x04 does not arm a reset action: default peripheral->escalation path still works after sending RSTACT with VT detect defining byte.
ccc_setmwl_sr_abort_during_data¶
Test: ccc_setmwl_sr_abort_during_data
Sr abort during SETMWL data phase. Verifies that the target does not apply the partial data.
BLOCKED BY DESIGN BUG: set_tx_data_complete fires unconditionally on Sr abort.
ccc_getstatus_abort_then_chain_setmwl¶
Test: ccc_getstatus_abort_then_chain_setmwl
Verifies that aborting GETSTATUS mid-read and immediately chaining into another CCC (SETMWL) in the same bus frame does not corrupt the target state.
ccc_getstatus_sr_abort_clears_protocol_err¶
Test: ccc_getstatus_sr_abort_clears_protocol_err
Verifies GETSTATUS Sr abort behavior with protocol error flag. Per spec, a target shall only clear its pending status upon successfully completing the GETSTATUS response.
BLOCKED BY DESIGN BUG: set_tx_data_complete fires unconditionally on Sr abort, causing premature error clearing.
ccc_getstatus_sr_abort_done_assert¶
Test: ccc_getstatus_sr_abort_done_assert
Verifies that aborting GETSTATUS during T-Bit transfer does not fire get_status_done and reports protocol error.
ccc_entdaa_virtual_only¶
Test: ccc_entdaa_virtual_only
Coverage: ccc.sv RxCmdTbit -> HandleVirtualTargetENTDAA. Boot with main target already addressed. Virtual target has no dynamic address. ENTDAA skips HandleTargetENTDAA and goes directly to HandleVirtualTargetENTDAA.
ccc_entdaa_main_only¶
Test: ccc_entdaa_main_only
Coverage: HandleTargetENTDAA -> WaitForENTDAAEnd (entdaa_needs_virt_addr=0). Boot with virtual target already addressed. Main target has no dynamic address. After main completes, FSM goes to WaitForENTDAAEnd.
ccc_entdaa_both_addressed¶
Test: ccc_entdaa_both_addressed
Coverage: RxCmdTbit -> WaitForENTDAAEnd. Boot with both targets already addressed. ENTDAA goes directly to WaitForENTDAAEnd since neither target needs an address.
ccc_te0_reserved_addr_direct¶
Test: ccc_te0_reserved_addr_direct
Coverage: Toggle is_te0_err_condition, te0_err_ccc (ccc.sv:769). Send a direct CCC where the target address phase uses 7E/R (reserved address with read bit). Triggers TE0 in TxTargetAddrAck.
ccc_direct_chain_7e_termination¶
Test: ccc_direct_chain_7e_termination
Coverage: ccc.sv target_addr_matches_rsvd -> NextCCC. After a direct GET CCC response, send Sr+7E/W instead of STOP. Triggers the reserved address path in TxTargetAddrAck, transitioning to NextCCC for CCC chaining.
ccc_all_det_en_toggle¶
Test: ccc_all_det_en_toggle
Coverage: All *_det_en_i toggle coverage. For TE0, TE1, TE2, TE5: toggle the detection enable CSR, inject the error with det_en=0 (verify no error flag), then with det_en=1 (verify error fires).
ccc_te2_direct_def_byte_tbit¶
Test: ccc_te2_direct_def_byte_tbit
Coverage: ccc.sv RxDirectDefByteTbit -> DoneCCC, WaitDirectRstart -> RxDirectDefByteTbit. Send a direct CCC with defining byte, then an extra data byte with bad T-bit parity before the repeated start for the target address.
ccc_direct_extra_data_before_addr¶
Test: ccc_direct_extra_data_before_addr
Coverage: ccc.sv WaitDirectRstart -> RxDirectDefByteTbit, RxDirectDefByteTbit -> WaitDirectRstart. Send a direct CCC with defining byte, then extra data bytes with good T-bit parity before the repeated start. Then complete the CCC normally.
ccc_te2_data_byte_direct_set¶
Test: ccc_te2_data_byte_direct_set
Coverage: RxDataTbit -> DoneCCC (ccc.sv:1104-1108). Send a direct SET CCC (SETMWL) and inject T-bit parity error on the first data byte after the target ACKs the address.
ccc_entdaa_te3_det_en_toggle¶
Test: ccc_entdaa_te3_det_en_toggle
Coverage: Toggle te3_err_det_en_i in ccc_entdaa. Inject TE3 (bad address parity during ENTDAA) with te3_err_det_en=0 then with te3_err_det_en=1.
ccc_entdaa_te4_det_en_disabled¶
Test: ccc_entdaa_te4_det_en_disabled
Coverage: TE4_ERR_DET_EN=0 path in ccc_entdaa. Inject TE4 (7E/W instead of 7E/R) with te4_err_det_en=0. Target should ACK the invalid reserved byte, TE4_ERR_STAT must remain 0, and the TE4 error counter must not increment.
ccc_stop_mid_transfer¶
Test: ccc_stop_mid_transfer
Coverage: Multiple FSM -> DoneCCC transitions via STOP override. Tests STOP during RxDefByte, RxDefByteOrBusCond, WaitDirectRstart, TxData, TxDataTbitCont, and TxDataTbitEnd states.
ccc_entdaa_stop_in_waitstart¶
Test: ccc_entdaa_stop_in_waitstart
Coverage: ENTDAA FSM WaitStart -> Done. Issue ENTDAA CCC byte, then STOP immediately before Sr+7E/R.
ccc_entdaa_stop_in_sendidbit¶
Test: ccc_entdaa_stop_in_sendidbit
Coverage: ENTDAA FSM SendIDBit -> Done. Start ENTDAA, let Sr+7E/R complete and begin ID bit transmission, then issue STOP mid-ID-bit.
ccc_entdaa_stop_in_receiveaddr¶
Test: ccc_entdaa_stop_in_receiveaddr
Coverage: ENTDAA FSM ReceiveAddr -> Done. Complete ID bit transmission (64 bits), then issue STOP mid-address-byte.
ccc_entdaa_stop_in_ackrsvdbyte¶
Test: ccc_entdaa_stop_in_ackrsvdbyte
Coverage: ENTDAA FSM AckRsvdByte -> Done. Issue STOP during the reserved byte ACK phase of ENTDAA.
ccc_entdaa_stop_in_sendnack¶
Test: ccc_entdaa_stop_in_sendnack
Coverage: ENTDAA FSM SendNack -> Done. Inject TE4 (7E/W instead of 7E/R) so target NACKs. ENTDAA FSM enters SendNack, then issue STOP.
ccc_stop_during_target_read¶
Test: ccc_stop_during_target_read
Coverage: TxData->DoneCCC, TxDataTbitCont->DoneCCC, TxDataTbitEnd->DoneCCC, TxTargetAddrAck->DoneCCC. Issues real bus-level STOP during target-driven read phases.
ccc_csr_concurrent_stress¶
Test: ccc_csr_concurrent_stress
Stress test: concurrent random FW (AXI) and I3C CCC accesses to CCC-affected CSRs. FW randomly reads/writes CCC-related CSRs via AXI in the background while I3C performs 50 random supported CCC operations (GET and SET). GET CCCs verify ACK; SET CCCs send random valid data. Goal: expose data races, coherency bugs, or FSM hangs under concurrent access from both interfaces.
entdaa¶
Perform the ENTDAA procedure, validate the addresses were assigned correctly.
entdaa_parity_errors¶
Perform the ENTDAA procedure, inject parity errors to offered addresses. Validate no address with a parity error was assigned. Disable parity checking and validate that addresses are assigned despite the error.
CSR access check¶
Testpoints¶
Test CSR accesses¶
Tests:
dat_csr_access- dct_csr_access- base_csr_access- pio_csr_access- ec_sec_fw_rec_csr_access- ec_stdby_ctrl_mode_csr_access- ec_tti_csr_access- ec_soc_mgmt_csr_access- ec_contrl_config_csr_access- ec_csr_access
Walk over all CSRs, write random value using AHB/AXI, read it back, and compare with expected output.
AXI burst read¶
Test: basic_burst_read
Tests if the CSRs can be correctly read using variously configured AXI burst read transactions.
At the beginning, the first 1KB of the register map is dumped in 4B chunks using the regular read_csr helper function which issues a single 4B AXI read for each chunk of data.
Then, for multiple possible combinations of arburst, arlen, arsize, arlock and aruser signal values a burst read is issued for a random starting address. Its response is then compared with values dumped at the beginning.
AXI burst write¶
Test: basic_burst_write
Tests if the CSRs can be correctly written to using variously configured AXI burst write transactions.
Firstly, the test data is prepared for each register in the map, taking into account properties of their fields. This results in a 1KB write data and expected readback buffers.
Then, for multiple possible combinations of awburst, awlen, awsize, awlock and awuser signal values a burst write is issued for a random starting address, with data supplied by the test write data buffer.
After confirming the transaction got an OKAY response, the same range of memory that had just been written to is then read back using the regular read_csr function and the obtained data is compared with the expected readback buffer.
AXI stall accesses¶
Tests:
Issue randomized read and write transactions, stall R and B channels for random time, release the bus and compare with expected output.
Empty queue read handling¶
Testpoints¶
normal_read_empty_rx_desc_queue¶
Test: normal_read_empty_rx_desc_queue
Read TTI RX_DESC_QUEUE_PORT when empty in normal mode. Must complete without hanging and return 0.
normal_read_empty_rx_data_port¶
Test: normal_read_empty_rx_data_port
Read TTI RX_DATA_PORT when empty in normal mode. Must complete without hanging and return 0.
normal_read_empty_indirect_fifo_data¶
Test: normal_read_empty_indirect_fifo_data
Read INDIRECT_FIFO_DATA when empty in normal mode. Must complete without hanging and return 0.
normal_read_empty_all_queues¶
Test: normal_read_empty_all_queues
Read all three empty FIFO ports in normal mode sequentially. Verifies no AXI bus deadlock from back-to-back external reads.
recovery_read_empty_rx_desc_queue¶
Test: recovery_read_empty_rx_desc_queue
Read TTI RX_DESC_QUEUE_PORT when empty in recovery mode. This is the scenario that caused the AXI deadlock bug: recovery_pending=1 caused R1MUX contention.
recovery_read_empty_rx_data_port¶
Test: recovery_read_empty_rx_data_port
Read TTI RX_DATA_PORT when empty in recovery mode. Must complete without hanging.
recovery_read_empty_indirect_fifo_data¶
Test: recovery_read_empty_indirect_fifo_data
Read INDIRECT_FIFO_DATA when empty in recovery mode. Must complete without hanging.
recovery_read_empty_all_queues¶
Test: recovery_read_empty_all_queues
Read all three empty FIFO ports in recovery mode sequentially. Verifies no AXI bus deadlock from back-to-back external reads while recovery_pending is asserted.
concurrent_recovery_xfer_and_rx_desc_read¶
Test: concurrent_recovery_xfer_and_rx_desc_read
While an I3C recovery read (PROT_CAP) is in-flight, which asserts recovery_pending, concurrently read TTI RX_DESC_QUEUE_PORT via AXI. This is the exact scenario that triggered the AXI deadlock bug.
concurrent_recovery_xfer_and_tx_desc_write¶
Test: concurrent_recovery_xfer_and_tx_desc_write
While an I3C recovery read (PROT_CAP) is in-flight, which asserts recovery_pending, concurrently write TTI TX_DESC_QUEUE_PORT via AXI.
concurrent_recovery_xfer_and_all_queue_access¶
Test: concurrent_recovery_xfer_and_all_queue_access
While an I3C recovery read (PROT_CAP) is in-flight, which asserts recovery_pending, concurrently access all TTI queue ports via AXI: read RX_DESC, read RX_DATA, write TX_DESC, and read INDIRECT_FIFO.
recovery_write_rx_data_observation¶
Test: recovery_write_rx_data_observation
Writes data to INDIRECT_FIFO_DATA on the virtual target via the recovery interface. In parallel, monitors the RTL signal tti_rx_depth to verify data flow observation.
Enter and exit HDR mode¶
Testpoints¶
Enter and exit HDR-DDR mode¶
Tests:
enter_exit_hdr_mode_write- enter_restart_exit_hdr_mode_write- enter_exit_hdr_mode_read- enter_restart_exit_hdr_mode_read
Issues ENTHDR0 CCC to the target, verifies that the target FSM is in IdleHDR state. Issues at least 1 read/write HDR-DDR command(s) followed by HDR exit pattern, verifies that the target FSM is back in Idle state.
HDR timeout disabled by default¶
Test: hdr_timeout_disabled_by_default
Verifies that the HDR timeout timer does not fire when the enable bit is 0 (default configuration).
HDR timeout configurable threshold¶
Test: hdr_timeout_configurable_threshold
Verifies that the HDR timeout timer fires at the configured threshold, not a hardcoded value.
HDR timeout resets on line low¶
Test: hdr_timeout_resets_on_line_low
Verifies that the HDR timeout timer resets when either SCL or SDA goes low.
HDR timeout does not fire for CCC HDR¶
Test: hdr_timeout_does_not_fire_for_ccc_hdr
Verifies that the HDR timeout timer does NOT fire during normal HDR mode entered via ENTHDR CCC.
HDR timeout recovery TE0¶
Test: hdr_timeout_recovery_te0
Verifies 60us timeout recovery after TE0 error (invalid reserved address). Timer triggers HDR exit and recovery.
HDR timeout recovery TE1¶
Test: hdr_timeout_recovery_te1
Verifies 60us timeout recovery after TE1 error (CCC parity error). Timer triggers HDR exit and recovery.
HDR exit pattern works alongside timer¶
Test: hdr_exit_pattern_works_alongside_timer
Verifies that the normal HDR Exit Pattern still works correctly when the HDR timeout timer is enabled.
cycle_all_hdr_modes¶
Test: cycle_all_hdr_modes
IBI handling¶
Testpoints¶
ibi_accept_read_all_data¶
Test: ibi_accept_read_all_data
Accept IBI, read all data bytes. Exercises MDB-only and various payload lengths. Verifies data integrity on controller side.
ibi_accept_partial_no_repeat¶
Test: ibi_accept_partial_no_repeat
Controller truncates additional IBI data bytes. Target shall NOT repeat the unserviced IBI per Sec 5.1.6.2 item 1.a.
ibi_refuse_no_retry_on_rstart¶
Test: ibi_refuse_no_retry_on_rstart
After NACK, target retries on Bus Available/Start but NOT on Repeated Start. Verifies WaitRestart->RxFByte transition (not RxFByteArb).
ibi_refuse_and_disable¶
Test: ibi_refuse_and_disable
Refuse IBI, then disable interrupts via DISEC CCC. Target must NOT retry until ENEC re-enables. NACKs the IBI followed by broadcast DISEC, then re-enables via ENEC.
ibi_accept_then_ccc¶
Test: ibi_accept_then_ccc
After accepting IBI and reading data, controller issues Sr->CCC. Verifies CCC executes correctly. Also verifies PENDING_INTERRUPT field behavior.
ibi_refuse_then_ccc¶
Test: ibi_refuse_then_ccc
After NACKing IBI, controller issues Sr->CCC. Target must NOT attempt IBI during the Sr->CCC frame. After STOP and bus available, target retries the IBI.
ibi_initiation_bus_available_vs_start¶
Test: ibi_initiation_bus_available_vs_start
Target initiates IBI via Bus Available Condition (1us) or during Bus Start within Bus Free (38.4ns). Verifies both initiation paths.
ibi_arbitration_dut_wins¶
Test: ibi_arbitration_dut_wins
Lower address equals higher priority. Verifies DUT can send IBI when configured with a lower address and wins arbitration.
ibi_arbitration_dut_loses_bus_available_wait¶
Test: ibi_arbitration_dut_loses_bus_available_wait
After losing arbitration (simulated via NACK), DUT sets ibi_inhibit and must wait for Bus Available (1us) before retrying. Controller issues transactions in between.
ibi_back_to_back¶
Test: ibi_back_to_back
Multiple IBIs issued sequentially. Verifies each is received correctly with proper status and interrupt behavior.
ibi_arb_loss_address¶
Test: ibi_arb_loss_address
DUT loses IBI arbitration to a lower-address peer during the address phase. RTL sets ibi_inhibit and DUT must NOT retry on the next Start, only after Bus Available.
ibi_arb_loss_rnw_bit¶
Test: ibi_arb_loss_rnw_bit
DUT tries IBI (addr+RnW=1) during a controller-initiated write to the same 7-bit address (addr+RnW=0). Address bits match on the bus; arbitration is lost on the RnW bit.
ibi_nack_sr_private_write¶
Test: ibi_nack_sr_private_write
Controller NACKs IBI then chains Sr followed by Private Write to the target within the same bus frame. Target must NOT attempt IBI on the chained Repeated Start.
ibi_nack_sr_directed_disec¶
Test: ibi_nack_sr_directed_disec
Controller NACKs IBI then chains Sr followed by Directed DISEC with DISINT to the target. Verifies IBI is disabled and target does not retry.
ibi_accept_no_mdb_stop¶
Test: ibi_accept_no_mdb_stop
Target always sends MDB (BCR[2]=1). Controller ACKs but sends STOP without reading MDB. Target should report a non-success IBI status since MDB was not consumed.
ibi_accept_no_mdb_sr_ccc¶
Test: ibi_accept_no_mdb_sr_ccc
Target always sends MDB (BCR[2]=1). Controller ACKs but sends Sr followed by CCC without reading MDB. Target should report a non-success IBI status since MDB was not consumed.
ibi_tbit_abort_sr_ccc¶
Test: ibi_tbit_abort_sr_ccc
Controller ACKs IBI, reads partial data (T-bit abort by stopping early), then chains Sr followed by CCC. Target should report IbiPartialData status.
ibi_queue_while_disabled_then_enable¶
Test: ibi_queue_while_disabled_then_enable
IBI data queued while IBI_EN=0 sits dormant in the descriptor pipeline until IBI_EN is set to 1. Verifies the IBI fires correctly after enabling.
ibi_retry_ctr_fw_reset¶
Test: ibi_retry_ctr_fw_reset
Verifies IBI_RETRY_CTR_RST singlepulse resets the retry counter mid-sequence. Without the FW reset, NACKs would exhaust the retry limit.
ibi_multiple_arb_losses¶
Test: ibi_multiple_arb_losses
Tests behavior after multiple IBI arbitration losses. Verifies correct retry and recovery behavior.
KNOWN ISSUE: IBI_QUEUE_RST only empties the FIFO; it does not reset descriptor_ibi state machine.
ibi_queued_during_hdr_fires_after_exit¶
Test: ibi_queued_during_hdr_fires_after_exit
Verifies IBI queued while DUT is in HDR mode fires correctly after the HDR exit pattern is detected and Bus Available occurs.
rxfbytearb_collision_blind_drive¶
Test: rxfbytearb_collision_blind_drive
RxFByteArb arb-loss on RnW bit with conforming controller. Per spec, address arbitration is open-drain: 0 is dominant. DUT enters RxFByteArb driving the IBI address and loses arbitration.
ibi_flush_from_idle_interrupt_flood¶
Test: ibi_flush_from_idle_interrupt_flood
Tests IBI queue flush from idle state with interrupt flooding.
KNOWN ISSUE: IBI_QUEUE_RST only empties the FIFO; it does not reset descriptor_ibi state machine.
ibi_multi_queue_nack_recovery¶
Test: ibi_multi_queue_nack_recovery
Pre-queues 3 IBIs into the TTI IBI FIFO, NACKs the first until retry exhaustion (retry_num=0), then FW resets the retry counter via IBI_RETRY_CTR_RST. The target retries the same IBI (still loaded in descriptor_ibi), controller accepts it and all subsequent IBIs drain in FIFO order. Verifies multi-IBI queuing, NACK retry exhaustion, FW-initiated retry counter reset, and IBI pipeline recovery.
ibi_multi_queue_partial_then_continue¶
Test: ibi_multi_queue_partial_then_continue
Pre-queues 3 IBIs, controller truncates the first IBI (partial read). descriptor_ibi flushes remaining data and auto-advances to the next queued IBI without FW intervention. Remaining IBIs are accepted with correct data. Verifies Flush -> Idle auto-advance path and that target does NOT repeat the partially-aborted IBI (Sec 5.1.6.2).
ibi_multi_queue_mixed_abort¶
Test: ibi_multi_queue_mixed_abort
Pre-queues 4 IBIs, exercises both abort types in sequence: IBI #0 is partially aborted (auto-advance via Flush), IBI #1 is accepted normally, IBI #2 is NACKed with retry exhaustion then recovered via FW retry counter reset, IBI #3 is accepted after auto-advancing from FIFO. Verifies interleaved partial-abort and NACK recovery paths in a single multi-IBI sequence.
ibi_rxfbytearb_wins_arbitration¶
Test: ibi_rxfbytearb_wins_arbitration
Coverage: i3c_target_fsm.sv RxFByteArb -> IbiReadAck. DUT has low address (0x10), wins IBI arbitration during a controller-initiated Start. FSM enters RxFByteArb and drives the IBI address, winning arbitration.
ibi_inhibit_retry_release¶
Test: ibi_inhibit_retry_release
Coverage: i3c_target_fsm.sv InhibitRetry -> InhibitNone transition. With retry_num=0, a single NACK exhausts retries. FW resets the retry counter to release inhibit. DUT retries and succeeds.
ibi_rxfbytearb_retry_exhausted¶
Test: ibi_rxfbytearb_retry_exhausted
Coverage: i3c_target_fsm.sv RxFByteArb -> RxFByte. Start with retry_num=7, NACK the DUT, then change retry_num=0 via CSR. Now ibi_can_retry is false, so RxFByteArb falls through to RxFByte.
ibi_arb_lost_in_drive_addr¶
Test: ibi_arb_lost_in_drive_addr
Coverage: i3c_target_fsm.sv IbiDriveAddr -> WaitRestart. DUT has a high address (0x60). It enters IbiDriveAddr via bus_available. A background task forces arbitration loss by driving SDA low, causing the FSM to transition to WaitRestart.
ibi_not_attempted_without_addr¶
Test: ibi_not_attempted_without_addr
Coverage: i3c_target_fsm.sv ibi_pending (cond). DUT is initialized with neither a static nor a dynamic address. An IBI is then pushed to the IBI queue and the test ensures that no action of sending the IBI is attempted by the DUT until it has a valid address assigned.
ibi_retry_count_limit¶
Test:
NACK all IBIs until count limit is reached
test_ibi_pending_read_notification¶
Test: ibi_pending_read_notification
test_ibi_refuse_retry¶
Test: ibi_refuse_retry
Target interrupts¶
Testpoints¶
rx_desc_stat¶
Test: rx_desc_stat
Enables RX_DESC_STAT TTI interrupt, checks if the irq_o signal is deasserted, sends a private write over I3C to the target and waits for irq_o assertion. Once the interrupt is asserted reads a RX descriptor from the TTI RX descriptor queue, ensures that irq_o gets deasserted after the read.
tx_desc_stat¶
Test: tx_desc_stat
Enables TX_DESC_STAT TTI interrupt, checks if the irq_o signal is deasserted, writes data to TTI TX data queue followed by writing a descriptor to TTI TX descriptor queue, sends a private read over I3C and waits for irq_o assertion. Once the interrupt is asserted clears it by writing 1 to the TX_DESC_STAT fields of TTI INTERRUPT_STATUS csr and ensures that irq_o signal gets deasserted.
ibi_done¶
Test: ibi_done
Enables IBI_DONE_EN TTI interrupt, checks if the irq_o signal is deasserted, and the status bit in TTI INTERRUPT_STATUS CSR cleared. Issues and IBI, waits for it to be serviced by the controller. Checks if the status bit is set in INTERRUPT_STATUS CSR and the irq_o signal asserted. Reads LAST_IBI_STATUS field from the TTI STATUS CSR, ensures that irq_o gets deasserted and status bit gets cleared afterwards.
interrupt_force¶
Test: interrupt_force
The test is run for each TTI interrupt:
TX_DESC_STAT_EN
RX_DESC_STAT_EN
RX_DESC_THLD_STAT_EN
RX_DATA_THLD_STAT_EN
IBI_DONE_EN
Ensures that irq_o is deasserted. Disables the interrupt in TTI INTERRUPT_ENABLE CSR, forces the interrupt by writing 1 to the corresponding field in TTI INTERRUPT_FORCE CSR, ensures that the irq_o does not get asserted.
Enables the interrupt in TTI INTERRUPT_ENABLE CSR, forces the interrupt by writing 1 to the corresponding field in TTI INTERRUPT_FORCE CSR, ensures that the irq_o does get asserted.
Clears the interrupt by writing 1 to its corresponding field in TTI INTERRUPT_STATUS CSR, ensures that irq_o gets deasserted and the status bit cleared.
rx_desc_overflow¶
Test: rx_desc_overflow
Checks if the tti_rx_desc_full signal gets asserted when there are enough unhandled private writes issued to overfill the RX descriptor FIFO.
Recovery mode tests¶
Testpoints¶
virtual_write¶
Test: virtual_write
Tests CSR write(s) through recovery protocol using the virtual target address. In the beginning sets the TTI and recovery addresses via two SETDASA CCCs.
Performs a write to DEVICE_RESET register via the recovery protocol targeting the virtual address. Reads the CSR content back through AHB/AXI, checks if the transfer was successful and the content read back matches. Then reads again the DEVICE_RESET register, this time via the recovery protocol. Check if the content matches.
Reads PENDING_INTERRUPT field from INTERRUPT_STATUS CSR via the GET_STATUS CCC command issued to the TTI I3C address. Verifies that the content read back matches what is set in the CSR.
Writes to the INDIRECT_FIFO_CTRL register using recovery protocol, reads content of the register via AHB/AXI and verifies that their content matches.
The test runs at core clock of 100 and 200 MHz. The slowest clock that does not result in a tSCO violation is 166 MHz. The I3C bus clock is set to 12.5 MHz.
virtual_overwrite¶
Test: virtual_overwrite
Tests CSR write(s) with lengths over CSR size to the virtual address using recovery protocol.
Performs a write to on of DEVICE_RESET/RECOVERY_CTRL/INDIRECT_FIFO_CTRL registers via the recovery protocol targeting the virtual address. Reads the CSR content back through AHB/AXI. Then reads again the selected register, this time via the recovery protocol. Check if the content matches value stored in the register.
virtual_write_alternating¶
Test: virtual_write_alternating
Sets the TTI and recovery addresses via two SETDASA CCCs.
Writes to DEVICE_RESET via recovery protocol targeting the virtual device address. Reads the register content through AHB/AXI and check if it matches with what has been written.
Sends a private write transfer to the TTI address. Reads the data back from TTI TX data queue and check that it matches.
Disables the recovery mode by writing 0x2 to DEVICE_STATUS register and repeats the previous steps to test whether the I3C core responds both to TTI and virtual addresses.
The test runs at core clock of 100 and 200 MHz. The slowest clock that does not result in a tSCO violation is 166 MHz. The I3C bus clock is set to 12.5 MHz.
read_fifo_ctrl¶
Test: read_fifo_ctrl
Sets the TTI and recovery addresses via two SETDASA CCCs.
Writes to DEVICE_RESET via recovery protocol targeting the virtual device address. Reads the register content through AHB/AXI and check if it matches with what has been written.
Writes to INDIRECT_FIFO_CTRL via recovery protocol targeting the virtual device address. Reads the register content via recovery protocol targeting the virtual device address and check if it matches with what has been written. Reads the register content through AHB/AXI and check if it matches with what has been written.
write¶
Test: write
Sets the TTI and recovery addresses via two SETDASA CCCs.
Performs a write to DEVICE_RESET register via the recovery protocol targeting the virtual address. Reads the CSR content back through AHB/AXI, checks if the transfer was successful and the content read back matches. Then reads again the DEVICE_RESET register, this time via the recovery protocol. Check if the content matches.
Writes to the INDIRECT_FIFO_CTRL register using recovery protocol, reads content of the register via AHB/AXI and verifies that their content matches.
The test runs at core clock of 100 and 200 MHz. The slowest clock that does not result in a tSCO violation is 166 MHz. The I3C bus clock is set to 12.5 MHz.
indirect_fifo_write¶
Test: indirect_fifo_write
Sets the TTI and recovery addresses via two SETDASA CCCs.
Retrieves indirect FIFO status and pointers by reading INDIRECT_FIFO_STATUS CSR over AHB/AXI bus. Writes data to the indirect FIFO through the recovery interface and retrieves status and pointers again. Reads the data from the FIFO back through AHB/AXI bus, retrieves FIFO pointers. Lastly clears the indirect FIFO by writing to INDIRECT_FIFO_CTRL through the recovery interface and obtains the pointers again.
After each FIFO status and pointer retrieval checks if both match the expected behavior.
The test runs at core clock of 100 and 200 MHz. The slowest clock that does not result in a tSCO violation is 166 MHz. The I3C bus clock is set to 12.5 MHz.
write_pec¶
Test: write_pec
Sets the TTI and recovery addresses via two SETDASA CCCs.
Writes some data to DEVICE_RESET register using the recovery interface. Then, repeats the write with different data but deliberately corrupts the recovery packet’s checksum (PEC). Finally, reads the content of DEVICE_RESET CSR over AHB/AXI and ensures that it matches with what was written in the first transfer. The test shall use random data length and value.
The test runs at core clock of 100 and 200 MHz. The slowest clock that does not result in a tSCO violation is 166 MHz. The I3C bus clock is set to 12.5 MHz.
read¶
Test: read
Sets the TTI and recovery addresses via two SETDASA CCCs.
Writes random data to the PROT_CAP recovery CSR via AHB/AXI. Disables the recovery mode, writes some data to TTI TX queues via AHB/AXI, enables the recovery mode and reads PROT_CAP using the recovery protocol. Checks if the content matches what was written in the beginning of the test.
The test runs at core clock of 100 and 200 MHz. The slowest clock that does not result in a tSCO violation is 166 MHz. The I3C bus clock is set to 12.5 MHz.
read_short¶
Test: read_short
Sets the TTI and recovery addresses via two SETDASA CCCs.
Writes random data to the PROT_CAP recovery CSR via AHB/AXI. Disables the recovery mode, writes some data to TTI TX queues via AHB/AXI, enables the recovery mode and reads PROT_CAP using the recovery protocol. The I3C read transfer is deliberately shorter - the recovery read is terminated by the I3C controller. Checks if the content read back matches what was written in the beginning of the test.
The test runs at core clock of 100 and 200 MHz. The slowest clock that does not result in a tSCO violation is 166 MHz. The I3C bus clock is set to 12.5 MHz.
read_long¶
Test: read_long
Sets the TTI and recovery addresses via two SETDASA CCCs.
Writes random data to the PROT_CAP recovery CSR via AHB/AXI. Disables the recovery mode, writes some data to TTI TX queues via AHB/AXI, enables the recovery mode and reads PROT_CAP using the recovery protocol. The I3C read transfer is deliberately longer - the recovery read is terminated by the I3C target. Checks if the content read back matches what was written in the beginning of the test.
The test runs at core clock of 100 and 200 MHz. The slowest clock that does not result in a tSCO violation is 166 MHz. The I3C bus clock is set to 12.5 MHz.
virtual_read¶
Test: virtual_read
Sets the TTI and recovery addresses via two SETDASA CCCs. Disables the recovery mode.
Issues a series of recovery read commands to all CSRs mentioned in the spec. The series is repeated twice - for recovery mode enabled and disabled. Each transfer is checked if the response is ACK or NACK and in case of ACK if PEC checksum is correct.
Checks if CSRs that should be available anytime (i.e. when the recovery mode is off) are always accessible, checks if other CSRs are accessible only in the recovery mode.
The test runs at core clock of 100 and 200 MHz. The slowest clock that does not result in a tSCO violation is 166 MHz. The I3C bus clock is set to 12.5 MHz.
virtual_read_alternating¶
Test: virtual_read_alternating
Alternates between recovery mode reads and TTI reads. Initially sets the TTI and recovery addresses via two SETDASA CCCs.
Writes random data to the PROT_CAP register over AHB/AXI, reads the register through the recovery protocol and check if the content matches.
Writes data and its descriptor to TTI TX queues, issues a private I3C read, verifies that the data read back matches.
Disables the recovery mode and repeats the recovery and TTI reads to ensure that both TTI and recovery transfers are possible regardless of the recovery mode setting.
The test runs at core clock of 100 and 200 MHz. The slowest clock that does not result in a tSCO violation is 166 MHz. The I3C bus clock is set to 12.5 MHz.
payload_available¶
Test: payload_available
Sets the TTI and recovery addresses via two SETDASA CCCs.
Ensures that initially the recovery_payload_available_o signal is deasserted. Then writes data to the indirect FIFO via the recovery interface and checks if the signal gets asserted.
Reads from INDIRECT_FIFO_DATA CSR over AHB/AXI and checks if the read causes the signal to be deasserted again.
The test runs at core clock of 100 and 200 MHz. The slowest clock that does not result in a tSCO violation is 166 MHz. The I3C bus clock is set to 12.5 MHz.
image_activated¶
Test: image_activated
Sets the TTI and recovery addresses via two SETDASA CCCs.
Ensures that initially the image_activated_o signal is deasserted. Writes 0xF to the 3rd byte of the RECOVERY_CTRL register using the recovery interface. Checks if the signal gets asserted. Then writes 0xFF to the same byte of the register and checks if the signal gets deasserted.
The test runs at core clock of 100 and 200 MHz. The slowest clock that does not result in a tSCO violation is 166 MHz. The I3C bus clock is set to 12.5 MHz.
indirect_fifo_reset_access¶
Test: indirect_fifo_reset_access
Sets the recovery address via SETDASA CCC.
Writes data to indirect FIFO and waits for the values to propagate through the core.
Resets indirect FIFO and writes new data to the indirect FIFO. Reads indirect FIFO and compares received data with one written after reset.
recovery_flow¶
Test: recovery_flow
The test exercises firmware image transfer flow using the recovery protocol. It consists of two agents running concurrently.
The AHB/AXI agent is responsible for recovery operation from the system bus side. It mimics operation of the recovery handling firmware.
The BFM agent issues I3C transactions and is responsible for pushing a firmware image to the target.
The test runs at core clock of 100 and 200 MHz. The slowest clock that does not result in a tSCO violation is 166 MHz. The I3C bus clock is set to 12.5 MHz.
ocp_csr_access¶
Test: ocp_csr_access
Sets the TTI and recovery addresses via two SETDASA CCCs.
Writes to DEVICE_RESET via recovery protocol targeting the virtual device address. Reads the register content through AHB/AXI and check if it matches with what has been written.
Writes to all remaining recovery CSRs using AHB/AXI, reads back their values and compares them.
ri_error_detection¶
Test: ri_error_detection
Tests Recovery Interface error detection, interrupt status, and counters. Validates RI_PEC_ERR (PEC/CRC error detection), RI_PROT_ERR (protocol error detection), and associated interrupt and counter behavior.
ri_comprehensive_stress¶
Test: ri_comprehensive_stress
Comprehensive Recovery Interface stress test covering PEC errors, T-bit parity errors, and protocol edge cases in rapid succession.
ri_error_injection_stress¶
Test: ri_error_injection_stress
Tests Recovery Interface resilience to various I3C framing errors and abnormal conditions including controller-side protocol violations and unexpected bus events.
ri_length_underrun¶
Test: ri_length_underrun
Tests that writing to INDIRECT_FIFO_DATA with RI length field 1 byte larger than actual data sent results in a length underrun error.
ri_mid_byte_stop¶
Test: ri_mid_byte_stop
Tests that issuing STOP mid-byte during different phases of the RI protocol is handled correctly. The device should detect the error and recover gracefully.
ri_read_interrupted_by_ccc¶
Test: ri_read_interrupted_by_ccc
Tests RI protocol error handling when the READ command’s read phase is interrupted by various bus conditions instead of the expected Sr + Addr+R sequence.
chained_ri_and_ccc_commands¶
Test: chained_ri_and_ccc_commands
Tests chaining of Recovery Interface commands, CCCs, and private writes within sequences using Sr. All RI/private transfers use Sr, only CCCs use broadcast address. Verifies correct interleaving.
indirect_fifo_large_write¶
Test: indirect_fifo_large_write
Tests writing more than 256 bytes to the INDIRECT_FIFO via I3C interface. The INDIRECT_FIFO has a fixed size (typically 256 bytes). Verifies correct handling of writes that exceed capacity.
indirect_fifo_two_writes_overflow¶
Test: indirect_fifo_two_writes_overflow
Tests two consecutive writes to the INDIRECT_FIFO that together exceed capacity. First write fits, second write overflows. Verifies correct handling of the overflow condition.
indirect_fifo_parity_error¶
Test: indirect_fifo_parity_error
Tests that T-bit (parity) errors during INDIRECT_FIFO_DATA write are handled correctly. Verifies parity errors on specific bytes are detected and reported.
indirect_fifo_overflow_pointer¶
Test: indirect_fifo_overflow_pointer
Tests that WRITE_INDEX does not increment when writing to a full INDIRECT_FIFO. Fills the hardware FIFO completely and verifies the pointer behavior on overflow.
write_exceeds_register_size¶
Test: write_exceeds_register_size
Tests behavior when writing more data than the register size allows. Attempts to write excess bytes to a recovery CSR and verifies correct handling.
private_read_and_ri_read¶
Test: private_read_and_ri_read
Verifies that a recovery interface PROT_CAP read and a standard private read from the TTI TX FIFO work correctly and do not interfere with each other.
parity_error_isolation¶
Test: parity_error_isolation
Verifies that parity/PEC errors on RI writes do not leak into the TTI interrupt path, and that T-bit errors on normal target writes do produce the expected TTI interrupts.
recovery_readonly_write_error¶
Test: recovery_readonly_write_error
Coverage: recovery_handler readonly_err=1, unsupported_err=0. Sends WRITE commands to read-only registers (PROT_CAP, DEVICE_ID, DEVICE_STATUS, HW_STATUS) and verifies PROT_ERROR=READONLY. Also tests readonly_err_det_en toggle for suppression.
recovery_read_write_phase_parity¶
Test: recovery_read_write_phase_parity
Coverage: RxLenH parity error on write-phase PEC. Sends a recovery READ command with a T-bit parity error on the PEC byte of the write phase. Recovery receiver detects error in RxLenH and transitions to Error.
recovery_write_pec_tbit_error¶
Test: recovery_write_pec_tbit_error
Coverage: RxPec parity error on descriptor. Sends a recovery WRITE command where the PEC byte has a T-bit parity error. Verifies the error is detected in RxPec state.
recovery_write_pec_overflow¶
Test: recovery_write_pec_overflow
Send a recovery WRITE command with more than one PEC bytes with length_err_det_en_i enabled and disabled.
recovery_all_det_en_toggle¶
Test: recovery_all_det_en_toggle
Coverage: Toggle all *_det_en_i signals. For each error detection enable bit in TARGET_ERR_CTRL: disable det_en and trigger error (verify not flagged), enable det_en and trigger error (verify flagged).
recovery_read_abort_at_len¶
Test: recovery_read_abort_at_len
Coverage: TxLenL/TxLenH bus_rstart_i -> Done. Aborts a recovery READ at different points in the response length transmission using command_read_abort.
recovery_premature_sr_in_header¶
Test: recovery_premature_sr_in_header
Coverage: Premature stop in RxCmd/RxLenL via bus_rstart_i. Sends partial recovery command headers with Sr at unexpected points during RxCmd and RxLenL states.
recovery_queue_resets¶
Test: recovery_queue_resets
Coverage: Toggle reg_rst_i, reg_rst_we_o, reg_rst_data_o on all queues. Exercises all RESET_CONTROL queue reset bits to toggle the reg_rst signals on every queue (IBI, RX desc, RX data, TX data).
recovery_hdr_mode_abort¶
Test: recovery_hdr_mode_abort
Coverage: in_hdr_mode_i override -> Error. Triggers TE0 error during an active recovery transaction to force in_hdr_mode_i=1 while the recovery FSM is in an active state. Recovers via HDR exit.
recovery_length_det_en_toggle¶
Test: recovery_length_det_en_toggle
Coverage: length error detection enable combinations. Tests length_err_det_en=0 (error suppressed), length_err_det_en=1 with underrun (error detected), and correct length (no error).
recovery_queue_thresholds¶
Test: recovery_queue_thresholds
Coverage: Toggle threshold input signals on all queues. Writes non-default values to QUEUE_THLD_CTRL and DATA_BUFFER_THLD_CTRL to toggle start_thrld_i and ready_thrld_i on all queues.
recovery_write_premature_stop_in_data¶
Test: recovery_write_premature_stop_in_data
Coverage: Premature stop in RxData and RxPec with length underrun. Sends a recovery WRITE with premature STOP during data or PEC phase, verifying correct error handling.
recovery_read_premature_start_in_pec¶
Test: recovery_read_premature_start_in_pec
Coverage: Premature Sr in TxPec. Sends a recovery read with premature Start during PEC phase.
recovery_indirect_fifo_overflow¶
Test: recovery_indirect_fifo_overflow
Coverage: Toggle indirect_fifo_overflow_err_det_en_i and rx_fifo_overflow_err_det_en_i. Writes more data to INDIRECT_FIFO_DATA than the FIFO can hold to trigger overflow, with det_en toggled.
recovery_ibi_queue_full¶
Test: recovery_ibi_queue_full
Coverage: Toggle ibi_queue.full_o. Fills the IBI queue (depth=64) by writing MDB-only IBI descriptors without triggering IBI acceptance. Verifies queue fills and device remains functional after reset.
recovery_bypass_fifo_done¶
Test: recovery_bypass_fifo_done
Coverage: Bypass path to Done in ExecFifoWrite. Enables bypass mode, writes data to INDIRECT_FIFO via recovery interface, then asserts REC_PAYLOAD_DONE to trigger the bypass exit path from ExecFifoWrite.
recovery_hdr_abort_per_state¶
Test: recovery_hdr_abort_per_state
Coverage: in_hdr_mode_i Error from ExecCsrWrite, TxData, TxLenH, TxLenL, TxPec. Uses TE0 injection to force the recovery FSM into Error from specific Tx states during READ responses.
recovery_read_abort_txlenl¶
Test: recovery_read_abort_txlenl
Coverage: TxLenL bus_rstart_i -> Done. Sends Sr immediately after the read address ACK, before the target finishes transmitting the LEN_L byte.
recovery_bypass_fifo_race¶
Test: recovery_bypass_fifo_race
Coverage: Bypass ExecFifoWrite -> Done. Enables bypass mode, sends a large INDIRECT_FIFO_DATA write via I3C, then races to set REC_PAYLOAD_DONE via CSR before the normal dcnt path completes.
recovery_readonly_write_irq¶
Test: recovery_readonly_write_irq
Verifies that writing to a read-only recovery register triggers the RI_READONLY_ERR interrupt output (irq_o toggle 0->1->0).
recovery_unsupported_cmd_irq¶
Test: recovery_unsupported_cmd_irq
Verifies that sending an unsupported command code triggers the RI_UNSUPPORTED_ERR interrupt output (irq_o toggle 0->1->0).
recovery_tx_pec_csr_data_race¶
Test: recovery_tx_pec_csr_data_race
PEC coherency under concurrent FW CSR writes. FW toggles RECOVERY_STATUS every few clocks in the background while the controller performs reads of the same register via I3C. Verifies that PEC is always correct despite concurrent AXI writes, proving csr_data snapshot integrity. Spec ref: OCP Recovery v1.1 Section 8.4.
recovery_ri_csr_concurrent_stress¶
Test: recovery_ri_csr_concurrent_stress
Stress test: concurrent random FW (AXI) and I3C accesses to recovery interface CSRs. FW randomly reads/writes RI CSRs via AXI in the background while I3C performs random read/write operations via the recovery protocol. Every I3C read checks PEC, data length, and NACK status. Exposes data races, coherency bugs, or FSM hangs under concurrent access.
Recovery bypass¶
Testpoints¶
simple_write_read¶
Test: indirect_fifo_write
Verify basic bypass functionality
Enable I3C Core bypass in the Recovery Handler via CSR
Write to the TTI TX Data Queue and read from the Indirect FIFO Queue
Compare the data and verify it hasn’t changed
check_csr_access¶
Tests:
ocp_csr_access_bypass_enabled- ocp_csr_access_bypass_disabled
Verify accessibility of CSRs as specified in the OCP Secure Firmware Recovery specification with additional bypass features
Write to all RW and read from all RO Secure Firmware Recovery Registers
Write to bypass registers with W1C property
Ensure the reserved fields of tested registers were not written
Ensure RW registers can be written and read back
Ensure RO registers cannot be written
Perform checks with bypass disabled and enabled
recovery_status_wires¶
Tests:
payload_available- image_activated
Verify recovery status wires as specified in the Caliptra SS Hardware Specification
Write to the TTI TX Queue and read from the Indirect FIFO Queue.
Ensure correct state of the
payload_availablewireWrite to the Recovery Control CSR to activate an image
Ensure correct state of the
image_activatedwire
indirect_fifo_overflow¶
Test: indirect_fifo_overflow
Verify that access is rejected when the Indirect FIFO Queue overflows
indirect_fifo_underflow¶
Test: indirect_fifo_underflow
Verify that access is rejected when the Indirect FIFO Queue underflows
i3c_bus_traffic_during_loopback¶
Test: i3c_bus_traffic_during_loopback
Verify that the Recovery Handler with bypass enabled is not in any way interfered by any I3C bus traffic
check_axi_filtering¶
Test: axi_filtering
Verify that AXI access to Secure Firmware Recovery registers is filtered
AXI IDs from the privileged ID list should always grant access to all registers
Once ID filtering is disabled, register access should be granted regardless of the transaction ID
With ID filtering enabled, all transactions with ID outside of the privileged ID list should be rejected with SLVERR response and register access request should not be propagated to the CPUIF
bypass_read¶
Test: read
Verify basic read functionality through recovery bypass
Enable I3C Core bypass in the Recovery Handler via CSR
Read from a recovery CSR via the bypass path
Verify data integrity
cptra_mcu_recovery¶
Test: recovery_flow
Verify that Caliptra Subsystem can perform a full Recovery Sequence with the I3C Core with the bypass feature enabled. This test will run software on both Caliptra core and Caliptra MCU to interact with the I3C Core and Caliptra RoT.
MCU should initialize the I3C Core with bypass enabled
Caliptra ROM should enable Recovery Mode
MCU should load the image to the Indirect FIFO Queue which will be read by Caliptra ROM
MCU should activate the image
Caliptra ROM should write the image to the MCU SRAM
The image should be identical with the one read form a simulated QSPI
bypass_to_i3c_switch¶
Test: bypass_to_normal_mode_switch
Boot the core in bypass mode and perform AXI recovery flow. During AXI recovery send random I3C traffic and assert all I3C packets are NACKed. Switch to I3C mode and send regular I3C traffic, make sure it is handled correctly. The test should cover corner cases where the switch happens in the middle of an I3C transaction.
target_peripheral_reset¶
Testpoints¶
target_peripheral_reset¶
Test: target_peripheral_reset
Issues I3C target reset pattern and verifies successful peripheral reset.
target_escalated_reset¶
Test: target_escalated_reset
Issues I3C target reset patterns and verifies successful reset escalation.
reset_at_min_timing¶
Test: reset_at_min_timing
Valid reset at exact spec minimum timing (tDIG_H = 140ns). Tests the target reset detector when the bus operates at the minimum timing thresholds specified in the I3C specification.
13_transitions_fails¶
Test: 13_transitions_fails
Only 13 SDA transitions should NOT trigger reset. The spec requires exactly 14 SDA transitions. With only 13, the FSM should remain in AwaitPattern and not trigger a reset.
15_transitions_before_scl¶
Test: 15_transitions_before_scl
15 SDA transitions before SCL rise should NOT trigger reset. Extra transitions beyond 14 while SCL is still low should prevent the pattern from being recognized.
scl_glitch_during_pattern¶
Test: scl_glitch_during_pattern
SCL goes high briefly during SDA transitions. When SCL goes stable high during the 14 SDA transitions, the transition counter should reset and pattern recognition should fail.
scl_glitch_during_pattern_final_edge¶
Test: scl_glitch_during_pattern_final_edge
SCL goes high together with the 14th SDA transition. This way, the reset detector FSM should already move to the AwaitSCL state, but then immediately detect SCL being stable high due to the posedge occuring too early, which should reset it to the default state and pattern recognition should fail.
sda_stable_low_during_await_scl¶
Test: sda_stable_low_during_await_scl
SDA goes stable low while waiting for SCL rise. In AwaitSCL state, if SDA becomes stable low, FSM should abort back to AwaitPattern.
scl_drops_during_await_sr¶
Test: scl_drops_during_await_sr
SCL goes low before START condition detected. In AwaitSr state, if SCL becomes stable low before START is detected, FSM should abort back to AwaitPattern.
scl_drops_during_await_p¶
Test: scl_drops_during_await_p
SCL goes low before STOP condition detected. In AwaitP state, if SCL becomes stable low before STOP is detected, FSM should abort back to AwaitPattern.
back_to_back_resets¶
Test: back_to_back_resets
Multiple valid resets in succession. Verifies that the FSM returns cleanly to initial state after reset and can detect subsequent reset patterns.
reset_after_failed_pattern¶
Test: reset_after_failed_pattern
Verifies FSM recovers after a failed pattern and can detect subsequent valid reset patterns.
first_edge_must_be_falling¶
Test: first_edge_must_be_falling
Pattern counting starts on negative edge. Per FSM logic, the first counted transition must be a falling edge. Starting with a rising edge should not be counted.
timing_at_2x_minimum¶
Test: timing_at_2x_minimum
Verifies reset detection works at 2x minimum timing (more relaxed timing). Serves as a sanity check that the detector is not too strict.
very_fast_timing_below_spec¶
Test: very_fast_timing_below_spec
Test with timing faster than spec minimum (aggressive timing). Tests if the detector can keep up with fast transitions.
mixed_valid_and_invalid_patterns¶
Test: mixed_valid_and_invalid_patterns
Sends a mix of valid and invalid patterns to stress the FSM transitions and verify correct behavior under varied conditions.
Target error detection¶
Testpoints¶
te0_errors¶
Test: te0_errors
TE0 error: reserved broadcast address triggers HDR error mode and recovery. Tests all 8 reserved address patterns, both recovery methods (HDR exit and timeout). Ensures that CSR with error counter does not overflow.
te1_errors¶
Test: te1_errors
TE1 error: CCC parity error triggers HDR error mode and recovery. Tests various broadcast CCCs with bad T-bit parity, both recovery methods, and ENTHDR0-specific behavior. Ensures that CSR with error counter does not overflow.
te2_private_write_parity¶
Test: te2_private_write_parity
TE2 error: bad T-bit parity on private write data causes data to be discarded. Verifies RX FIFO is empty after parity error, error registers update, and target recovers for subsequent transfers. Ensures that CSR with error counter does not overflow.
te_error_registers_sweep¶
Test: te_error_registers_sweep
Register infrastructure test: FORCE->STATUS, W1C, counter saturation, ENABLE gating, and multi-bit FORCE. No bus traffic – pure register verification of the error detection infrastructure.
controller_abort_scenarios¶
Test: controller_abort_scenarios
Controller abort during private write/read at random positions. Verifies the target remains functional after aborted transactions.
te_error_sequence_mixing¶
Test: te_error_sequence_mixing
Cross-coverage: inject TE0, TE1, TE2 in random order with recovery. Verifies that each error type is correctly detected and only the corresponding status/counter is updated.
te_error_ri_isolation¶
Test: te_error_ri_isolation
Verifies TE errors do not corrupt RI path and vice versa. Phase 1: TE0 error -> recover -> verify normal TTI traffic works. Phase 2: Normal traffic after RI transfer -> verify no TE errors.
te_counter_per_event¶
Test: te_counter_per_event
Verifies TE0/TE1 error counters increment exactly once per single error event. TE0 fires once per corrupted address header. TE1 fires once per CCC byte with bad parity.
te0_during_ccc_repeated_start¶
Test: te0_during_ccc_repeated_start
Coverage: i3c_target_fsm.sv in_hdr_mode_i override from CheckSByte. Trigger TE0 from RxSByteRepeated state via S+7E/W -> ACK -> Sr -> 7E/R. FSM enters CheckSByte then transitions to InHDRMode via in_hdr_mode_i override. Recovers via HDR timeout.
ri_interrupt_force_all¶
Test: ri_interrupt_force_all
Tests interrupt FORCE mechanism for all RI error interrupt instances. For each RI error type (readonly, unsupported, rx_fifo_overflow, indirect_fifo_overflow): disable interrupt and force (verify no effect), enable and force (verify status set and irq_o high), clear and verify irq_o low.
ri_rx_fifo_overflow_irq¶
Test: ri_rx_fifo_overflow_irq
Verifies that RX FIFO overflow triggers the RI_RX_FIFO_OVERFLOW_ERR interrupt output (irq_o toggle 0->1->0) when both DET_EN and INTR_EN are enabled.
ri_indirect_fifo_overflow_irq¶
Test: ri_indirect_fifo_overflow_irq
Verifies that INDIRECT FIFO overflow triggers the RI_INDIRECT_FIFO_OVERFLOW_ERR interrupt output (irq_o toggle 0->1->0) when both DET_EN and INTR_EN are enabled.
error_counters_saturation¶
Tests:
te5_counter_saturation- framing_counter_saturation- ri_pec_counter_saturation- ri_length_counter_saturation- ri_readonly_counter_saturation- ri_unsupported_counter_saturation- ri_rx_fifo_overflow_counter_saturation- ri_indirect_fifo_overflow_counter_saturation
Writes 0xFE to error counter, triggers errors and ensures that the counter increments without overflowing. The tests cover counters for:
TE5
FRAMING
RI_PEC
RI_LENGTH
RI_READONLY
RI_UNSUPPORTED
RI_RX_FIFO_OVERFLOW
RI_INDIRECT_FIFO_OVERFLOW
tSCO timing verification¶
Testpoints¶
tsco_write_ack_handoff¶
Test: tsco_write_ack_handoff
PROSECUTOR TEST: Verifies tSCO timing on write-ACK handoff. Per I3C spec S5.1.2.3.1 step 2 and Table 87, after the target sees the rising edge of SCL during ACK, it shall release SDA to Hi-Z within tSCO (max 12ns). Sends a private write and measures tSCO on the ACK handoff.
tsco_setdasa_virtual_target¶
Test: tsco_setdasa_virtual_target
PROSECUTOR TEST: Verifies tSCO timing on SETDASA to virtual target. The bus monitor has detected a tSCO violation specifically during SETDASA directed to the virtual target address. Measures tSCO during that specific transaction.
Compliance test suite¶
The list of non-public tests which utilize Avery I3C VIP framework and have been successfully ran against the design is available in the CTS list.