Skip to content

Commit

Permalink
Merge pull request #105 from shuchitak/feature/fix_tests
Browse files Browse the repository at this point in the history
Modify backpressure test to something sensible
  • Loading branch information
shuchitak authored Mar 7, 2024
2 parents 71db570 + 99c48de commit 94a1dca
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 51 deletions.
24 changes: 0 additions & 24 deletions test/build_lib_i2s_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,6 @@ source ${FRAMEWORK_IO_ROOT}/tools/ci/helper_functions.sh

# row format is: "make_target BOARD toolchain"
declare -a applications=(
"test_hil_backpressure_test_32_768000_4_5_5"
"test_hil_backpressure_test_32_768000_4_0_10"
"test_hil_backpressure_test_32_768000_4_10_0"
"test_hil_backpressure_test_32_768000_3_5_5"
"test_hil_backpressure_test_32_768000_3_0_10"
"test_hil_backpressure_test_32_768000_3_10_0"
"test_hil_backpressure_test_32_768000_2_5_5"
"test_hil_backpressure_test_32_768000_2_0_10"
"test_hil_backpressure_test_32_768000_2_10_0"
"test_hil_backpressure_test_32_768000_1_5_5"
"test_hil_backpressure_test_32_768000_1_0_10"
"test_hil_backpressure_test_32_768000_1_10_0"
"test_hil_backpressure_test_32_384000_4_5_5"
"test_hil_backpressure_test_32_384000_4_0_10"
"test_hil_backpressure_test_32_384000_4_10_0"
Expand Down Expand Up @@ -81,18 +69,6 @@ declare -a applications=(
"test_hil_i2s_slave_test_32_1_4_0_inv"
"test_hil_i2s_slave_test_32_1_0_4_inv"
"test_hil_i2s_slave_test_32_1_2_2_inv"
"test_hil_backpressure_test_16_768000_4_5_5"
"test_hil_backpressure_test_16_768000_4_0_10"
"test_hil_backpressure_test_16_768000_4_10_0"
"test_hil_backpressure_test_16_768000_3_5_5"
"test_hil_backpressure_test_16_768000_3_0_10"
"test_hil_backpressure_test_16_768000_3_10_0"
"test_hil_backpressure_test_16_768000_2_5_5"
"test_hil_backpressure_test_16_768000_2_0_10"
"test_hil_backpressure_test_16_768000_2_10_0"
"test_hil_backpressure_test_16_768000_1_5_5"
"test_hil_backpressure_test_16_768000_1_0_10"
"test_hil_backpressure_test_16_768000_1_10_0"
"test_hil_backpressure_test_16_384000_4_5_5"
"test_hil_backpressure_test_16_384000_4_0_10"
"test_hil_backpressure_test_16_384000_4_10_0"
Expand Down
2 changes: 1 addition & 1 deletion test/lib_i2s/backpressure_test/backpressure_test.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ set(APP_LINK_OPTIONS
# Tile Targets
#**********************
if(NOT DEFINED ENV{SAMPLE_RATES})
set(SAMPLE_RATES 768000 384000 192000)
set(SAMPLE_RATES 384000 192000)
else()
set(SAMPLE_RATES $ENV{SAMPLE_RATES})
endif()
Expand Down
179 changes: 157 additions & 22 deletions test/lib_i2s/backpressure_test/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#define BURN_THREADS 6
#endif
#ifndef SAMPLE_FREQUENCY
#define SAMPLE_FREQUENCY 768000
#define SAMPLE_FREQUENCY 192000
#endif
#ifndef TEST_LEN
#define TEST_LEN 1000
Expand Down Expand Up @@ -44,6 +44,127 @@

#define SETSR(c) asm volatile("setsr %0" : : "n"(c));

enum {
SAMPLE_RATE_192000,
SAMPLE_RATE_384000,
NUM_SAMPLE_RATES
}e_sample_rates;

enum {
BITDEPTH_16,
BITDEPTH_32,
NUM_BIT_DEPTHS
}e_bit_depth;

enum {
NUM_I2S_LINES_1,
NUM_I2S_LINES_2,
NUM_I2S_LINES_3,
NUM_I2S_LINES_4,
}e_channel_config;

static int acceptable_receive_delay = 0, acceptable_send_delay = 0;
static int acceptable_delay_ticks[NUM_SAMPLE_RATES][NUM_I2S_LINES_4+1][NUM_BIT_DEPTHS];

static inline void populate_acceptable_delay_ticks()
{
// These numbers are logged by running the test and logging the delay at the last passing iteration
// before the backpressure test starts failing. So, on top of the bare minimum code in the i2s_send()
// and i2s_receive() functions in this file plus their calling overheads, we have acceptable_delay_ticks number
// of cycles per send and receive callback function call to add any extra processing.

// 192 KHz
acceptable_delay_ticks[SAMPLE_RATE_192000][NUM_I2S_LINES_1][BITDEPTH_16] = 170;
acceptable_delay_ticks[SAMPLE_RATE_192000][NUM_I2S_LINES_1][BITDEPTH_32] = 185;
acceptable_delay_ticks[SAMPLE_RATE_192000][NUM_I2S_LINES_2][BITDEPTH_16] = 140;
acceptable_delay_ticks[SAMPLE_RATE_192000][NUM_I2S_LINES_2][BITDEPTH_32] = 155;
acceptable_delay_ticks[SAMPLE_RATE_192000][NUM_I2S_LINES_3][BITDEPTH_16] = 105;
acceptable_delay_ticks[SAMPLE_RATE_192000][NUM_I2S_LINES_3][BITDEPTH_32] = 125;
acceptable_delay_ticks[SAMPLE_RATE_192000][NUM_I2S_LINES_4][BITDEPTH_16] = 70;
acceptable_delay_ticks[SAMPLE_RATE_192000][NUM_I2S_LINES_4][BITDEPTH_32] = 90;

// 384 KHz
acceptable_delay_ticks[SAMPLE_RATE_384000][NUM_I2S_LINES_1][BITDEPTH_16] = 50;
acceptable_delay_ticks[SAMPLE_RATE_384000][NUM_I2S_LINES_1][BITDEPTH_32] = 55;
acceptable_delay_ticks[SAMPLE_RATE_384000][NUM_I2S_LINES_2][BITDEPTH_16] = 15;
acceptable_delay_ticks[SAMPLE_RATE_384000][NUM_I2S_LINES_2][BITDEPTH_32] = 25;
// For 384 KHz, we have non-zero backpressure only up to 2 channels
acceptable_delay_ticks[SAMPLE_RATE_384000][NUM_I2S_LINES_3][BITDEPTH_16] = 0;
acceptable_delay_ticks[SAMPLE_RATE_384000][NUM_I2S_LINES_3][BITDEPTH_32] = 0;
acceptable_delay_ticks[SAMPLE_RATE_384000][NUM_I2S_LINES_4][BITDEPTH_16] = 0;
acceptable_delay_ticks[SAMPLE_RATE_384000][NUM_I2S_LINES_4][BITDEPTH_32] = 0;
}

void get_acceptable_delay()
{
int sample_rate;
if(SAMPLE_FREQUENCY == 192000)
{
sample_rate = SAMPLE_RATE_192000;
}
else if(SAMPLE_FREQUENCY == 384000)
{
sample_rate = SAMPLE_RATE_384000;
}
else
{
printf("ERROR: Invalid sample rate %d\n", SAMPLE_FREQUENCY);
_Exit(1);
}

int bit_depth;
if(DATA_BITS == 16)
{
bit_depth = BITDEPTH_16;
}
else if(DATA_BITS == 32)
{
bit_depth = BITDEPTH_32;
}
else
{
printf("ERROR: Invalid bit_depth %d\n", DATA_BITS);
_Exit(1);
}
if((NUM_I2S_LINES < 1) || (NUM_I2S_LINES > 4))
{
printf("ERROR: Invalid NUM_I2S_LINES %d\n", NUM_I2S_LINES);
_Exit(1);
}
int delay = acceptable_delay_ticks[sample_rate][NUM_I2S_LINES-1][bit_depth];

if(delay <= 0)
{
printf("ERROR: Invalid delay %d. Check if testing an unsupported configuration\n", delay);
_Exit(1);
}

// get the send and receive delay based on the
if((RECEIVE_DELAY_INCREMENT == 5) && (SEND_DELAY_INCREMENT == 5))
{
// Backpressure passes at delay, so add another increment number of ticks to get to the first fail instance
acceptable_receive_delay = delay + 5;
acceptable_send_delay = delay + 5;
}
else if((RECEIVE_DELAY_INCREMENT == 0) && (SEND_DELAY_INCREMENT == 10))
{
// Backpressure passes at 2*delay, so add another increment number of ticks to get to the first fail instance
acceptable_receive_delay = 0;
acceptable_send_delay = 2*delay + 10;
}
else if((RECEIVE_DELAY_INCREMENT == 10) && (SEND_DELAY_INCREMENT == 0))
{
// Backpressure passes at 2*delay, so add another increment number of ticks to get to the first fail instance
acceptable_receive_delay = 2*delay + 10;
acceptable_send_delay = 0;
}
else
{
printf("ERROR: Unsupported receive (%d) and send (%d) delay increment combination\n", RECEIVE_DELAY_INCREMENT, SEND_DELAY_INCREMENT);
_Exit(1);
}
}

/* Ports and clocks used by the application */
port_t p_lrclk = XS1_PORT_1G;
port_t p_bclk = XS1_PORT_1H;
Expand All @@ -54,8 +175,9 @@ port_t p_din [4] = {XS1_PORT_1I, XS1_PORT_1J, XS1_PORT_1K, XS1_PORT_1L};
xclock_t mclk = XS1_CLKBLK_1;
xclock_t bclk = XS1_CLKBLK_2;

static volatile int receive_delay = 5000;
static volatile int receive_delay = 0;
static volatile int send_delay = 0;
static volatile int32_t receive_data_store[8];

void i2s_init(void *app_data, i2s_config_t *i2s_config)
{
Expand All @@ -75,6 +197,9 @@ void i2s_send(void *app_data, size_t n, int32_t *send_data)

void i2s_receive(void *app_data, size_t n, int32_t *receive_data)
{
for (size_t c = 0; c < n; c++) {
receive_data_store[c] = receive_data[c];
}
if (receive_delay) {
delay_ticks(receive_delay);
}
Expand All @@ -85,11 +210,6 @@ i2s_restart_t i2s_restart_check(void *app_data)
return I2S_NO_RESTART;
}

#if DATA_BITS == 32
#define OVERHEAD_TICKS 185 // Some of the period needs to be allowed for the callbacks
#else
#define OVERHEAD_TICKS 185 // Non-32b data widths take longer to process
#endif
#define JITTER 1 //Allow for rounding so does not break when diff = period + 1
#define N_CYCLES_AT_DELAY 1 //How many LR clock cycles to measure at each backpressure delay value
#define DIFF_WRAP_16(new, old) (new > old ? new - old : new + 0x10000 - old)
Expand Down Expand Up @@ -121,28 +241,40 @@ void test_lr_period() {
port_set_trigger_in_equal(p_lr_test, 0);
(void) port_in(p_lr_test);
counter++;
if (counter == N_CYCLES_AT_DELAY) {
receive_delay += RECEIVE_DELAY_INCREMENT;
send_delay += SEND_DELAY_INCREMENT;
if ((receive_delay + send_delay) > (period - OVERHEAD_TICKS)) {
printf("PASS\n");
_Exit(0);
}
counter = 0;
}

port_set_trigger_in_equal(p_lr_test, 1);
(void) port_in(p_lr_test);
time = port_get_trigger_time(p_lr_test);

int diff = DIFF_WRAP_16(time, time_old);
if (diff > (period + JITTER)) {
printf("Backpressure breaks at receive delay ticks=%d, send delay ticks=%d\n",
receive_delay, send_delay);
printf("actual diff: %d, maximum (period + Jitter): %d\n",
diff, (period + JITTER));
_Exit(1);
// The delay we're able to add in the i2s_receive() function should be acceptable_receive_delay ticks or more
if(receive_delay < acceptable_receive_delay)
{
printf("Backpressure breaks at receive delay ticks = %d, acceptable receive delay = %d\n",
receive_delay, acceptable_receive_delay);
printf("actual diff: %d, maximum (period + Jitter): %d\n", diff, (period + JITTER));
_Exit(1);
}

// The delay we're able to add in the i2s_send() function should be acceptable_send_delay ticks or more
if(send_delay < acceptable_send_delay)
{
printf("Backpressure breaks at send delay ticks = %d, acceptable send delay = %d\n",
send_delay, acceptable_send_delay);
printf("actual diff: %d, maximum (period + Jitter): %d\n", diff, (period + JITTER));
_Exit(1);
}
printf("PASS\n");
_Exit(0);
}

if (counter == N_CYCLES_AT_DELAY) {
receive_delay += RECEIVE_DELAY_INCREMENT;
send_delay += SEND_DELAY_INCREMENT;
counter = 0;
}
time_old = time;
time_old = time;
}
}

Expand All @@ -153,6 +285,9 @@ void burn(void) {
}

int main() {
populate_acceptable_delay_ticks();
get_acceptable_delay();

i2s_callback_group_t i_i2s = {
.init = (i2s_init_t) i2s_init,
.restart_check = (i2s_restart_check_t) i2s_restart_check,
Expand Down
10 changes: 6 additions & 4 deletions test/lib_i2s/test_backpressure.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import subprocess
from pathlib import Path

sample_rate_args = {"768kbps": 768000, "384kbps": 384000, "192kbps": 192000}
sample_rate_args = {"384kbps": 384000, "192kbps": 192000}

num_channels_args = {"1ch": 1, "2ch": 2, "3ch": 3, "4ch": 4}

Expand All @@ -17,7 +17,12 @@

bitdepth_args = {"16b": 16, "32b": 32}

# 384000 has a non-zero backpressure only upto 2 channels
def uncollect_if(bitdepth, sample_rate, num_channels, receive_increment, send_increment):
if sample_rate == 384000 and num_channels > 2:
return True

@pytest.mark.uncollect_if(func=uncollect_if)
@pytest.mark.parametrize("bitdepth", bitdepth_args.values(), ids=bitdepth_args.keys())
@pytest.mark.parametrize(
"sample_rate", sample_rate_args.values(), ids=sample_rate_args.keys()
Expand All @@ -41,9 +46,6 @@ def test_i2s_backpressure(
send_increment,
bitdepth,
):
if (num_channels != 4) and not nightly:
pytest.skip("Only run 4 channel tests unless it is a nightly")

id_string = (
f"{bitdepth}_{sample_rate}_{num_channels}_{receive_increment}_{send_increment}"
)
Expand Down

0 comments on commit 94a1dca

Please sign in to comment.