[top-i2c,dv] Added chip level I2C Device TX_RX test#633
Conversation
dafa77b to
c434d75
Compare
fbf55a9 to
13af90e
Compare
d5e3010 to
74cf3b0
Compare
74cf3b0 to
0646a31
Compare
engdoreis
left a comment
There was a problem hiding this comment.
I left a suggestion, otherwise it LGTM.
| VOLATILE_WRITE(i2c->txdata, txdata); | ||
| } | ||
|
|
||
| void i2c_clear_cmd_complete(i2c_t i2c) |
There was a problem hiding this comment.
I suggest making a function to clear interrupts that take the interrupt as argument like uart:
mocha/sw/device/lib/hal/uart.c
Line 36 in 3b3b9e2
There was a problem hiding this comment.
Do you mean something like that:
void i2c_clear_intr_state(i2c_t i2c, uint32_t state)
{
VOLATILE_WRITE(i2c->intr_state, state);
}
There was a problem hiding this comment.
Yes, but 'state' would be an enum with the interrupts. It should also accept more then one interrupt per call.
There was a problem hiding this comment.
For this test, I only wanted to clear cmd_complete field of intr_state register. I am not checking / enabling interrupts for smoke tests. But your suggestion is good and I'll do it as part of a separate PR. Thanks!
3e897ea to
eb7d381
Compare
| @@ -37,23 +69,42 @@ function int unsigned top_chip_dv_i2c_tx_rx_vseq::round_up_divide(int unsigned a | |||
| endfunction | |||
|
|
|||
| function void top_chip_dv_i2c_tx_rx_vseq::configure_agent_timing(); | |||
There was a problem hiding this comment.
I think these changes also have an impact on top_chip_dv_i2c_host_tx_rx_vseq. Isn't it an issue?
There was a problem hiding this comment.
I don't think that host_tx_rx_test gets affected. I've took these calculations from i2c_base_vseq function get_timing_values(). They look sensible to reason.
There was a problem hiding this comment.
Oh, sorry. I think I didn't answer this question well. These parameters are used to add delays which should depend on the speed of the I2C bus and not on host / device part. So, whatever the speed is just calculate the timing parameter the same way
There was a problem hiding this comment.
Sorry, I was unclear. The issue I see is that you've created the dut_init task for top_chip_dv_i2c_device_tx_rx_vseq to read some SW symbols and then use them in this configure_agent_timing function, all fine here. But in your implementation of top_chip_dv_i2c_host_tx_rx_vseq::dut_init() should also backdoor read these missing SW symbols.
This also needs to be added in host_tx_rx_test.c as done in device_tx_rx_test.c or in a common shared file?
Something like:
const uint16_t scl_high_time_ns = 4000;
const uint16_t setup_data_time_ns = 250;
const uint16_t setup_start_time_ns = 4700;
const uint16_t hold_start_time_ns = 4000;
const uint16_t setup_stop_time_ns = 4000;
const uint16_t bus_free_time_ns = 4700;
const uint16_t rise_time_ns = I2C_RISE_NS;
const uint16_t fall_time_ns = I2C_FALL_NS;There was a problem hiding this comment.
No, they are not useful for the host test. For host test, the TB is the device responsible for sending responses (rdata, ack, and nack). This is the function i2c_driver.sv#L50 called by the driver where only device_send_bit(_) is used deep down in i2c_if that majorly uses tClockPulse, tClockLow, and tHoldBit. other parameters like tSdaUnstable and tTimeOut are not neccessary for smoke test
There was a problem hiding this comment.
I've added comments here: changes#diff-e7f07ab57afcc3afbc109eaf390fe9db01a5e5372a8e20b41ccb00e04c9ef14eR37-R51 explaining the we oinly need subset of timing parameters for host test
There was a problem hiding this comment.
Traced through calc_timing_params_in_cycles() for the host path and I don't think "the remaining parameters default to 0" holds up. round_up_divide(a, b) is ((a - 1) / b) + 1, with a/b as int unsigned. For every parameter host_tx_rx doesn't backdoor-read (scl_high, setup_data, setup_start, hold_start, setup_stop, bus_free, rise, fall), the backing sw_*_time_ns array is never written, so a = 0 when round_up_divide runs. 0 - 1 in unsigned 32-bit arithmetic wraps to 4294967295, not -1, so the result isn't 0 — it's floor(4294967295 / clk_period) + 1 truncated into a 16-bit field. For a 5ns clock period that's 858993460, which truncates to 13108 cycles, not 0. So 8 of the 10 *_cycles fields end up with a clock-period-dependent garbage value, and nearly every field configure_agent_timing() computes (tSetupBit, tClockPulse, tClockLow, tSetupStop, tHoldStop) mixes in at least one of them.
I'd rather we set these explicitly for the host test the same way device_tx_rx_test.c does, rather than leaning on round_up_divide to return 0 for an input it was never written to handle — that keeps both vseqs symmetric and doesn't depend on an accident of integer wraparound working out. Could you add the same 8 consts to host_tx_rx_test.c and the corresponding backdoor reads to top_chip_dv_i2c_host_tx_rx_vseq::dut_init(), same as the device vseq?
There was a problem hiding this comment.
Oh yes, thanks for figuring this out. My intention is just to add stuff that is required for the vseq / test. I can add all the timing parameters in host_tx_rx_test.x but it is not going to be consumed by the i2c_driver when it is driving the device interface. I can go ahead and revert it back to manually calculating scl_low_cycles and scl_hold_cycles. WDYT?
There was a problem hiding this comment.
Reverting fixes the underflow, but tClockPulse/tSetupBit still end up 0 either way, and tClockPulse is one of the three you called essential. Rather than reason about it further, could you run i2c_host_tx_rx and paste the print_i2c_timing_cfg() output here? If it passes cleanly with tClockPulse/tSetupBit at 0, I'll drop this. If not, let's just add the explicit consts to host_tx_rx_test.c instead.
There was a problem hiding this comment.
but tClockPulse/tSetupBit still end up 0 either way, and tClockPulse is one of the three you called essential.
Oh yes, you are right. Sorry, I am a bit slow today. I'll re-think about it again. Thanks for your careful analysis
9c8cb36 to
eddbdd0
Compare
f4fb13a to
3a94487
Compare
3a94487 to
ca5122a
Compare
A reviewer on lowRISC#633 commented about inconsistency in the naming of tBUF timing parameter accross different places. That made me look at the name of the bus_free_time_cycles field in the i2c_timing_params_t struct and I realized that it is also inconsistent. Signed-off-by: Kinza Qamar <kqzaman@lowrisc.org>
A reviewer on lowRISC#633 commented about inconsistency in the naming of tBUF timing parameter accross different places. That made me look at the name of the bus_free_time_cycles field in the i2c_timing_params_t struct and I realized that it is also inconsistent. Signed-off-by: Kinza Qamar <kqzaman@lowrisc.org>
f048803 to
62ae5e7
Compare
| @@ -37,23 +69,42 @@ function int unsigned top_chip_dv_i2c_tx_rx_vseq::round_up_divide(int unsigned a | |||
| endfunction | |||
|
|
|||
| function void top_chip_dv_i2c_tx_rx_vseq::configure_agent_timing(); | |||
There was a problem hiding this comment.
Sorry, I was unclear. The issue I see is that you've created the dut_init task for top_chip_dv_i2c_device_tx_rx_vseq to read some SW symbols and then use them in this configure_agent_timing function, all fine here. But in your implementation of top_chip_dv_i2c_host_tx_rx_vseq::dut_init() should also backdoor read these missing SW symbols.
This also needs to be added in host_tx_rx_test.c as done in device_tx_rx_test.c or in a common shared file?
Something like:
const uint16_t scl_high_time_ns = 4000;
const uint16_t setup_data_time_ns = 250;
const uint16_t setup_start_time_ns = 4700;
const uint16_t hold_start_time_ns = 4000;
const uint16_t setup_stop_time_ns = 4000;
const uint16_t bus_free_time_ns = 4700;
const uint16_t rise_time_ns = I2C_RISE_NS;
const uint16_t fall_time_ns = I2C_FALL_NS;A reviewer on lowRISC#633 commented about inconsistency in the naming of tBUF timing parameter accross different places. That made me look at the name of the bus_free_time_cycles field in the i2c_timing_params_t struct and I realized that it is also inconsistent. Signed-off-by: Kinza Qamar <kqzaman@lowrisc.org>
…vice Signed-off-by: Kinza Qamar <kqzaman@lowrisc.org>
Signed-off-by: Kinza Qamar <kqzaman@lowrisc.org>
62ae5e7 to
de25817
Compare
Signed-off-by: Kinza Qamar <kqzaman@lowrisc.org>
de25817 to
1e22416
Compare
| class top_chip_dv_i2c_device_tx_rx_vseq extends top_chip_dv_i2c_tx_rx_vseq; | ||
| `uvm_object_utils(top_chip_dv_i2c_device_tx_rx_vseq) | ||
|
|
||
| // TODO: Remove once #600 is merged. This is maintained by SW to make this Vseq in sync |
There was a problem hiding this comment.
This PR #600 has been merged now. Could you rebase and remove this workaround?
|
|
||
| // Wait until SW is done writing to the TX FIFO | ||
| // | ||
| // TODO: Remove when #600 is merged |
A reviewer on lowRISC#633 commented about inconsistency in the naming of tBUF timing parameter accross different places. That made me look at the name of the bus_free_time_cycles field in the i2c_timing_params_t struct and I realized that it is also inconsistent. Signed-off-by: Kinza Qamar <kqzaman@lowrisc.org>
Added a host Vseq and device SW. The host will initiate read / write transfer. The device SW waits for the transfers to finish and compare the data bytes in each transfer at the end