From 4575185082fc7e6bcfa0d77b6eb1c3a8b4e2c7a8 Mon Sep 17 00:00:00 2001 From: errsu Date: Sun, 16 Nov 2025 12:33:02 +0100 Subject: [PATCH 01/11] Add support for XCommon CMake - tested with XTC 15.3.1 on XP-SKC-X200 sliceboard (XS-2 CPU XE216-512-FB236) and XA-SK-SDRAM slice (64Mb IS42S16400F) - .gitignore taken from other XMOS projects that already support XCommon CMake (mostly a superset of the previous version) - to get it running, fixed test/sdram_multi_client + sdram_server called with client_count=7 according the the actual number of clients + run sdram_server in fast mode, otherwise there would be a short moment when enough clients (running in fast mode) are busy at the same time, so the sdram_server running in slow mode doesn't get enough cycles, resulting in errors - cosmetic change in sdram_bench to actually use BUF_WORDS, so that all tests run with the same buffer size, which is not a multiple of the page size (which was probably the intention) --- .gitignore | 58 ++++++++++++++----- CMakeLists.txt | 6 ++ examples/CMakeLists.txt | 5 ++ examples/sdram_demo/CMakeLists.txt | 15 +++++ lib_sdram/lib_build_info.cmake | 13 +++++ tests/CMakeLists.txt | 7 +++ tests/sdram_benchmark/CMakeLists.txt | 15 +++++ tests/sdram_benchmark/src/sdram_bench.xc | 20 +++---- tests/sdram_multi_client_test/CMakeLists.txt | 15 +++++ .../src/sdram_multi_client_test.xc | 6 +- tests/sdram_testbench/CMakeLists.txt | 15 +++++ 11 files changed, 150 insertions(+), 25 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 examples/CMakeLists.txt create mode 100644 examples/sdram_demo/CMakeLists.txt create mode 100644 lib_sdram/lib_build_info.cmake create mode 100644 tests/CMakeLists.txt create mode 100644 tests/sdram_benchmark/CMakeLists.txt create mode 100644 tests/sdram_multi_client_test/CMakeLists.txt create mode 100644 tests/sdram_testbench/CMakeLists.txt diff --git a/.gitignore b/.gitignore index 5bf0d73..e6abb90 100644 --- a/.gitignore +++ b/.gitignore @@ -1,19 +1,51 @@ -**.build*/* -**/bin/* -*.o -*.xe +# Tmp files & logs +*.settings +*.bin +*.zip +*.log *.vcd -*.s +*.swp +*.*~ +*.xmt +*.swo +*.swn +*~ +*.DS_Store + +# Python +*.pyc +**/*.egg-info/ +**/.venv*/ +.python-version + +# XMOS temp files +**/*build*/* +*/bin/* +**/flash_bin_node* +**/fw-* +**/s2l-* +**/spanning-xn-* +**/target-xn* *.xi +*.o *.i *.a -**/_build/* -lib_lcd/doc/rst/_build/* -**/run_*.log +*.d +*.decouple +*.pca.xml +**/CMakeFiles/* + +# XMOS binaries +*.xe + +# Built documentation +doc/_build/pdf/*.pdf +**/doc/pdf/*.pdf **/pdf/* **/html/* -Installs/* -.settings* -examples/lcd_demo/.build*/* -*.swp -examples/sdram_demo/.build* + +# Testing +tests/expect +tests/logs +tests/result +tests/test_*/**/*.xn diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..aa8809b --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.21) +include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake) +project(lib_sdram) + +add_subdirectory(examples) +add_subdirectory(tests) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 0000000..5d1f667 --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.21) +include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake) +project(lib_sdram_examples) + +add_subdirectory(sdram_demo) diff --git a/examples/sdram_demo/CMakeLists.txt b/examples/sdram_demo/CMakeLists.txt new file mode 100644 index 0000000..17a9d38 --- /dev/null +++ b/examples/sdram_demo/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.21) +include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake) +project(sdram_demo) + +set(APP_HW_TARGET SLICEKIT-XC200-X1.xn) + +set(APP_DEPENDENT_MODULES "lib_sdram") +set(APP_INCLUDES src) +set(APP_COMPILER_FLAGS -g -O2) + +set(APP_PCA_ENABLE ON) + +set(XMOS_SANDBOX_DIR ${CMAKE_CURRENT_LIST_DIR}/../../..) + +XMOS_REGISTER_APP() diff --git a/lib_sdram/lib_build_info.cmake b/lib_sdram/lib_build_info.cmake new file mode 100644 index 0000000..dcefdd1 --- /dev/null +++ b/lib_sdram/lib_build_info.cmake @@ -0,0 +1,13 @@ +set(LIB_NAME lib_sdram) +set(LIB_VERSION 3.3.0) +set(LIB_INCLUDES api src) + +set(LIB_DEPENDENT_MODULES "") + +set(LIB_COMPILER_FLAGS -O3 + -Wno-unusual-code + -fasm-linenum + -fcomment-asm + -g) + +XMOS_REGISTER_MODULE() diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..1e6260c --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.21) +include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake) +project(lib_sdram_tests) + +add_subdirectory(sdram_benchmark) +add_subdirectory(sdram_multi_client_test) +add_subdirectory(sdram_testbench) diff --git a/tests/sdram_benchmark/CMakeLists.txt b/tests/sdram_benchmark/CMakeLists.txt new file mode 100644 index 0000000..2ea126e --- /dev/null +++ b/tests/sdram_benchmark/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.21) +include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake) +project(sdram_benchmark) + +set(APP_HW_TARGET SLICEKIT-XC200-X1.xn) + +set(APP_DEPENDENT_MODULES "lib_sdram") +set(APP_INCLUDES src) +set(APP_COMPILER_FLAGS -g -O2) + +set(APP_PCA_ENABLE ON) + +set(XMOS_SANDBOX_DIR ${CMAKE_CURRENT_LIST_DIR}/../../..) + +XMOS_REGISTER_APP() diff --git a/tests/sdram_benchmark/src/sdram_bench.xc b/tests/sdram_benchmark/src/sdram_bench.xc index c081301..65e09ab 100644 --- a/tests/sdram_benchmark/src/sdram_bench.xc +++ b/tests/sdram_benchmark/src/sdram_bench.xc @@ -47,10 +47,10 @@ void application(streaming chanend c_server, s_sdram_state sdram_state) { #define BUF_WORDS (240) - unsigned buffer_0[ROW_WORDS]; - unsigned buffer_1[ROW_WORDS]; - unsigned buffer_2[ROW_WORDS]; - unsigned buffer_3[ROW_WORDS]; + unsigned buffer_0[BUF_WORDS]; + unsigned buffer_1[BUF_WORDS]; + unsigned buffer_2[BUF_WORDS]; + unsigned buffer_3[BUF_WORDS]; unsigned * movable buffer_pointer_0 = buffer_0; unsigned * movable buffer_pointer_1 = buffer_1; @@ -62,10 +62,10 @@ void application(streaming chanend c_server, s_sdram_state sdram_state) { #define SECONDS 2 unsigned words_since_timeout = 0; t :> time; - sdram_read(c_server, sdram_state, 0, ROW_WORDS, move(buffer_pointer_0)); - sdram_read(c_server, sdram_state, 0, ROW_WORDS, move(buffer_pointer_1)); - sdram_read(c_server, sdram_state, 0, ROW_WORDS, move(buffer_pointer_2)); - sdram_read(c_server, sdram_state, 0, ROW_WORDS, move(buffer_pointer_3)); + sdram_read(c_server, sdram_state, 0, BUF_WORDS, move(buffer_pointer_0)); + sdram_read(c_server, sdram_state, 0, BUF_WORDS, move(buffer_pointer_1)); + sdram_read(c_server, sdram_state, 0, BUF_WORDS, move(buffer_pointer_2)); + sdram_read(c_server, sdram_state, 0, BUF_WORDS, move(buffer_pointer_3)); while(1){ select { case t when timerafter(time + SECONDS*100000000) :> time: @@ -73,8 +73,8 @@ void application(streaming chanend c_server, s_sdram_state sdram_state) { words_since_timeout = 0; break; case sdram_complete(c_server, sdram_state, buffer_pointer_0):{ - words_since_timeout += ROW_WORDS; - sdram_read(c_server, sdram_state, 0, ROW_WORDS, move(buffer_pointer_0)); + words_since_timeout += BUF_WORDS; + sdram_read(c_server, sdram_state, 0, BUF_WORDS, move(buffer_pointer_0)); break; } } diff --git a/tests/sdram_multi_client_test/CMakeLists.txt b/tests/sdram_multi_client_test/CMakeLists.txt new file mode 100644 index 0000000..00e8f9a --- /dev/null +++ b/tests/sdram_multi_client_test/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.21) +include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake) +project(sdram_multi_client_test) + +set(APP_HW_TARGET SLICEKIT-XC200-X1.xn) + +set(APP_DEPENDENT_MODULES "lib_sdram") +set(APP_INCLUDES src) +set(APP_COMPILER_FLAGS -g -O2) + +set(APP_PCA_ENABLE ON) + +set(XMOS_SANDBOX_DIR ${CMAKE_CURRENT_LIST_DIR}/../../..) + +XMOS_REGISTER_APP() diff --git a/tests/sdram_multi_client_test/src/sdram_multi_client_test.xc b/tests/sdram_multi_client_test/src/sdram_multi_client_test.xc index 37e0ede..79bceb2 100644 --- a/tests/sdram_multi_client_test/src/sdram_multi_client_test.xc +++ b/tests/sdram_multi_client_test/src/sdram_multi_client_test.xc @@ -104,7 +104,9 @@ int main() { } printf("Success\n"); } - on tile[SERVER_TILE]:sdram_server(c_sdram, 1, + on tile[SERVER_TILE]:{ + set_thread_fast_mode_on(); + sdram_server(c_sdram, 7, sdram_dq_ah, sdram_cas, sdram_ras, @@ -112,7 +114,7 @@ int main() { sdram_clk, sdram_cb, 2, 128, 16, 8,12, 2, 64, 4096, 4); + } } return 0; } - diff --git a/tests/sdram_testbench/CMakeLists.txt b/tests/sdram_testbench/CMakeLists.txt new file mode 100644 index 0000000..df7169b --- /dev/null +++ b/tests/sdram_testbench/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.21) +include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake) +project(sdram_testbench) + +set(APP_HW_TARGET SLICEKIT-XC200-X1.xn) + +set(APP_DEPENDENT_MODULES "lib_sdram") +set(APP_INCLUDES src) +set(APP_COMPILER_FLAGS -g -O2) + +set(APP_PCA_ENABLE ON) + +set(XMOS_SANDBOX_DIR ${CMAKE_CURRENT_LIST_DIR}/../../..) + +XMOS_REGISTER_APP() From bc11f60f5bf321c2bee43bc6e5778da46f941d87 Mon Sep 17 00:00:00 2001 From: errsu Date: Mon, 17 Nov 2025 12:22:23 +0100 Subject: [PATCH 02/11] Add an SDRAM timing calculations tool - as used to calculate the theoretical SDRAM read timings for xcore-ai - with documentation of the signals and latencies in the comments --- CMakeLists.txt | 1 + README.rst | 10 +- tools/CMakeLists.txt | 5 + .../sdram_timing_calculations/CMakeLists.txt | 12 ++ tools/sdram_timing_calculations/README.rst | 57 +++++++ .../src/sdram_timing_calculations.c | 155 ++++++++++++++++++ 6 files changed, 234 insertions(+), 6 deletions(-) create mode 100644 tools/CMakeLists.txt create mode 100644 tools/sdram_timing_calculations/CMakeLists.txt create mode 100644 tools/sdram_timing_calculations/README.rst create mode 100644 tools/sdram_timing_calculations/src/sdram_timing_calculations.c diff --git a/CMakeLists.txt b/CMakeLists.txt index aa8809b..ca695aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,3 +4,4 @@ project(lib_sdram) add_subdirectory(examples) add_subdirectory(tests) +add_subdirectory(tools) diff --git a/README.rst b/README.rst index 7fafb73..6e5c8d5 100644 --- a/README.rst +++ b/README.rst @@ -4,8 +4,8 @@ SDRAM Library SDRAM Libary ------------ -The XMOS SDRAM library is designed for read and write access of arbitrary length 32b long word buffers at up to 62.5MHz clock rates. -It uses an optimized pinout with address and data lines overlaid along with other pinout +The XMOS SDRAM library is designed for read and write access of arbitrary length 32b long word buffers at up to 62.5MHz clock rates. +It uses an optimized pinout with address and data lines overlaid along with other pinout optimizations to implement 16 bit read/writes to Single Data Rate (SDR) SDRAM devices of size up to 256Mb, while consuming a total of just 20 xCORE I/O pins. @@ -46,9 +46,7 @@ Related application notes ......................... - I/O Timings for xCORE200 [#]_. +- I/O Timings for xcore-ai [#]_. .. [#] https://www.xmos.com/download/private/I-O-timings-for-xCORE200%281.0%29.pdf - - - - +.. [#] https://www.xmos.com/download/xcore_ai-I-O-Timings(7).pdf/ diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt new file mode 100644 index 0000000..8729b33 --- /dev/null +++ b/tools/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.21) +include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake) +project(lib_sdram_tools) + +add_subdirectory(sdram_timing_calculations) diff --git a/tools/sdram_timing_calculations/CMakeLists.txt b/tools/sdram_timing_calculations/CMakeLists.txt new file mode 100644 index 0000000..2b074e2 --- /dev/null +++ b/tools/sdram_timing_calculations/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.21) +include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake) +project(sdram_timing_calculations) + +set(XMOS_SANDBOX_DIR ${CMAKE_CURRENT_LIST_DIR}/../../..) +set(APP_HW_TARGET XU316-1024-FB265-C24) +set(APP_COMPILER_FLAGS -O3 -Wall) +set(APP_PCA_ENABLE ON) +set(APP_DEPENDENT_MODULES) +set(APP_INCLUDES src) + +XMOS_REGISTER_APP() diff --git a/tools/sdram_timing_calculations/README.rst b/tools/sdram_timing_calculations/README.rst new file mode 100644 index 0000000..118fe1e --- /dev/null +++ b/tools/sdram_timing_calculations/README.rst @@ -0,0 +1,57 @@ +SDRAM Data Input Timing Calculations +==================================== + +:scope: Tools +:description: Tool to find input delays matching the round trip window +:keywords: Memory,SDRAM,Round Trip Time +:boards: custom board with xcore-ai and SDRAM + +The tool calculates read delays for the SDRAM data input ports. +Input parameters are to be taken from datasheets to edit the +defines in the code. C was taken as programming language for the +tool just because it should be available to all XMOS developers. + +The input values in the code are selected for a custom board +with xcore-ai and SDRAM, but the method should be valid, with adapted +inputs, for other situations as well, including XS1 and XS2. + +How to use +---------- + +To build and run (with XTC 15.3.x):: + +> cd lib_sdram\tools\sdram_timing_calculations\ +> cmake -G "Unix Makefiles" -B build +> xmake -C build +> xsim .\bin\sdram_timing_calculations.xe + +The results per setting are shown as follows (refer to comments in the program):: + + F_core: 600 MHz, clock divider: 6, F_clk: 50.00 MHz + div: 6 read: 1 sample: 1 pad: 2 result: 0 [40558 ..( -574).. 39984 ..( 4600).. 44584] ps + div: 6 read: 1 sample: 1 pad: 1 result: 1 [38892 ..( 1092).. 39984 ..( 2934).. 42918] ps + div: 6 read: 1 sample: 1 pad: 0 result: 1 [37226 ..( 2758).. 39984 ..( 1268).. 41252] ps + div: 6 read: 2 sample: 0 pad: 5 result: 0 [45556 ..( 4424).. 49980 ..( -398).. 49582] ps + ^ ^ ^ ^ ^ + | | | | | + | | | | --- 1 if the read time fits in the read window + | | | -------------- pad_delay (0..5) + | | --------------------- sample_delay 0 or 1 + | ------------------------------- read_delay_clocks (0..2) + ---------------------------------------- clock_divider (4..12) + +The read window timing is shown in picoseconds from falling clock edge:: + + [40558 ..( -574).. 39984 ..( 4600).. 44584] + ^ ^ ^ ^ ^ + | | | | | + read windows start --- | | | | + start margin -------------- | | | + read time ---------------------- | | + end margin --------------------------------- | + read window end ----------------------------------------- + +A negative margin means that there is none. +So, theoretically, such setting cannot reliably work. +In practice, some of the assumptions about hardware +latencies are relatively weak. diff --git a/tools/sdram_timing_calculations/src/sdram_timing_calculations.c b/tools/sdram_timing_calculations/src/sdram_timing_calculations.c new file mode 100644 index 0000000..3d09dc1 --- /dev/null +++ b/tools/sdram_timing_calculations/src/sdram_timing_calculations.c @@ -0,0 +1,155 @@ +#include +#include + +// Taking data from SDRAM datasheet +// -------------------------------- +// +// CAS latency of 2 * Tclk taken into account separately, not in this tool. +// +// t_ac2 - Access Time From CLK +// t_oh2 - Output Data Hold Time +// +// Showing the clock signal with clock cycle numbers and the SDRAM output data +// corresponding to these clock cycles (..00xx11..11xx22...), +// as given in the datasheet: +// +// |<-------- Tclk ------->| +// ___1 ___________2 ___________3 ----------- +// |___________| t_ac2 |___________| t_oh2 |___________| |___ +// |<------->| |<-->| +// 000000000000000000xxxx11111111111111111111xxxx22222222222222222222xxxx333333 +// |<---------------->| output data availability window +// | ^ +// |_____________________| +// +// +// Applying roundtrip latencies (pin dependent, line capacity, XMOS signal resync) +// ------------------------------------------------------------------------------- +// +// Since we are only looking at the clock output vs. data input, it is irrelevant +// if latencies are added before or after the signals entering/leaving the SDRAM. +// +// The read window start is defined by the maximum round trip times. +// The read window end is defined by the minimum round trip times. +// +// ___1 ___________2 ___________3 ----------- +// |___________| |___________| |___________| |___ +// |<------- rtt_max ------------>|000000000000000000xxxx11111111111111111111xx +// |<- rtt_min ->|000000000000000000xxxx11111111111111111111xxxx222222222222222 +// -->|-|<-- read window +// +// rtt_max = LAT_PIN_DEP_MAX + LAT_LINE_CAP_MAX + 5 * Tcore +// rtt_min = LAT_PIN_DEP_MIN + LAT_LINE_CAP_MIN + 4 * Tcore +// +// +// Chosing a read time (t_read) using read_delay_clocks and sample_delay, +// and moving the signal there using pad_delay: +// ---------------------------------------------------------------------- +// t_read +// |<-Tclk/2-->|<-(read_delay_clocks + sample_delay/2) * Tclk->| +// ___1 ___________2 ___________3 ----------- +// |___________| |___________| |___________| |___ +// | |<------- rtt_max ------------>|000000000000000000xxxx11111111111111111 +// | |<- rtt_min ->|000000000000000000xxxx11111111111111111111xxxx2222222222 +// |<-->| pad_delay * Tcore t_read_min -->|-|<-- t_read_max +// +// read_delay_clocks = 0, 1, 2, ... +// sample_delay = 0 | 1 +// pad_delay = 0...5 +// +// t_read = Tclk/2 + (read_delay_clocks + sample_delay / 2) * Tclk +// t_read_min = Tclk/2 + t_ac2 + rtt_max + pad_delay * Tcore +// t_read_max = 3Tclk/2 + t_oh2 + rtt_min + pad_delay * Tcore + + +// all values in picoseconds and MHz + +//---------------------------------------------------------------------------------------- +// Values for a xcore-ai/600 MHz onboard SDRAM case +//---------------------------------------------------------------------------------------- +// processor clock +#define FCORE 600 +#define TCORE (1000000/FCORE) + +// I/O timing for xcore_ai, A.2, p.19, X1D00..X1D71 +#define LAT_PIN_DEP_MIN 400 +#define LAT_PIN_DEP_MAX 4500 + +// I/O timing for xcore_ai, A.3, p.20, 3.3V 5pF 4mA +// - address/data lines are short, IS45S16400J has an input capacity of 3.5pF +#define LAT_LINE_CAP_MIN 1700 +#define LAT_LINE_CAP_MAX 9000 + +// I/O timing for xcore_ai, 4.1, p.13 +#define LAT_RESYNC_MIN (4*TCORE) +#define LAT_RESYNC_MAX (5*TCORE) + +// IS45S16400J Datasheet p.16 +#define SDRAM_T_AC2 5400 +#define SDRAM_T_OH2 2500 + +#if 0 +//---------------------------------------------------------------------------------------- +// Values for the XS2/500 MHz slicekit +//---------------------------------------------------------------------------------------- +// processor clock +#define FCORE 500 +#define TCORE (1000000/FCORE) + +// I/O timing for xCORE200, p.18, all pins +#define LAT_PIN_DEP_MIN 3000 +#define LAT_PIN_DEP_MAX 11300 + +// 1.4 ns of PCB round trip delay (correct for XCORE200 slicekit) +#define LAT_LINE_CAP_MIN 1400 +#define LAT_LINE_CAP_MAX 1400 + +// I/O timing for xcore_ai, 4.1, p.13 +#define LAT_RESYNC_MIN (4*TCORE) +#define LAT_RESYNC_MAX (5*TCORE) + +// IS45S16400D Datasheet p.14 +#define SDRAM_T_AC2 6000 +#define SDRAM_T_OH2 2500 + +#endif + +//---------------------------------------------------------------------------------------- + +int main() +{ + printf("SDRAM input read timing\n"); + printf("-----------------------\n"); + + unsigned rtt_min = LAT_PIN_DEP_MIN + LAT_LINE_CAP_MIN + LAT_RESYNC_MIN; + unsigned rtt_max = LAT_PIN_DEP_MAX + LAT_LINE_CAP_MAX + LAT_RESYNC_MAX; + printf("\nRound trip time min: %d ps, max: %d ps\n", rtt_min, rtt_max); + + for (unsigned clock_divider = 4; clock_divider < 13; clock_divider++) + { + printf("\nF_core: %d MHz, clock divider: %d, F_clk: %d.%02d MHz\n", + FCORE, clock_divider, FCORE / (2 * clock_divider), (FCORE * 50 / clock_divider) % 100); + + for (unsigned read_delay_clocks = 0; read_delay_clocks < 3; read_delay_clocks++) + { + for (unsigned sample_delay = 0; sample_delay < 2; sample_delay++) + { + // t_read = Tclk/2 + (read_delay_clocks + sample_delay / 2) * Tclk + // Tclk = Tcore * clock_divider * 2 + unsigned t_read = TCORE * clock_divider * (read_delay_clocks * 2 + 1 + sample_delay); + for (unsigned i = 0; i < 6; i++) + { + unsigned pad_delay = 5 - i; + unsigned t_read_min = (clock_divider + pad_delay) * TCORE + SDRAM_T_AC2 + rtt_max; + unsigned t_read_max = (3 * clock_divider + pad_delay) * TCORE + SDRAM_T_OH2 + rtt_min; + unsigned success = (t_read_min < t_read && t_read < t_read_max); + printf("div: %2d read: %d sample: %d pad: %d result: %d [%5d ..(%6d).. %5d ..(%6d).. %5d] ps\n", + clock_divider, read_delay_clocks, sample_delay, pad_delay, success, + t_read_min, t_read - t_read_min, t_read, t_read_max - t_read, t_read_max); + } + } + } + } + + return 0; +} From 296c4731918147afa1206981dd61ef45915c8534 Mon Sep 17 00:00:00 2001 From: errsu Date: Tue, 18 Nov 2025 22:20:10 +0100 Subject: [PATCH 03/11] adapt lib_sdram timings to xcore-ai (XS3) - for 600 MHz clock instead of the 500 MHz default of XS1/XS2 - tested with an XU316 board with 64Mbit Winbond W9864G6KH-6 which is equivalent to an ISSI IS42S16400D-7 - depending on the clock divider, the READ/WRITE_SETUP_LATENCY could possibly be further optimized (reduced) for XS3 compared to XS2, as the thread cycles of XS3 are shorter by 17%, but this is relevant only for small buffer read/write commands --- lib_sdram/src/io.S | 7 +++-- lib_sdram/src/server.xc | 61 +++++++++++++++++++++++++++++++++-------- 2 files changed, 54 insertions(+), 14 deletions(-) diff --git a/lib_sdram/src/io.S b/lib_sdram/src/io.S index 770a1ac..442b472 100644 --- a/lib_sdram/src/io.S +++ b/lib_sdram/src/io.S @@ -1,7 +1,8 @@ // Copyright 2014-2021 XMOS LIMITED. // This Software is subject to the terms of the XMOS Public Licence: Version 1. .text -#ifdef __XS2A__ + +#if defined(__XS2A__) || defined (__XS3A__) //xCore 200 optimised version with support for >8bit row addresses .cc_top sdram_block_write.function .align 4 @@ -185,7 +186,7 @@ sdram_block_write: ////////////////////////////////////////////////////////////////// -#ifdef __XS2A__ +#if defined(__XS2A__) || defined (__XS3A__) //xCore 200 optimised version with support for >8bit row addresses .cc_top sdram_block_read.function .align 4 @@ -306,7 +307,7 @@ sdram_block_read_cleanup: sdram_block_read: .issue_mode single #define READ_STACK_WORDS 6 - + ENTSP_lu6 READ_STACK_WORDS //r0 buffer pointer diff --git a/lib_sdram/src/server.xc b/lib_sdram/src/server.xc index 0fc5b22..746437a 100644 --- a/lib_sdram/src/server.xc +++ b/lib_sdram/src/server.xc @@ -71,10 +71,50 @@ static unsigned sdram_init( set_port_clock(ras, cb); set_port_clock(we, cb); +#ifdef __XS3A__ // assuming 600MHz clock + // See tools/sdram_timing_calculations how values for xcore-ai are selected. + // Settings below are for pins X1D00..X1D71, 3.3V 5pF 4mA, IS42S16400D-7 + // with some corrections towards earlier reads after HW tests. + switch(clock_divider) { + case 5: // Tclk = 60.00MHz + read_delay_whole_clocks = 1; + set_port_sample_delay(dq_ah); + set_pad_delay(dq_ah, 0); + break; + case 6: // Tclk = 50.00MHz + read_delay_whole_clocks = 1; + set_port_sample_delay(dq_ah); + set_pad_delay(dq_ah, 2); + break; + case 7: // Tclk = 42.86MHz + read_delay_whole_clocks = 1; + set_port_sample_delay(dq_ah); + set_pad_delay(dq_ah, 4); + break; + case 8: // Tclk = 37.50MHz + read_delay_whole_clocks = 1; + set_port_sample_delay(dq_ah); + set_pad_delay(dq_ah, 5); + break; + case 9: // Tclk = 33.33MHz + read_delay_whole_clocks = 1; + set_port_no_sample_delay(dq_ah); + set_pad_delay(dq_ah, 0); + break; + case 10: // Tclk = 30.00MHz + read_delay_whole_clocks = 1; + set_port_no_sample_delay(dq_ah); + set_pad_delay(dq_ah, 1); + break; + default: + __builtin_trap(); + break; + } +#else // assuming 500MHz clock //Setup pad and internal read delays to compensate for round trip delays - //SDRAM used for timing calcs has 6ns max access (clock to data) time and 2.5ns min hold time - //Timing also includes 1.4ns of PCB round trip delay (correct for XCORE200 slicekit) - //Timings assume use of any combination of ports ( setup = 21.3ns and hold = -11ns) Greater timing margins can be obtained + //SDRAM used for timing calcs has 6ns max access (clock to data) time and 2.5ns min hold time + //Timing also includes 1.4ns of PCB round trip delay (correct for XCORE200 slicekit) + //Timings assume use of any combination of ports ( setup = 21.3ns and hold = -11ns) Greater timing margins can be obtained //by choosing specific ports. Please consult the "IO timings for xCORE200" document for details switch(clock_divider) { case 4: // 500 / (4 * 2) = 62.50MHz. ~100ps margin @@ -97,7 +137,7 @@ static unsigned sdram_init( set_port_sample_delay(dq_ah); set_pad_delay(dq_ah, 5); break; - case 8: // 500 / (8 * 2) = 31.25MHz. ~6.1ns margin + case 8: // 500 / (8 * 2) = 31.25MHz. ~6.1ns margin read_delay_whole_clocks = 1; set_port_no_sample_delay(dq_ah); set_pad_delay(dq_ah, 0); @@ -118,13 +158,12 @@ static unsigned sdram_init( // set_port_sample_delay(dq_ah); // set_pad_delay(dq_ah, 2); // break; - default: // Support for any frequency lower that 25MHz can be implemented by using + default: // Support for any frequency lower that 25MHz can be implemented by using // the 25MHz delay settings which will provide 12.7ns margin (plenty) __builtin_trap(); break; } - - +#endif start_clock(cb); @@ -152,7 +191,7 @@ static unsigned sdram_init( t+=600; // 600 * 16 = 9.6us partout_timed(ras, 2, CTRL_RAS_PRECHARGE | (CTRL_RAS_NOP<<1), t); partout_timed(we, 2, CTRL_WE_PRECHARGE | (CTRL_WE_NOP<<1), t); - + //Set next port out for 20 clocks (20 * 16 = 320ns) (TRP = 16ns) t+=20; @@ -212,9 +251,9 @@ void sdram_block_read(unsigned * buffer, sdram_ports &ports, unsigned t0, unsign void sdram_block_write(unsigned * buffer, sdram_ports &ports, unsigned t0, unsigned word_count, unsigned row_words); //The below latency figures are to allow for the overhead of calling the ASM block read after the transaction has started -//They are calulated assuming the SDRAM and server tasks are both running at 62.5MHz. They can be scaled down proportionally +//They are calulated assuming the SDRAM and server tasks are both running at 62.5MHz. They can be scaled down proportionally //if using lower SDRAM clock rates, but the server task still runs at 62.5MHz -#ifdef __XS2A__ +#if defined(__XS2A__) || defined (__XS3A__) #define WRITE_SETUP_LATENCY (42) //Simulated time with thread @ 62.5MHz is 36 thread cycles #define READ_SETUP_LATENCY (50) //Simulated time with thread @ 62.5MHz is 43 thread cycles #else @@ -243,7 +282,7 @@ static inline void write_impl(unsigned row, unsigned col, unsigned bank, //printf("Write buffer pointer=%p\trow_words=%x\tword_count=%x\n",buffer, row_words, word_count); dq_ah @ t <: rowcol; - + partout_timed(cas, 3, CTRL_CAS_ACTIVE | (CTRL_CAS_WRITE<<1) | (CTRL_CAS_NOP<<2), t); partout_timed(ras, 3, CTRL_RAS_ACTIVE | (CTRL_RAS_WRITE<<1) | (CTRL_RAS_NOP<<2), t); partout_timed(we , 3, CTRL_WE_ACTIVE | (CTRL_WE_WRITE<<1) | (CTRL_WE_NOP<<2), t); From 05993416008350a438539b7847009d4b8ee3b097 Mon Sep 17 00:00:00 2001 From: errsu Date: Tue, 18 Nov 2025 22:50:57 +0100 Subject: [PATCH 04/11] adapt lib_sdram example and tests to xcore-ai (XS3) - XS2 tests were done with XP-SKC-X200 and SDRAM slice containing IS42S16400F-7, to check for regressions - XS3 tests were done with a test board equipped with XU316-1024-FB265-C24 CPU and a 64 Mbit SDRAM Winbond W9864G6KH-6 (which is equivalent to IS42S16400D-7) - the XS3 test board does not support xscope, so all tests were adapted to optinally work with JTAG I/O, - to run tests with JTAG I/O, edit the respective config.xscope files to turn xscope off, set the #define JTAG_IO_PRINT (if any) to 1, and use xrun --io instead of xrun --xscope --- examples/sdram_demo/CMakeLists.txt | 1 + examples/sdram_demo/config.xscope | 4 +- examples/sdram_demo/src/sdram_demo.xc | 31 ++- .../sdram_demo/xcore_ai_sdram_test_board.xn | 55 +++++ tests/sdram_benchmark/CMakeLists.txt | 1 + tests/sdram_benchmark/config.xscope | 4 +- tests/sdram_benchmark/src/sdram_bench.xc | 51 ++++- .../xcore_ai_sdram_test_board.xn | 55 +++++ tests/sdram_multi_client_test/CMakeLists.txt | 1 + tests/sdram_multi_client_test/config.xscope | 4 +- .../src/sdram_multi_client_test.xc | 36 ++- .../xcore_ai_sdram_test_board.xn | 55 +++++ tests/sdram_testbench/CMakeLists.txt | 1 + tests/sdram_testbench/config.xscope | 4 +- tests/sdram_testbench/src/sdram_testbench.xc | 207 +++++++++++------- .../xcore_ai_sdram_test_board.xn | 55 +++++ 16 files changed, 459 insertions(+), 106 deletions(-) create mode 100644 examples/sdram_demo/xcore_ai_sdram_test_board.xn create mode 100644 tests/sdram_benchmark/xcore_ai_sdram_test_board.xn create mode 100644 tests/sdram_multi_client_test/xcore_ai_sdram_test_board.xn create mode 100644 tests/sdram_testbench/xcore_ai_sdram_test_board.xn diff --git a/examples/sdram_demo/CMakeLists.txt b/examples/sdram_demo/CMakeLists.txt index 17a9d38..9f13eb0 100644 --- a/examples/sdram_demo/CMakeLists.txt +++ b/examples/sdram_demo/CMakeLists.txt @@ -3,6 +3,7 @@ include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake) project(sdram_demo) set(APP_HW_TARGET SLICEKIT-XC200-X1.xn) +#set(APP_HW_TARGET xcore_ai_sdram_test_board.xn) set(APP_DEPENDENT_MODULES "lib_sdram") set(APP_INCLUDES src) diff --git a/examples/sdram_demo/config.xscope b/examples/sdram_demo/config.xscope index 29ab652..fd50384 100644 --- a/examples/sdram_demo/config.xscope +++ b/examples/sdram_demo/config.xscope @@ -1,2 +1,2 @@ - - + + diff --git a/examples/sdram_demo/src/sdram_demo.xc b/examples/sdram_demo/src/sdram_demo.xc index 0f0b5ef..da04f58 100644 --- a/examples/sdram_demo/src/sdram_demo.xc +++ b/examples/sdram_demo/src/sdram_demo.xc @@ -66,9 +66,20 @@ void application(streaming chanend c_server) { } //Use port mapping according to slicekit used -#ifdef __XS2A__ +#if defined(__XS3A__) +// SDRAM test board for XU316 +#define CLOCK_DIV 5 // (600/ (5*2)) = 60.0MHz +#define SERVER_TILE 1 +on tile[SERVER_TILE] : out buffered port:32 sdram_dq_ah = XS1_PORT_16A; +on tile[SERVER_TILE] : out buffered port:32 sdram_cas = XS1_PORT_1A; +on tile[SERVER_TILE] : out buffered port:32 sdram_ras = XS1_PORT_1P; +on tile[SERVER_TILE] : out buffered port:8 sdram_we = XS1_PORT_1M; +on tile[SERVER_TILE] : out port sdram_clk = XS1_PORT_1F; +on tile[SERVER_TILE] : clock sdram_cb = XS1_CLKBLK_1; +#elif defined(__XS2A__) //Triangle slot tile 0 for XU216 -#define SERVER_TILE 0 +#define CLOCK_DIV 4 // (500/ (4*2)) = 62.5MHz +#define SERVER_TILE 0 on tile[SERVER_TILE] : out buffered port:32 sdram_dq_ah = XS1_PORT_16B; on tile[SERVER_TILE] : out buffered port:32 sdram_cas = XS1_PORT_1J; on tile[SERVER_TILE] : out buffered port:32 sdram_ras = XS1_PORT_1I; @@ -77,7 +88,8 @@ on tile[SERVER_TILE] : out port sdram_clk = XS1_ on tile[SERVER_TILE] : clock sdram_cb = XS1_CLKBLK_2; #else //Square slot on A16 slicekit -#define SERVER_TILE 1 +#define CLOCK_DIV 4 // (500/ (4*2)) = 62.5MHz +#define SERVER_TILE 1 on tile[SERVER_TILE] : out buffered port:32 sdram_dq_ah = XS1_PORT_16A; on tile[SERVER_TILE] : out buffered port:32 sdram_cas = XS1_PORT_1B; on tile[SERVER_TILE] : out buffered port:32 sdram_ras = XS1_PORT_1G; @@ -89,7 +101,9 @@ on tile[SERVER_TILE] : clock sdram_cb = XS1_ int main() { streaming chan c_sdram[1]; par { - on tile[SERVER_TILE]:sdram_server(c_sdram, 1, + on tile[SERVER_TILE]:{ + set_core_high_priority_on(); + sdram_server(c_sdram, 1, sdram_dq_ah, sdram_cas, sdram_ras, @@ -97,12 +111,13 @@ int main() { sdram_clk, sdram_cb, #if USE_256Mb - 2, 256, 16, 9, 13, 2, 64, 8192, 4); //IS45S16160D 256Mb option or similar + //IS45S16160D 256Mb option or similar + 2, 256, 16, 9, 13, 2, 64, 8192, CLOCK_DIV); #else - 2, 128, 16, 8, 12, 2, 64, 4096, 4); //Uses IS42S16400D 64Mb part supplied on SDRAM slice + //Uses IS42S16400D 64Mb part supplied on SDRAM slice + 2, 128, 16, 8, 12, 2, 64, 4096, CLOCK_DIV); #endif - //Note clock div 4 gives (500/ (4*2)) = 62.5MHz - + } on tile[SERVER_TILE]: application(c_sdram[0]); on tile[SERVER_TILE]: par(int i=0;i<6;i++) while(1); //Consume the remaining MHz } diff --git a/examples/sdram_demo/xcore_ai_sdram_test_board.xn b/examples/sdram_demo/xcore_ai_sdram_test_board.xn new file mode 100644 index 0000000..dca6088 --- /dev/null +++ b/examples/sdram_demo/xcore_ai_sdram_test_board.xn @@ -0,0 +1,55 @@ + + + Board + xcore-ai SDRAM Test Board + + + tileref tile[2] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/sdram_benchmark/CMakeLists.txt b/tests/sdram_benchmark/CMakeLists.txt index 2ea126e..f883b7d 100644 --- a/tests/sdram_benchmark/CMakeLists.txt +++ b/tests/sdram_benchmark/CMakeLists.txt @@ -3,6 +3,7 @@ include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake) project(sdram_benchmark) set(APP_HW_TARGET SLICEKIT-XC200-X1.xn) +#set(APP_HW_TARGET xcore_ai_sdram_test_board.xn) set(APP_DEPENDENT_MODULES "lib_sdram") set(APP_INCLUDES src) diff --git a/tests/sdram_benchmark/config.xscope b/tests/sdram_benchmark/config.xscope index 29ab652..fd50384 100644 --- a/tests/sdram_benchmark/config.xscope +++ b/tests/sdram_benchmark/config.xscope @@ -1,2 +1,2 @@ - - + + diff --git a/tests/sdram_benchmark/src/sdram_bench.xc b/tests/sdram_benchmark/src/sdram_bench.xc index 65e09ab..b8a83dc 100644 --- a/tests/sdram_benchmark/src/sdram_bench.xc +++ b/tests/sdram_benchmark/src/sdram_bench.xc @@ -5,15 +5,19 @@ #include #include "sdram.h" +#define JTAG_IO_PRINT 0 // set to 0 when using xrun --xscope + // set to 1 for xrun --io + + //For XS2 (xCORE200) put an SDRAM slice into the 'triangle' slot of tile 0 of the XP-SKC-X200 slice kit //If using 256Mb slice, then define USE_256Mb below, otherwise leave commented out #define SDRAM_256Mb 1 //Use IS42S16160D 256Mb or similar #define SDRAM_128Mb 0 //Use IS42S16800D 128Mb //othewise IS42S16400D 64Mb which is default on XMOS boards + #define CAS_LATENCY 2 #define REFRESH_MS 64 -#define CLOCK_DIV 4 //Note clock div 4 gives (500/ (4*2)) = 62.5MHz #define DATA_BITS 16 #if SDRAM_256Mb @@ -42,6 +46,12 @@ #define ROW_WORDS 128 #endif +unsigned timer_is_after(timer t, unsigned time) +{ + unsigned now; + t :> now; + return timeafter(now, time); +} #pragma unsafe arrays void application(streaming chanend c_server, s_sdram_state sdram_state) { @@ -67,6 +77,19 @@ void application(streaming chanend c_server, s_sdram_state sdram_state) { sdram_read(c_server, sdram_state, 0, BUF_WORDS, move(buffer_pointer_2)); sdram_read(c_server, sdram_state, 0, BUF_WORDS, move(buffer_pointer_3)); while(1){ +#if JTAG_IO_PRINT + // avoid slow JTAG IO results printing to + // interrupt SDRAM server reading command + sdram_complete(c_server, sdram_state, buffer_pointer_0); + words_since_timeout += BUF_WORDS; + if (timer_is_after(t, time + SECONDS*100000000)) + { + printintln(words_since_timeout*4/SECONDS); + words_since_timeout = 0; + t :> time; + } + sdram_read(c_server, sdram_state, 0, BUF_WORDS, move(buffer_pointer_0)); +#else select { case t when timerafter(time + SECONDS*100000000) :> time: printintln(words_since_timeout*4/SECONDS); @@ -78,6 +101,7 @@ void application(streaming chanend c_server, s_sdram_state sdram_state) { break; } } +#endif } } @@ -96,14 +120,37 @@ void sdram_client(streaming chanend c_server) { application(c_server, sdram_state); } +#if defined(__XS3A__) +// SDRAM test board for XU316 +#define CLOCK_DIV 5 // (600/ (5*2)) = 60.0MHz +#define SERVER_TILE 1 +on tile[SERVER_TILE] : out buffered port:32 sdram_dq_ah = XS1_PORT_16A; +on tile[SERVER_TILE] : out buffered port:32 sdram_cas = XS1_PORT_1A; +on tile[SERVER_TILE] : out buffered port:32 sdram_ras = XS1_PORT_1P; +on tile[SERVER_TILE] : out buffered port:8 sdram_we = XS1_PORT_1M; +on tile[SERVER_TILE] : out port sdram_clk = XS1_PORT_1F; +on tile[SERVER_TILE] : clock sdram_cb = XS1_CLKBLK_1; +#elif defined(__XS2A__) //Triangle slot tile 0 for XU216 -#define SERVER_TILE 0 +#define CLOCK_DIV 4 // (500/ (4*2)) = 62.5MHz +#define SERVER_TILE 0 on tile[SERVER_TILE] : out buffered port:32 sdram_dq_ah = XS1_PORT_16B; on tile[SERVER_TILE] : out buffered port:32 sdram_cas = XS1_PORT_1J; on tile[SERVER_TILE] : out buffered port:32 sdram_ras = XS1_PORT_1I; on tile[SERVER_TILE] : out buffered port:8 sdram_we = XS1_PORT_1K; on tile[SERVER_TILE] : out port sdram_clk = XS1_PORT_1L; on tile[SERVER_TILE] : clock sdram_cb = XS1_CLKBLK_2; +#else +//Square slot on A16 slicekit +#define CLOCK_DIV 4 // (500/ (4*2)) = 62.5MHz +#define SERVER_TILE 1 +on tile[SERVER_TILE] : out buffered port:32 sdram_dq_ah = XS1_PORT_16A; +on tile[SERVER_TILE] : out buffered port:32 sdram_cas = XS1_PORT_1B; +on tile[SERVER_TILE] : out buffered port:32 sdram_ras = XS1_PORT_1G; +on tile[SERVER_TILE] : out buffered port:8 sdram_we = XS1_PORT_1C; +on tile[SERVER_TILE] : out port sdram_clk = XS1_PORT_1F; +on tile[SERVER_TILE] : clock sdram_cb = XS1_CLKBLK_2; +#endif int main() { streaming chan c_sdram[1]; diff --git a/tests/sdram_benchmark/xcore_ai_sdram_test_board.xn b/tests/sdram_benchmark/xcore_ai_sdram_test_board.xn new file mode 100644 index 0000000..dca6088 --- /dev/null +++ b/tests/sdram_benchmark/xcore_ai_sdram_test_board.xn @@ -0,0 +1,55 @@ + + + Board + xcore-ai SDRAM Test Board + + + tileref tile[2] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/sdram_multi_client_test/CMakeLists.txt b/tests/sdram_multi_client_test/CMakeLists.txt index 00e8f9a..06581f2 100644 --- a/tests/sdram_multi_client_test/CMakeLists.txt +++ b/tests/sdram_multi_client_test/CMakeLists.txt @@ -3,6 +3,7 @@ include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake) project(sdram_multi_client_test) set(APP_HW_TARGET SLICEKIT-XC200-X1.xn) +#set(APP_HW_TARGET xcore_ai_sdram_test_board.xn) set(APP_DEPENDENT_MODULES "lib_sdram") set(APP_INCLUDES src) diff --git a/tests/sdram_multi_client_test/config.xscope b/tests/sdram_multi_client_test/config.xscope index 29ab652..fd50384 100644 --- a/tests/sdram_multi_client_test/config.xscope +++ b/tests/sdram_multi_client_test/config.xscope @@ -1,2 +1,2 @@ - - + + diff --git a/tests/sdram_multi_client_test/src/sdram_multi_client_test.xc b/tests/sdram_multi_client_test/src/sdram_multi_client_test.xc index 79bceb2..79ce1a7 100644 --- a/tests/sdram_multi_client_test/src/sdram_multi_client_test.xc +++ b/tests/sdram_multi_client_test/src/sdram_multi_client_test.xc @@ -12,7 +12,6 @@ //othewise IS42S16400D 64Mb which is default on XMOS boards #define CAS_LATENCY 2 #define REFRESH_MS 64 -#define CLOCK_DIV 4 //Note clock div 4 gives (500/ (4*2)) = 62.5MHz #define DATA_BITS 16 #if SDRAM_256Mb @@ -80,14 +79,37 @@ void sdram_client(streaming chanend c_server, int n) { test(c_server, sdram_state, n); } +#if defined(__XS3A__) +// SDRAM test board for XU316 +#define CLOCK_DIV 5 // (600/ (5*2)) = 60.0MHz +#define SERVER_TILE 1 +on tile[SERVER_TILE] : out buffered port:32 sdram_dq_ah = XS1_PORT_16A; +on tile[SERVER_TILE] : out buffered port:32 sdram_cas = XS1_PORT_1A; +on tile[SERVER_TILE] : out buffered port:32 sdram_ras = XS1_PORT_1P; +on tile[SERVER_TILE] : out buffered port:8 sdram_we = XS1_PORT_1M; +on tile[SERVER_TILE] : out port sdram_clk = XS1_PORT_1F; +on tile[SERVER_TILE] : clock sdram_cb = XS1_CLKBLK_1; +#elif defined(__XS2A__) //Triangle slot tile 0 for XU216 -#define SERVER_TILE 0 +#define CLOCK_DIV 4 // (500/ (4*2)) = 62.5MHz +#define SERVER_TILE 0 on tile[SERVER_TILE] : out buffered port:32 sdram_dq_ah = XS1_PORT_16B; on tile[SERVER_TILE] : out buffered port:32 sdram_cas = XS1_PORT_1J; on tile[SERVER_TILE] : out buffered port:32 sdram_ras = XS1_PORT_1I; on tile[SERVER_TILE] : out buffered port:8 sdram_we = XS1_PORT_1K; on tile[SERVER_TILE] : out port sdram_clk = XS1_PORT_1L; on tile[SERVER_TILE] : clock sdram_cb = XS1_CLKBLK_2; +#else +//Square slot on A16 slicekit +#define CLOCK_DIV 4 // (500/ (4*2)) = 62.5MHz +#define SERVER_TILE 1 +on tile[SERVER_TILE] : out buffered port:32 sdram_dq_ah = XS1_PORT_16A; +on tile[SERVER_TILE] : out buffered port:32 sdram_cas = XS1_PORT_1B; +on tile[SERVER_TILE] : out buffered port:32 sdram_ras = XS1_PORT_1G; +on tile[SERVER_TILE] : out buffered port:8 sdram_we = XS1_PORT_1C; +on tile[SERVER_TILE] : out port sdram_clk = XS1_PORT_1F; +on tile[SERVER_TILE] : clock sdram_cb = XS1_CLKBLK_2; +#endif int main() { streaming chan c_sdram[7]; @@ -113,7 +135,15 @@ int main() { sdram_we, sdram_clk, sdram_cb, - 2, 128, 16, 8,12, 2, 64, 4096, 4); + CAS_LATENCY, + ROW_WORDS, + DATA_BITS, + COL_ADDRESS_BITS, + ROW_ADDRESS_BITS, + BANK_ADDRESS_BITS, + REFRESH_MS, + REFRESH_CYCLES, + CLOCK_DIV); } } return 0; diff --git a/tests/sdram_multi_client_test/xcore_ai_sdram_test_board.xn b/tests/sdram_multi_client_test/xcore_ai_sdram_test_board.xn new file mode 100644 index 0000000..dca6088 --- /dev/null +++ b/tests/sdram_multi_client_test/xcore_ai_sdram_test_board.xn @@ -0,0 +1,55 @@ + + + Board + xcore-ai SDRAM Test Board + + + tileref tile[2] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/sdram_testbench/CMakeLists.txt b/tests/sdram_testbench/CMakeLists.txt index df7169b..66b6464 100644 --- a/tests/sdram_testbench/CMakeLists.txt +++ b/tests/sdram_testbench/CMakeLists.txt @@ -3,6 +3,7 @@ include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake) project(sdram_testbench) set(APP_HW_TARGET SLICEKIT-XC200-X1.xn) +#set(APP_HW_TARGET xcore_ai_sdram_test_board.xn) set(APP_DEPENDENT_MODULES "lib_sdram") set(APP_INCLUDES src) diff --git a/tests/sdram_testbench/config.xscope b/tests/sdram_testbench/config.xscope index 29ab652..fd50384 100644 --- a/tests/sdram_testbench/config.xscope +++ b/tests/sdram_testbench/config.xscope @@ -1,2 +1,2 @@ - - + + diff --git a/tests/sdram_testbench/src/sdram_testbench.xc b/tests/sdram_testbench/src/sdram_testbench.xc index 01842b2..6f42487 100644 --- a/tests/sdram_testbench/src/sdram_testbench.xc +++ b/tests/sdram_testbench/src/sdram_testbench.xc @@ -7,19 +7,32 @@ #include #include "sdram.h" +#define VERBOSE_MSG 1 +#define MAX_ERRORS 10 // max number of errors reported per test +#define JTAG_IO_PRINT 0 // set to 0 when using xrun --xscope + // set to 1 for xrun --io + +static void verbose_print(unsigned char* msg) +{ +#if VERBOSE_MSG + printstr(msg); +#if JTAG_IO_PRINT + delay_milliseconds(20); // allow server to recover +#endif +#endif +} + //For XS2 (xCORE200) put an SDRAM slice into the 'triangle' slot of tile 0 of the XP-SKC-X200 slice kit //If using 256Mb slice, then define USE_256Mb below, otherwise leave commented out -#define VERBOSE_MSG 1 - #define SDRAM_256Mb 1 //Use IS42S16160D 256Mb #define SDRAM_128Mb 0 //Use IS42S16800D 128Mb //othewise IS42S16400D 64Mb which is default on XMOS boards + #define FAST_TEST 1 //Simplify read and wait only 12 seconds instead of 120 for refresh tests #define CAS_LATENCY 2 #define REFRESH_MS 64 -#define CLOCK_DIV 4 //Note clock div 4 gives (500 / (4*2)) = 62.5MHz #define DATA_BITS 16 #if SDRAM_256Mb @@ -71,15 +84,15 @@ static unsigned super_pattern() { } #define TEST_WORDS (ROW_WORDS) -#define MAX_BUFFER_WORDS 512 //Allows for 512Mb SDRAM +#define MAX_BUFFER_WORDS 512 //Allows for 512Mb SDRAM -static void whole_memory_write_read(streaming chanend c_server, s_sdram_state &sdram_state){ +static unsigned whole_memory_write_read(streaming chanend c_server, s_sdram_state &sdram_state){ unsigned buffer[MAX_BUFFER_WORDS]; unsigned * movable buffer_pointer = buffer; int error = 0; - if (VERBOSE_MSG) printf("Begin : whole_memory_write_read\n"); + verbose_print("Begin : whole_memory_write_read\n"); const unsigned clear_word = 0xdeafbeef; //clear memory to know value @@ -89,8 +102,7 @@ static void whole_memory_write_read(streaming chanend c_server, s_sdram_state &s sdram_write(c_server, sdram_state, addr, TEST_WORDS, move(buffer_pointer)); sdram_complete(c_server, sdram_state, buffer_pointer); } - printf("cleared all memory to 0x%x\n", clear_word); - + verbose_print("cleared all memory to 0xdeafbeef\n"); //Fill address value into memory location for(unsigned addr = 0; addr < TOTAL_MEMORY_WORDS; addr += TEST_WORDS){ @@ -101,7 +113,7 @@ static void whole_memory_write_read(streaming chanend c_server, s_sdram_state &s sdram_complete(c_server, sdram_state, buffer_pointer); } - printf("written incrementing pattern\n"); + verbose_print("written incrementing pattern\n"); #if FAST_TEST for(unsigned addr = 0; addr < TOTAL_MEMORY_WORDS; addr += TEST_WORDS){ @@ -114,23 +126,26 @@ static void whole_memory_write_read(streaming chanend c_server, s_sdram_state &s for(unsigned i=0;i int; + return success; } -static void test_4_threads(streaming chanend c_server, s_sdram_state &sdram_state) { +static unsigned test_4_threads(streaming chanend c_server, s_sdram_state &sdram_state) { chan c[3]; - if (VERBOSE_MSG) - printf("4 threaded test suite start\n"); + verbose_print("4 threaded test suite start\n"); + unsigned success; par { - testbench(c_server, sdram_state, c[0], c[1]); + success = testbench(c_server, sdram_state, c[0], c[1]); load_thread(c[1], c[2]); load_thread(c[2], c[0]); } - if (VERBOSE_MSG) - printf("4 threaded test suite completed\n"); + verbose_print("4 threaded test suite completed\n"); + return success; } -static void test_8_threads(streaming chanend c_server, s_sdram_state &sdram_state) { +static unsigned test_8_threads(streaming chanend c_server, s_sdram_state &sdram_state) { chan c[7]; - if (VERBOSE_MSG) - printf("8 threaded test suite start\n"); + verbose_print("8 threaded test suite start\n"); + unsigned success; par { - testbench(c_server, sdram_state, c[0], c[1]); + success = testbench(c_server, sdram_state, c[0], c[1]); load_thread(c[1], c[2]); load_thread(c[2], c[3]); load_thread(c[3], c[4]); @@ -331,79 +358,89 @@ static void test_8_threads(streaming chanend c_server, s_sdram_state &sdram_stat load_thread(c[5], c[6]); load_thread(c[6], c[0]); } - if (VERBOSE_MSG) - printf("8 threaded test suite completed\n"); + verbose_print("8 threaded test suite completed\n"); + return success; } -static void test_7_threads(streaming chanend c_server, s_sdram_state &sdram_state) { +static unsigned test_7_threads(streaming chanend c_server, s_sdram_state &sdram_state) { chan c[6]; - if (VERBOSE_MSG) - printf("7 threaded test suite start\n"); + verbose_print("7 threaded test suite start\n"); + unsigned success; par { - testbench(c_server, sdram_state, c[0], c[1]); + success = testbench(c_server, sdram_state, c[0], c[1]); load_thread(c[1], c[2]); load_thread(c[2], c[3]); load_thread(c[3], c[4]); load_thread(c[4], c[5]); load_thread(c[5], c[0]); } - if (VERBOSE_MSG) - printf("7 threaded test suite completed\n"); + verbose_print("7 threaded test suite completed\n"); + return success; } -static void test_6_threads(streaming chanend c_server, s_sdram_state &sdram_state) { +static unsigned test_6_threads(streaming chanend c_server, s_sdram_state &sdram_state) { chan c[5]; - if (VERBOSE_MSG) - printf("6 threaded test suite start\n"); + verbose_print("6 threaded test suite start\n"); + unsigned success; par { - testbench(c_server, sdram_state, c[0], c[1]); + success = testbench(c_server, sdram_state, c[0], c[1]); load_thread(c[1], c[2]); load_thread(c[2], c[3]); load_thread(c[3], c[4]); load_thread(c[4], c[0]); } - if (VERBOSE_MSG) - printf("6 threaded test suite completed\n"); + verbose_print("6 threaded test suite completed\n"); + return success; } -static void test_5_threads(streaming chanend c_server, s_sdram_state &sdram_state) { +static unsigned test_5_threads(streaming chanend c_server, s_sdram_state &sdram_state) { chan c[4]; - if (VERBOSE_MSG) - printf("5 threaded test suite start\n"); + verbose_print("5 threaded test suite start\n"); + unsigned success; par { - testbench(c_server, sdram_state, c[0], c[1]); + success = testbench(c_server, sdram_state, c[0], c[1]); load_thread(c[1], c[2]); load_thread(c[2], c[3]); load_thread(c[3], c[0]); } - if (VERBOSE_MSG) - printf("5 threaded test suite completed\n"); + verbose_print("5 threaded test suite completed\n"); + return success; } void sdram_client(streaming chanend c_server) { #if SDRAM_256Mb - printf("Using 256Mb SDRAM\n"); + verbose_print("Using 256Mb SDRAM\n"); #elif SDRAM_128Mb - printf("Using 128Mb SDRAM\n"); + verbose_print("Using 128Mb SDRAM\n"); #else - printf("Using 64Mb SDRAM\n"); + verbose_print("Using 64Mb SDRAM\n"); #endif set_thread_fast_mode_on(); s_sdram_state sdram_state; sdram_init_state(c_server, sdram_state); - if (VERBOSE_MSG) - printf("Test suite begin\n"); - test_4_threads(c_server, sdram_state); - test_5_threads(c_server, sdram_state); - test_6_threads(c_server, sdram_state); - test_7_threads(c_server, sdram_state); - test_8_threads(c_server, sdram_state); - if (VERBOSE_MSG) - printf("Test suite completed\n"); + verbose_print("Test bench begin\n"); + unsigned success = test_4_threads(c_server, sdram_state); + success &= test_5_threads(c_server, sdram_state); + success &= test_6_threads(c_server, sdram_state); + success &= test_7_threads(c_server, sdram_state); + success &= test_8_threads(c_server, sdram_state); + verbose_print("Test bench completed\t\t\t"); + printf(success?"pass\n":"fail\n"); _Exit(0); } -#ifdef __XS2A__ -//XO-SKC-X200-1V0 Triangle slot tile 0 -#define SERVER_TILE 0 +#if defined(__XS3A__) +// SDRAM test board for XU316 +#define CLOCK_DIV 5 // (600/ (5*2)) = 60.0MHz +#define SERVER_TILE 1 +on tile[SERVER_TILE] : out buffered port:32 sdram_dq_ah = XS1_PORT_16A; +on tile[SERVER_TILE] : out buffered port:32 sdram_cas = XS1_PORT_1A; +on tile[SERVER_TILE] : out buffered port:32 sdram_ras = XS1_PORT_1P; +on tile[SERVER_TILE] : out buffered port:8 sdram_we = XS1_PORT_1M; +on tile[SERVER_TILE] : out port sdram_clk = XS1_PORT_1F; +on tile[SERVER_TILE] : clock sdram_cb = XS1_CLKBLK_1; +#elif defined(__XS2A__) +//Triangle slot tile 0 for XU216 +#define CLOCK_DIV 4 // (500/ (4*2)) = 62.5MHz +#define SERVER_TILE 0 on tile[SERVER_TILE] : out buffered port:32 sdram_dq_ah = XS1_PORT_16B; on tile[SERVER_TILE] : out buffered port:32 sdram_cas = XS1_PORT_1J; on tile[SERVER_TILE] : out buffered port:32 sdram_ras = XS1_PORT_1I; @@ -412,7 +449,8 @@ on tile[SERVER_TILE] : out port sdram_clk = XS1_ on tile[SERVER_TILE] : clock sdram_cb = XS1_CLKBLK_2; #else //Square slot on A16 slicekit -#define SERVER_TILE 1 +#define CLOCK_DIV 4 // (500/ (4*2)) = 62.5MHz +#define SERVER_TILE 1 on tile[SERVER_TILE] : out buffered port:32 sdram_dq_ah = XS1_PORT_16A; on tile[SERVER_TILE] : out buffered port:32 sdram_cas = XS1_PORT_1B; on tile[SERVER_TILE] : out buffered port:32 sdram_ras = XS1_PORT_1G; @@ -448,4 +486,3 @@ int main() { } return 0; } - diff --git a/tests/sdram_testbench/xcore_ai_sdram_test_board.xn b/tests/sdram_testbench/xcore_ai_sdram_test_board.xn new file mode 100644 index 0000000..dca6088 --- /dev/null +++ b/tests/sdram_testbench/xcore_ai_sdram_test_board.xn @@ -0,0 +1,55 @@ + + + Board + xcore-ai SDRAM Test Board + + + tileref tile[2] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From d7055704bc0b22dd2cf0baa00e010c50346ec1f4 Mon Sep 17 00:00:00 2001 From: errsu Date: Wed, 19 Nov 2025 00:22:40 +0100 Subject: [PATCH 05/11] make clear cas_latency is turned into read time offset - first of all, to avoid confusion - this solves the potential issue that cas_latency is declared const static in the header and used as mutable variable in the implementation - it will also be useful for later refactorings - cas_latency parameter was not used in the write function - this is an equivalent transform --- lib_sdram/src/io.S | 8 ++++---- lib_sdram/src/server.xc | 25 ++++++++++++------------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/lib_sdram/src/io.S b/lib_sdram/src/io.S index 442b472..10eebc3 100644 --- a/lib_sdram/src/io.S +++ b/lib_sdram/src/io.S @@ -203,7 +203,7 @@ sdram_block_read: //r2 t0 - start time //r3 word_count //sp[1] row_words - //sp[2] cas_latency + //sp[2] read_time_offset #define ras r0 #define dq_ah r1 @@ -223,7 +223,7 @@ sdram_block_read: sub new_buf_ptr, r0, 0 //set the first input time (t+CAS+N) - ldw temp, sp[READ_STACK_WORDS+2] //cas_latency + ldw temp, sp[READ_STACK_WORDS+2] //read_time_offset add start_time, r2, temp //calculate the time to issue the terminate cmd @@ -315,7 +315,7 @@ sdram_block_read: //r2 t0 - start time //r3 word_count //sp[1] row_words - //sp[2] cas_latency + //sp[2] read_time_offset #define ras r0 #define dq_ah r1 @@ -340,7 +340,7 @@ sdram_block_read: ldaw temp, r0[-temp] set dp, temp - ldw temp, sp[READ_STACK_WORDS+2] //cas_latency + ldw temp, sp[READ_STACK_WORDS+2] //read_time_offset add start_time, r2, temp //calculate the time to issue the terminate cmd diff --git a/lib_sdram/src/server.xc b/lib_sdram/src/server.xc index 746437a..cf4551c 100644 --- a/lib_sdram/src/server.xc +++ b/lib_sdram/src/server.xc @@ -247,7 +247,7 @@ typedef struct { unsigned we; } sdram_ports; -void sdram_block_read(unsigned * buffer, sdram_ports &ports, unsigned t0, unsigned word_count, unsigned row_words, unsigned cas_latency); +void sdram_block_read(unsigned * buffer, sdram_ports &ports, unsigned t0, unsigned word_count, unsigned row_words, unsigned read_time_offset); void sdram_block_write(unsigned * buffer, sdram_ports &ports, unsigned t0, unsigned word_count, unsigned row_words); //The below latency figures are to allow for the overhead of calling the ASM block read after the transaction has started @@ -300,7 +300,7 @@ static inline void read_impl(unsigned row, unsigned col, unsigned bank, out buffered port:32 ras, out buffered port:8 we, const static unsigned row_words, - unsigned cas_latency) { + unsigned read_time_offset) { //Work out first and second 16b commands (lower word first) - ACT followed by READ (no precharge) unsigned rowcol = row | (bank<>row_address_bits){ @@ -365,7 +365,6 @@ static void write(unsigned start_row, unsigned start_col, out buffered port:32 ras, out buffered port:8 we, const static unsigned row_words, - unsigned cas_latency, const static unsigned col_address_bits, const static unsigned row_address_bits, const static unsigned bank_address_bits) { @@ -413,7 +412,7 @@ static int handle_command(e_command cmd_type, sdram_cmd &cmd, out buffered port:32 ras, out buffered port:8 we, const static unsigned row_words, - unsigned cas_latency, + unsigned read_time_offset, const static unsigned col_address_bits, const static unsigned row_address_bits, const static unsigned bank_address_bits) { @@ -427,12 +426,12 @@ static int handle_command(e_command cmd_type, sdram_cmd &cmd, switch (cmd_type) { case SDRAM_CMD_READ: { read(row, col, bank, cmd.buffer, cmd.word_count, dq_ah, cas, ras, we, - row_words, cas_latency, col_address_bits, row_address_bits, bank_address_bits); + row_words, read_time_offset, col_address_bits, row_address_bits, bank_address_bits); break; } case SDRAM_CMD_WRITE: { write(row, col, bank, cmd.buffer, cmd.word_count, dq_ah, cas, ras, we, - row_words, cas_latency, col_address_bits, row_address_bits, bank_address_bits); + row_words, col_address_bits, row_address_bits, bank_address_bits); break; } default: @@ -455,7 +454,7 @@ void sdram_server(streaming chanend c_client[client_count], out buffered port:8 we, out port clk, clock cb, - unsigned cas_latency, + const static unsigned cas_latency, const static unsigned row_words, const static unsigned col_bits, const static unsigned col_address_bits, @@ -476,7 +475,7 @@ void sdram_server(streaming chanend c_client[client_count], cmd_buffer[i]->buffer = null; } - cas_latency = sdram_init(dq_ah, cas, ras, we, clk, cb, cas_latency, clock_divider); + unsigned read_time_offset = sdram_init(dq_ah, cas, ras, we, clk, cb, cas_latency, clock_divider); unsafe { for(unsigned i=0;i Date: Wed, 19 Nov 2025 01:04:24 +0100 Subject: [PATCH 06/11] factor out delay selection from sdram_init - the delay selection function does not configure the actual delays, that is still done by sdram_init - this means select_delays could actually be replaced by a table, indexed by the clock divider (maybe the compiler is doing just that) - actually two tables, one for XS3 and one for XS1/XS2 - sdram_init is not concerned anymore about read_delay_whole_clocks --- lib_sdram/src/server.xc | 184 +++++++++++++++++++++++----------------- 1 file changed, 104 insertions(+), 80 deletions(-) diff --git a/lib_sdram/src/server.xc b/lib_sdram/src/server.xc index cf4551c..62d9c71 100644 --- a/lib_sdram/src/server.xc +++ b/lib_sdram/src/server.xc @@ -25,51 +25,11 @@ static void refresh(unsigned ncycles, } } -static unsigned sdram_init( - out buffered port:32 dq_ah, - out buffered port:32 cas, - out buffered port:32 ras, - out buffered port:8 we, - out port clk, - clock cb, - unsigned cas_latency, - const static unsigned clock_divider -) { - //This parameter is used to delay the read by a whole number of sdram clocks - //It is used to compensate for the large round trip delay time of the xcore IO - - unsigned read_delay_whole_clocks = 0; - - timer T; - int time, t; - - //Do input from dq_ah to get it off the bus. Note use of asm to get around direction type of port - //This will help avoid contention if the code restarts with SDRAM in read mode for any reason - - unsigned tmp; - asm volatile("in %0, res[%1]" : "=r"(tmp) : "r"(dq_ah)); - - //Output NOP - partout(cas, 1, CTRL_CAS_NOP); - partout(ras, 1, CTRL_RAS_NOP); - partout(we, 1, CTRL_WE_NOP); - - sync(dq_ah); - stop_clock(cb); - - T :> time; - T when timerafter(time + 100 * TIMER_TICKS_PER_US) :> time; - - asm("setclk res[%0], %1"::"r"(cb), "r"(XS1_CLK_XCORE)); - set_clock_div(cb, clock_divider); - - set_port_clock(clk, cb); - set_port_mode_clock(clk); - - set_port_clock(dq_ah, cb); - set_port_clock(cas, cb); - set_port_clock(ras, cb); - set_port_clock(we, cb); +static void select_delays( + const static unsigned clock_divider, + unsigned& read_delay_whole_clocks, + unsigned& sample_delay, + unsigned& pad_delay) { #ifdef __XS3A__ // assuming 600MHz clock // See tools/sdram_timing_calculations how values for xcore-ai are selected. @@ -78,85 +38,86 @@ static unsigned sdram_init( switch(clock_divider) { case 5: // Tclk = 60.00MHz read_delay_whole_clocks = 1; - set_port_sample_delay(dq_ah); - set_pad_delay(dq_ah, 0); + sample_delay = 1; + pad_delay = 0; break; case 6: // Tclk = 50.00MHz read_delay_whole_clocks = 1; - set_port_sample_delay(dq_ah); - set_pad_delay(dq_ah, 2); + sample_delay = 1; + pad_delay = 2; break; case 7: // Tclk = 42.86MHz read_delay_whole_clocks = 1; - set_port_sample_delay(dq_ah); - set_pad_delay(dq_ah, 4); + sample_delay = 1; + pad_delay = 4; break; case 8: // Tclk = 37.50MHz read_delay_whole_clocks = 1; - set_port_sample_delay(dq_ah); - set_pad_delay(dq_ah, 5); + sample_delay = 1; + pad_delay = 5; break; case 9: // Tclk = 33.33MHz read_delay_whole_clocks = 1; - set_port_no_sample_delay(dq_ah); - set_pad_delay(dq_ah, 0); + sample_delay = 0; + pad_delay = 0; break; case 10: // Tclk = 30.00MHz read_delay_whole_clocks = 1; - set_port_no_sample_delay(dq_ah); - set_pad_delay(dq_ah, 1); + sample_delay = 0; + pad_delay = 1; break; default: __builtin_trap(); break; } #else // assuming 500MHz clock - //Setup pad and internal read delays to compensate for round trip delays //SDRAM used for timing calcs has 6ns max access (clock to data) time and 2.5ns min hold time //Timing also includes 1.4ns of PCB round trip delay (correct for XCORE200 slicekit) - //Timings assume use of any combination of ports ( setup = 21.3ns and hold = -11ns) Greater timing margins can be obtained - //by choosing specific ports. Please consult the "IO timings for xCORE200" document for details + //Timings assume use of any combination of ports ( setup = 21.3ns and hold = -11ns) + //Greater timing margins can be obtained by choosing specific ports. + //Please consult the "IO timings for xCORE200" document for details + switch(clock_divider) { case 4: // 500 / (4 * 2) = 62.50MHz. ~100ps margin read_delay_whole_clocks = 2; - set_port_no_sample_delay(dq_ah); - set_pad_delay(dq_ah, 2); + sample_delay = 0; + pad_delay = 2; break; case 5: // 500 / (5 * 2) = 50.00MHz. ~2.1ns margin read_delay_whole_clocks = 1; - set_port_sample_delay(dq_ah); - set_pad_delay(dq_ah, 1); + sample_delay = 1; + pad_delay = 1; break; case 6: // 500 / (6 * 2) = 41.67MHz. ~4.1ns margin read_delay_whole_clocks = 1; - set_port_sample_delay(dq_ah); - set_pad_delay(dq_ah, 3); + sample_delay = 1; + pad_delay = 3; break; case 7: // 500 / (7 * 2) = 35.71MHz. ~6.1ns margin read_delay_whole_clocks = 1; - set_port_sample_delay(dq_ah); - set_pad_delay(dq_ah, 5); + sample_delay = 1; + pad_delay = 5; break; case 8: // 500 / (8 * 2) = 31.25MHz. ~6.1ns margin read_delay_whole_clocks = 1; - set_port_no_sample_delay(dq_ah); - set_pad_delay(dq_ah, 0); + sample_delay = 0; + pad_delay = 0; break; case 9: // 500 / (9 * 2) = 27.78MHz. ~10.1ns margin read_delay_whole_clocks = 1; - set_port_no_sample_delay(dq_ah); - set_pad_delay(dq_ah, 0); + sample_delay = 0; + pad_delay = 0; break; case 10: // 500 / (10 * 2) = 25.00MHz. ~12.1ns margin read_delay_whole_clocks = 1; - set_port_no_sample_delay(dq_ah); - set_pad_delay(dq_ah, 0); + sample_delay = 0; + pad_delay = 0; break; // 83.33MHz may be possible with compromised setup/hold times and specific port usage. //case 3: // 500 / (3 * 2) = 83.33MHz. // read_delay_whole_clocks = 2; - // set_port_sample_delay(dq_ah); - // set_pad_delay(dq_ah, 2); + // sample_delay = 1; + // pad_delay = 2; // break; default: // Support for any frequency lower that 25MHz can be implemented by using // the 25MHz delay settings which will provide 12.7ns margin (plenty) @@ -164,6 +125,61 @@ static unsigned sdram_init( break; } #endif +} + +static void sdram_init( + out buffered port:32 dq_ah, + out buffered port:32 cas, + out buffered port:32 ras, + out buffered port:8 we, + out port clk, + clock cb, + unsigned cas_latency, + const static unsigned clock_divider, + unsigned sample_delay, + unsigned pad_delay) { + + timer T; + int time, t; + + //Do input from dq_ah to get it off the bus. Note use of asm to get around direction type of port + //This will help avoid contention if the code restarts with SDRAM in read mode for any reason + + unsigned tmp; + asm volatile("in %0, res[%1]" : "=r"(tmp) : "r"(dq_ah)); + + //Output NOP + partout(cas, 1, CTRL_CAS_NOP); + partout(ras, 1, CTRL_RAS_NOP); + partout(we, 1, CTRL_WE_NOP); + + sync(dq_ah); + stop_clock(cb); + + T :> time; + T when timerafter(time + 100 * TIMER_TICKS_PER_US) :> time; + + asm("setclk res[%0], %1"::"r"(cb), "r"(XS1_CLK_XCORE)); + set_clock_div(cb, clock_divider); + + set_port_clock(clk, cb); + set_port_mode_clock(clk); + + set_port_clock(dq_ah, cb); + set_port_clock(cas, cb); + set_port_clock(ras, cb); + set_port_clock(we, cb); + + // Setup pad and internal read delays to compensate for round trip delays + if (sample_delay) + { + set_port_sample_delay(dq_ah); + } + else + { + set_port_no_sample_delay(dq_ah); + } + set_pad_delay(dq_ah, pad_delay); start_clock(cb); @@ -235,9 +251,6 @@ static unsigned sdram_init( //Perform refresh of whole memory refresh(256, cas, ras); - - return (cas_latency + read_delay_whole_clocks); - } typedef struct { @@ -475,7 +488,18 @@ void sdram_server(streaming chanend c_client[client_count], cmd_buffer[i]->buffer = null; } - unsigned read_time_offset = sdram_init(dq_ah, cas, ras, we, clk, cb, cas_latency, clock_divider); + unsigned read_delay_whole_clocks; + unsigned sample_delay; + unsigned pad_delay; + + select_delays(clock_divider, read_delay_whole_clocks, sample_delay, pad_delay); + + sdram_init(dq_ah, cas, ras, we, clk, cb, cas_latency, + clock_divider, sample_delay, pad_delay); + + // This parameter is used to delay the read by a whole number of sdram clocks + // It is used to compensate for the large round trip delay time of the xcore IO + unsigned read_time_offset = cas_latency + read_delay_whole_clocks; unsafe { for(unsigned i=0;i Date: Wed, 19 Nov 2025 03:54:09 +0100 Subject: [PATCH 07/11] allow to pass read delay parameters to sdram_server - by introducing a new function, sdram_server_with_delays - it gets a none-const non-static clock divider and the three parameters which were before derived from this clock divider - the original sdram_server is functionally unchanged and implemented in terms of the new function, using the now called select_default_delays function - clock_divider is not used in time-critical code, all other const-static parameters are unchanged and therefore no new performance issues are created - the new sdram_server_with_delays function has following use cases + the SDRAM read timing depends very much on the users situation - SDRAM IC selection, PCB line capacities, XMOS CPU pin selection, pin driver current selection, temperature ranges, supply voltage levels - therefore it is an advantage if the user can specify these parameters in the application without a need to modify the lib_sdram library + the function allows to write a tool that would test various settings to see which timing ranges actually do work, to verify the theoretical considerations + it could make it possibly to reach higher SDRAM speeds using an adaptive timing, which means the working timing range is measured before the actual SDRAM use or in idle phases, by trial-and-error with varying settings --- lib_sdram/api/sdram.h | 50 ++++++++++++++++++++++++++++++ lib_sdram/src/server.xc | 67 ++++++++++++++++++++++++++++++++++------- 2 files changed, 106 insertions(+), 11 deletions(-) diff --git a/lib_sdram/api/sdram.h b/lib_sdram/api/sdram.h index 04f2bec..6f30698 100644 --- a/lib_sdram/api/sdram.h +++ b/lib_sdram/api/sdram.h @@ -51,6 +51,56 @@ void sdram_server(streaming chanend c_client[client_count], const static unsigned refresh_cycles, const static unsigned clock_divider); +/** + * Same as ``sdram_server``, but with a non-const-static clock divider + * and additional timing parameters adjusting the data input window. + * ``sdram_server`` uses defaults for these parameters depending on the clock divider. + * Refer to tools/sdram_timing_calculations for more information. + * + * \param c_client This is an ordered array of the streaming channels to the clients. It is in client + * priority order(element 0 being the highest priority). + * \param client_count The number of clients. + * \param dq_ah The data and address bus port. + * \param cas The CAS signal port. + * \param ras The RAS signal port. + * \param we The WE signal port. + * \param clk The SDRAM clock. + * \param cb Clock block to control the ports. + * \param cas_latency The CAS latency. + * \param row_words The number of 32b words in a SDRAM row (half the number of columns). + * \param col_bits The count of bits for a memory location, normally 16. + * \param col_address_bits The number of bits in the column address bus. + * \param row_address_bits The number of bits in the row address bus. + * \param bank_address_bits The number of bits in the bank address bus. + * \param refresh_ms The count of milliseconds for a full refresh cycle. + * \param refresh_cycles The count of refresh instructions per full refresh cycle. + * \param clock_divider The divider of the system clock to the SDRAM clock. + * \param read_delay_whole_clocks The number of SDRAM clock cycles (Tclk) to defer input reading + * \param sample_delay 1 for an extra 1/2 Tclk input reading delay, 0 for none + * \param pad_delay The number of core clock cycles (Tcore) to delay the input signal, + * in range 0..5. This has the effect of reading input earlier. + **/ +void sdram_server_with_delays(streaming chanend c_client[client_count], + const static unsigned client_count, + out buffered port:32 dq_ah, + out buffered port:32 cas, + out buffered port:32 ras, + out buffered port:8 we, + out port clk, + clock cb, + const static unsigned cas_latency, + const static unsigned row_words, + const static unsigned col_bits, + const static unsigned col_address_bits, + const static unsigned row_address_bits, + const static unsigned bank_address_bits, + const static unsigned refresh_ms, + const static unsigned refresh_cycles, + unsigned clock_divider, + unsigned read_delay_whole_clocks, + unsigned sample_delay, + unsigned pad_delay); + /** * This is used to initialise the sdram_state that follows the channel to the SDRAM server. It must only be called * once on the s_sdram_state that it is initialising. A client must have only one s_sdram_state that exists for the diff --git a/lib_sdram/src/server.xc b/lib_sdram/src/server.xc index 62d9c71..5cf14bd 100644 --- a/lib_sdram/src/server.xc +++ b/lib_sdram/src/server.xc @@ -25,8 +25,23 @@ static void refresh(unsigned ncycles, } } -static void select_delays( - const static unsigned clock_divider, +/** + * Function used by sdram_server to get default read time settings + * depending on the clock divider. + * See comments below for assumptions the function makes about the hardware. + * If the default delays do not fit your hardware situation, + * consider using sdram_server_with_delays. + * + * \param clock_divider The divider of the system clock to the SDRAM clock. + * \param read_delay_whole_clocks Returns the number of SDRAM clock cycles (Tclk) + * to defer input reading + * \param sample_delay Returns 1 for an extra 1/2 Tclk input reading delay, 0 for none + * \param pad_delay Returns the number of core clock cycles (Tcore) to delay the input + * signal, in range 0..5. This has the effect of reading input earlier. + * + **/ +static void select_default_delays( + const unsigned clock_divider, unsigned& read_delay_whole_clocks, unsigned& sample_delay, unsigned& pad_delay) { @@ -135,7 +150,7 @@ static void sdram_init( out port clk, clock cb, unsigned cas_latency, - const static unsigned clock_divider, + unsigned clock_divider, unsigned sample_delay, unsigned pad_delay) { @@ -459,7 +474,7 @@ static int handle_command(e_command cmd_type, sdram_cmd &cmd, #define XCORE_CLOCKS_PER_MS 100000 #pragma unsafe arrays -void sdram_server(streaming chanend c_client[client_count], +void sdram_server_with_delays(streaming chanend c_client[client_count], const static unsigned client_count, out buffered port:32 dq_ah, out buffered port:32 cas, @@ -475,7 +490,11 @@ void sdram_server(streaming chanend c_client[client_count], const static unsigned bank_address_bits, const static unsigned refresh_ms, const static unsigned refresh_cycles, - const static unsigned clock_divider){ + unsigned clock_divider, + unsigned read_delay_whole_clocks, + unsigned sample_delay, + unsigned pad_delay) { + timer t; unsigned time; sdram_cmd cmd_buffer[7][SDRAM_MAX_CMD_BUFFER]; @@ -488,12 +507,6 @@ void sdram_server(streaming chanend c_client[client_count], cmd_buffer[i]->buffer = null; } - unsigned read_delay_whole_clocks; - unsigned sample_delay; - unsigned pad_delay; - - select_delays(clock_divider, read_delay_whole_clocks, sample_delay, pad_delay); - sdram_init(dq_ah, cas, ras, we, clk, cb, cas_latency, clock_divider, sample_delay, pad_delay); @@ -547,3 +560,35 @@ void sdram_server(streaming chanend c_client[client_count], } } } + +#pragma unsafe arrays +void sdram_server(streaming chanend c_client[client_count], + const static unsigned client_count, + out buffered port:32 dq_ah, + out buffered port:32 cas, + out buffered port:32 ras, + out buffered port:8 we, + out port clk, + clock cb, + const static unsigned cas_latency, + const static unsigned row_words, + const static unsigned col_bits, + const static unsigned col_address_bits, + const static unsigned row_address_bits, + const static unsigned bank_address_bits, + const static unsigned refresh_ms, + const static unsigned refresh_cycles, + const unsigned clock_divider){ + + unsigned read_delay_whole_clocks; + unsigned sample_delay; + unsigned pad_delay; + + select_default_delays(clock_divider, read_delay_whole_clocks, sample_delay, pad_delay); + + sdram_server_with_delays(c_client, client_count, + dq_ah, cas, ras, we, clk, cb, + cas_latency, row_words, col_bits, col_address_bits, + row_address_bits, bank_address_bits, refresh_ms, refresh_cycles, + clock_divider, read_delay_whole_clocks, sample_delay, pad_delay); +} From ff51b5124abed72e9491c82535b5e388a0341e43 Mon Sep 17 00:00:00 2001 From: errsu Date: Thu, 20 Nov 2025 01:58:16 +0100 Subject: [PATCH 08/11] add an sdram_timing_test - that tests read delay parameter combinations for clock dividers from 4 to 12 and prints out which work and which not - does a single write/read test with fixed and walking 1 pattern and whole memory test with random pattern --- tools/CMakeLists.txt | 1 + tools/sdram_timing_test/CMakeLists.txt | 16 + tools/sdram_timing_test/SLICEKIT-XC200-X1.xn | 74 +++++ tools/sdram_timing_test/config.xscope | 2 + .../src/sdram_timing_test.xc | 281 ++++++++++++++++++ .../xcore_ai_sdram_test_board.xn | 55 ++++ 6 files changed, 429 insertions(+) create mode 100644 tools/sdram_timing_test/CMakeLists.txt create mode 100644 tools/sdram_timing_test/SLICEKIT-XC200-X1.xn create mode 100644 tools/sdram_timing_test/config.xscope create mode 100644 tools/sdram_timing_test/src/sdram_timing_test.xc create mode 100644 tools/sdram_timing_test/xcore_ai_sdram_test_board.xn diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 8729b33..ca3f074 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -3,3 +3,4 @@ include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake) project(lib_sdram_tools) add_subdirectory(sdram_timing_calculations) +add_subdirectory(sdram_timing_test) diff --git a/tools/sdram_timing_test/CMakeLists.txt b/tools/sdram_timing_test/CMakeLists.txt new file mode 100644 index 0000000..cf95dc1 --- /dev/null +++ b/tools/sdram_timing_test/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.21) +include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake) +project(sdram_timing_test) + +set(APP_HW_TARGET SLICEKIT-XC200-X1.xn) +#set(APP_HW_TARGET xcore_ai_sdram_test_board.xn) + +set(APP_DEPENDENT_MODULES "lib_sdram") +set(APP_INCLUDES src) +set(APP_COMPILER_FLAGS -g -O2) + +set(APP_PCA_ENABLE ON) + +set(XMOS_SANDBOX_DIR ${CMAKE_CURRENT_LIST_DIR}/../../..) + +XMOS_REGISTER_APP() diff --git a/tools/sdram_timing_test/SLICEKIT-XC200-X1.xn b/tools/sdram_timing_test/SLICEKIT-XC200-X1.xn new file mode 100644 index 0000000..20e6c91 --- /dev/null +++ b/tools/sdram_timing_test/SLICEKIT-XC200-X1.xn @@ -0,0 +1,74 @@ + + + Board + sliceKIT Core Board (XC200) + + + + tileref tile[2] + tileref usb_tile + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/sdram_timing_test/config.xscope b/tools/sdram_timing_test/config.xscope new file mode 100644 index 0000000..fd50384 --- /dev/null +++ b/tools/sdram_timing_test/config.xscope @@ -0,0 +1,2 @@ + + diff --git a/tools/sdram_timing_test/src/sdram_timing_test.xc b/tools/sdram_timing_test/src/sdram_timing_test.xc new file mode 100644 index 0000000..b6cbc76 --- /dev/null +++ b/tools/sdram_timing_test/src/sdram_timing_test.xc @@ -0,0 +1,281 @@ +#include +#include +#include +#include "sdram.h" + +#define VERBOSE_MSG 1 +#define ERROR_MSG 0 + +//For XS2 (xCORE200) put an SDRAM slice into the 'triangle' slot of tile 0 of the XP-SKC-X200 slice kit +//If using 256Mb slice, then define USE_256Mb below, otherwise leave commented out + +#define SDRAM_256Mb 1 //Use IS42S16160D 256Mb or similar +#define SDRAM_128Mb 0 //Use IS42S16800D 128Mb + //otherwise IS42S16400D 64Mb which is default on XMOS boards + +#define CAS_LATENCY 2 +#define REFRESH_MS 64 +#define DATA_BITS 16 + +#if SDRAM_256Mb +#define REFRESH_CYCLES 8192 +#define COL_ADDRESS_BITS 9 +#define ROW_ADDRESS_BITS 13 +#define BANK_ADDRESS_BITS 2 +#define BANK_COUNT 4 +#define ROW_COUNT 8192 +#define ROW_WORDS 256 +#elif SDRAM_128Mb +#define REFRESH_CYCLES 4096 +#define COL_ADDRESS_BITS 9 +#define ROW_ADDRESS_BITS 12 +#define BANK_ADDRESS_BITS 2 +#define BANK_COUNT 4 +#define ROW_COUNT 4096 +#define ROW_WORDS 256 +#else +#define REFRESH_CYCLES 4096 +#define COL_ADDRESS_BITS 8 +#define ROW_ADDRESS_BITS 12 +#define BANK_ADDRESS_BITS 2 +#define BANK_COUNT 4 +#define ROW_COUNT 4096 +#define ROW_WORDS 128 +#endif + +#if defined(__XS3A__) +// SDRAM test board for XU316 +#define SERVER_TILE 1 +on tile[SERVER_TILE] : out buffered port:32 sdram_dq_ah = XS1_PORT_16A; +on tile[SERVER_TILE] : out buffered port:32 sdram_cas = XS1_PORT_1A; +on tile[SERVER_TILE] : out buffered port:32 sdram_ras = XS1_PORT_1P; +on tile[SERVER_TILE] : out buffered port:8 sdram_we = XS1_PORT_1M; +on tile[SERVER_TILE] : out port sdram_clk = XS1_PORT_1F; +on tile[SERVER_TILE] : clock sdram_cb = XS1_CLKBLK_1; +#elif defined(__XS2A__) +//Triangle slot tile 0 for XU216 +#define SERVER_TILE 0 +on tile[SERVER_TILE] : out buffered port:32 sdram_dq_ah = XS1_PORT_16B; +on tile[SERVER_TILE] : out buffered port:32 sdram_cas = XS1_PORT_1J; +on tile[SERVER_TILE] : out buffered port:32 sdram_ras = XS1_PORT_1I; +on tile[SERVER_TILE] : out buffered port:8 sdram_we = XS1_PORT_1K; +on tile[SERVER_TILE] : out port sdram_clk = XS1_PORT_1L; +on tile[SERVER_TILE] : clock sdram_cb = XS1_CLKBLK_2; +#else +//Square slot on A16 slicekit +#define SERVER_TILE 1 +on tile[SERVER_TILE] : out buffered port:32 sdram_dq_ah = XS1_PORT_16A; +on tile[SERVER_TILE] : out buffered port:32 sdram_cas = XS1_PORT_1B; +on tile[SERVER_TILE] : out buffered port:32 sdram_ras = XS1_PORT_1G; +on tile[SERVER_TILE] : out buffered port:8 sdram_we = XS1_PORT_1C; +on tile[SERVER_TILE] : out port sdram_clk = XS1_PORT_1F; +on tile[SERVER_TILE] : clock sdram_cb = XS1_CLKBLK_2; +#endif + +unsigned get_core_frequency() +{ + unsigned pll_ctl_value; + + read_sswitch_reg(get_local_tile_id(), XS1_SSWITCH_PLL_CTL_NUM, pll_ctl_value); + + unsigned OD = (pll_ctl_value >> 23) & 0x7; + unsigned F = (pll_ctl_value >> 8) & 0x1FFF; + unsigned R = (pll_ctl_value >> 0) & 0x3F; + unsigned f_osc = 24000000; + unsigned f_core = (f_osc / 2) * (F+1) / ((R+1) * (OD+1)); + return f_core; +} + +unsigned sdram_tester(streaming chanend c_server) +{ +#define BUF_WORDS (512) + unsigned read_buffer[BUF_WORDS]; + unsigned write_buffer[BUF_WORDS]; + unsigned * movable read_buffer_pointer = read_buffer; + unsigned * movable write_buffer_pointer = write_buffer; + + s_sdram_state sdram_state; + sdram_init_state(c_server, sdram_state); + + // fixed pattern / single r/w test + + for (unsigned i = 0; i < BUF_WORDS; i++) + { + write_buffer_pointer[i] = 0xcafebabe; + read_buffer_pointer[i] = 0; // clear read pointer + } + + sdram_write(c_server, sdram_state, 0x0, BUF_WORDS, move(write_buffer_pointer)); + sdram_complete(c_server, sdram_state, write_buffer_pointer); + + sdram_read(c_server, sdram_state, 0x0, BUF_WORDS, move(read_buffer_pointer)); + sdram_complete(c_server, sdram_state, read_buffer_pointer); + + for (unsigned i = 0; i < BUF_WORDS; i++) + { + if (read_buffer_pointer[i] != write_buffer_pointer[i]) + { + if (ERROR_MSG) + { + printf("fixed pattern at address 0x%x written %08x read %08x\n", + i, write_buffer_pointer[i], read_buffer_pointer[i]); + } + return 0; + } + } + + // walking 1 pattern / single r/w test + for (unsigned i = 0; i < BUF_WORDS; i++) + { + write_buffer_pointer[i] = 1 << i; + read_buffer_pointer[i] = 0; // clear read pointer + } + + sdram_write(c_server, sdram_state, 0x0, BUF_WORDS, move(write_buffer_pointer)); + sdram_complete(c_server, sdram_state, write_buffer_pointer); + + sdram_read(c_server, sdram_state, 0x0, BUF_WORDS, move(read_buffer_pointer)); + sdram_complete(c_server, sdram_state, read_buffer_pointer); + + for (unsigned i = 0; i < BUF_WORDS; i++) + { + if (read_buffer_pointer[i] != write_buffer_pointer[i]) + { + if (ERROR_MSG) + { + printf("walking 1 pattern at address 0x%x written %08x read %08x\n", + i, write_buffer_pointer[i], read_buffer_pointer[i]); + } + return 0; + } + } + + // random pattern / whole memory test + for (unsigned i = 0; i < BUF_WORDS; i++) + { + write_buffer_pointer[i] = rand(); + } + + for (unsigned address = 0; address < 4096 * BUF_WORDS; address += BUF_WORDS) + { + // uncomment to simulate an error + // unsigned temp; + // if (address == 1024 * BUF_WORDS) { + // temp = write_buffer_pointer[20]; + // write_buffer_pointer[20] = 0xdeadbeef; + // } + sdram_write(c_server, sdram_state, address, BUF_WORDS, move(write_buffer_pointer)); + sdram_complete(c_server, sdram_state, write_buffer_pointer); + // if (address == 1024 * BUF_WORDS) { + // write_buffer_pointer[20] = temp; + // } + } + + for (unsigned address = 0; address < 4096 * BUF_WORDS; address += BUF_WORDS) + { + // clear read buffer + for (unsigned i = 0; i < BUF_WORDS; i++) + { + read_buffer_pointer[i] = 0; + } + + sdram_read (c_server, sdram_state, address, BUF_WORDS, move( read_buffer_pointer)); + sdram_complete(c_server, sdram_state, read_buffer_pointer); + for (unsigned i = 0; i < BUF_WORDS; i++) + { + if (read_buffer_pointer[i] != write_buffer_pointer[i]) + { + if (ERROR_MSG) + { + printf("random pattern at address 0x%x written %08x read %08x\n", + address + i, write_buffer_pointer[i], read_buffer_pointer[i]); + } + return 0; + } + } + } + return 1; +} + +void sdram_test(unsigned clock_divider, + unsigned read_delay_whole_clocks, + unsigned sample_delay, + unsigned pad_delay) +{ + streaming chan c_sdram[1]; + unsigned success; + + par + { + { + set_core_high_priority_on(); + sdram_server_with_delays(c_sdram, 1, sdram_dq_ah, sdram_cas, sdram_ras, + sdram_we, sdram_clk, sdram_cb, + CAS_LATENCY, ROW_WORDS, DATA_BITS, + COL_ADDRESS_BITS, ROW_ADDRESS_BITS, BANK_ADDRESS_BITS, + REFRESH_MS, REFRESH_CYCLES, + clock_divider, read_delay_whole_clocks, sample_delay, pad_delay); + } + { + set_core_high_priority_on(); + success = sdram_tester(c_sdram[0]); + sdram_shutdown(c_sdram[0]); + } + } + printf("div: %2d read: %d sample: %d pad: %d result: %d\n", + clock_divider, read_delay_whole_clocks, sample_delay, pad_delay, success); +} + +void sdram_test_suite() +{ + if (VERBOSE_MSG) + { +#if SDRAM_256Mb + printf("Using 256Mb SDRAM\n"); +#elif SDRAM_128Mb + printf("Using 128Mb SDRAM\n"); +#else + printf("Using 64Mb SDRAM\n"); +#endif + printf("starting SDRAM tests\n"); + } + + unsigned f_core = get_core_frequency(); + + for (unsigned clock_divider = 4; clock_divider < 13; clock_divider++) + { + if (VERBOSE_MSG) + { + unsigned f_core_MHz = f_core / 1000000; + printf("\nF_core: %d MHz, clock divider: %d, F_clk: %d.%02d MHz\n", + f_core_MHz, clock_divider, + f_core_MHz / (2 * clock_divider), + (f_core_MHz * 50 / clock_divider) % 100); + } + for (unsigned read_delay_clocks = 0; read_delay_clocks < 3; read_delay_clocks++) + { + for (unsigned sample_delay = 0; sample_delay < 2; sample_delay++) + { + for (unsigned i = 0; i < 6; i++) + { + unsigned pad_delay = 5 - i; + sdram_test(clock_divider, read_delay_clocks, sample_delay, pad_delay); + } + } + } + } + if (VERBOSE_MSG) + { + printf("SDRAM tests finished\n\n"); + } +} + +int main() +{ + par + { + on tile[SERVER_TILE]: sdram_test_suite(); + on tile[SERVER_TILE]: par(int i=0;i<6;i++) while(1); + } + return 0; +} diff --git a/tools/sdram_timing_test/xcore_ai_sdram_test_board.xn b/tools/sdram_timing_test/xcore_ai_sdram_test_board.xn new file mode 100644 index 0000000..dca6088 --- /dev/null +++ b/tools/sdram_timing_test/xcore_ai_sdram_test_board.xn @@ -0,0 +1,55 @@ + + + Board + xcore-ai SDRAM Test Board + + + tileref tile[2] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From d9fa2496846ab4193f1d28336e98b83c20868422 Mon Sep 17 00:00:00 2001 From: errsu Date: Thu, 20 Nov 2025 13:07:46 +0100 Subject: [PATCH 09/11] join SDRAM timing calculation and test into one tool - this allows to compare theoretical and practical results easily - provide calculation and actual test results compared to default values chosen in lib_sdram/src/server.xc --- tools/CMakeLists.txt | 3 +- .../CMakeLists.txt | 7 +- tools/sdram_timing/README.rst | 84 +++ .../SLICEKIT-XC200-X1.xn | 0 .../config.xscope | 0 tools/sdram_timing/results.txt | 714 ++++++++++++++++++ tools/sdram_timing/src/sdram_calc.h | 13 + .../src/sdram_calc.xc} | 99 ++- tools/sdram_timing/src/sdram_ports.h | 30 + tools/sdram_timing/src/sdram_test.h | 7 + .../src/sdram_test.xc} | 129 +--- tools/sdram_timing/src/sdram_timing.xc | 104 +++ .../xcore_ai_sdram_test_board.xn | 0 .../sdram_timing_calculations/CMakeLists.txt | 12 - tools/sdram_timing_calculations/README.rst | 57 -- 15 files changed, 1035 insertions(+), 224 deletions(-) rename tools/{sdram_timing_test => sdram_timing}/CMakeLists.txt (64%) create mode 100644 tools/sdram_timing/README.rst rename tools/{sdram_timing_test => sdram_timing}/SLICEKIT-XC200-X1.xn (100%) rename tools/{sdram_timing_test => sdram_timing}/config.xscope (100%) create mode 100644 tools/sdram_timing/results.txt create mode 100644 tools/sdram_timing/src/sdram_calc.h rename tools/{sdram_timing_calculations/src/sdram_timing_calculations.c => sdram_timing/src/sdram_calc.xc} (66%) create mode 100644 tools/sdram_timing/src/sdram_ports.h create mode 100644 tools/sdram_timing/src/sdram_test.h rename tools/{sdram_timing_test/src/sdram_timing_test.xc => sdram_timing/src/sdram_test.xc} (56%) create mode 100644 tools/sdram_timing/src/sdram_timing.xc rename tools/{sdram_timing_test => sdram_timing}/xcore_ai_sdram_test_board.xn (100%) delete mode 100644 tools/sdram_timing_calculations/CMakeLists.txt delete mode 100644 tools/sdram_timing_calculations/README.rst diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index ca3f074..abc3028 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -2,5 +2,4 @@ cmake_minimum_required(VERSION 3.21) include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake) project(lib_sdram_tools) -add_subdirectory(sdram_timing_calculations) -add_subdirectory(sdram_timing_test) +add_subdirectory(sdram_timing) diff --git a/tools/sdram_timing_test/CMakeLists.txt b/tools/sdram_timing/CMakeLists.txt similarity index 64% rename from tools/sdram_timing_test/CMakeLists.txt rename to tools/sdram_timing/CMakeLists.txt index cf95dc1..abdaaed 100644 --- a/tools/sdram_timing_test/CMakeLists.txt +++ b/tools/sdram_timing/CMakeLists.txt @@ -1,9 +1,10 @@ cmake_minimum_required(VERSION 3.21) include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake) -project(sdram_timing_test) +project(sdram_timing) -set(APP_HW_TARGET SLICEKIT-XC200-X1.xn) -#set(APP_HW_TARGET xcore_ai_sdram_test_board.xn) +set(APP_HW_TARGET SLICEKIT-XC200-X1.xn) +#set(APP_HW_TARGET xcore_ai_sdram_test_board.xn) +#set(APP_HW_TARGET XU316-1024-FB265-C24) set(APP_DEPENDENT_MODULES "lib_sdram") set(APP_INCLUDES src) diff --git a/tools/sdram_timing/README.rst b/tools/sdram_timing/README.rst new file mode 100644 index 0000000..06c2a1d --- /dev/null +++ b/tools/sdram_timing/README.rst @@ -0,0 +1,84 @@ +SDRAM Data Input Timing Calc&Test +================================= + +:scope: Tools +:description: Tool to find input delays matching the round trip window +:keywords: Memory,SDRAM,Round Trip Time +:boards: custom board with xcore-ai and SDRAM, XS2 slicekit with SDRAM slice + +The tool calculates suitability of read delays for the SDRAM data input, +using parameters from the datasheets and assumptions about the board parameters. +It also tests these read delays and shows the results in a table for comparison. + +How to use +---------- + +Preparations + +- edit timing parameters in sdram_calc.xc according to your SDRAM datasheet, + the XMOS timing papers (linked in top level README) and your board situation +- adapt SDRAM port selection in sdram_ports.h +- select your SDRAM type (SDRAM_256Mb/SDRAM_128Mb/64Mb) in sdram_test.xc, + possibly adapt the SDRAM configuration parameters at the same place +- select your board or create a new one in CMakeLists.txt +- switch between JTAG IO and XScope in config.xscope + +To build and run (with XTC 15.3.x):: + +> cd lib_sdram\tools\sdram_timing\ +> cmake -G "Unix Makefiles" -B build +> xmake -C build + +If your board supports XScope:: + +> xrun --xscope .\bin\sdram_timing.xe + +If you want to use JTAG IO:: + +> xrun --io .\bin\sdram_timing.xe + +If you don't have hardware or just want to do the calculations + +- set #define TEST to 0 in sdram_timing.xc +- select DEFAULT_FCORE at the same place +- disable XScope in config.xscope + +then:: + +> xsim .\bin\sdram_timing.xe + +The results per setting are shown as follows (refer to comments in sdram_calc.xc):: + + F_core: 600 MHz, clock divider: 6, F_clk: 50.00 MHz + div: 6 read: 1 sample: 1 pad: 2 [40.558 ( -0.574) 39.984 ( 4.600) 44.584] calc: 0 test: 1 + div: 6 read: 1 sample: 1 pad: 1 [38.892 ( 1.092) 39.984 ( 2.934) 42.918] calc: 1 test: 1 + div: 6 read: 1 sample: 1 pad: 0 [37.226 ( 2.758) 39.984 ( 1.268) 41.252] calc: 1 test: 1 + div: 6 read: 2 sample: 0 pad: 5 [45.556 ( 4.424) 49.980 ( -0.398) 49.582] calc: 0 test: 1 + ^ ^ ^ ^ \_________________________________________/ ^ ^ + | | | | ^ | | + | | | | | | | + | | | | read window --------- | | + | | | | | | + | | | | 1 if read time fits in calculated read window --- | + | | | | 1 if the hardware test succeeded ----------- + | | | | + | | | -------------- pad_delay (0..5) + | | --------------------- sample_delay 0 or 1 + | ------------------------------- read_delay_clocks (0..2) + --------------------------------------- clock_divider (4..12) + +The read window timing is shown in nanoseconds from falling clock edge:: + + [40.558 ( -0.574) 39.984 ( 4.600) 44.584] + ^ ^ ^ ^ ^ + | | | | | + read windows start --- | | | | + start margin ------------- | | | + read time --------------------- | | + end margin ------------------------------ | + read window end --------------------------------------- + +A negative margin means that there is none. +So, theoretically, such setting cannot reliably work. +In practice, some of the assumptions about hardware +latencies are relatively weak. diff --git a/tools/sdram_timing_test/SLICEKIT-XC200-X1.xn b/tools/sdram_timing/SLICEKIT-XC200-X1.xn similarity index 100% rename from tools/sdram_timing_test/SLICEKIT-XC200-X1.xn rename to tools/sdram_timing/SLICEKIT-XC200-X1.xn diff --git a/tools/sdram_timing_test/config.xscope b/tools/sdram_timing/config.xscope similarity index 100% rename from tools/sdram_timing_test/config.xscope rename to tools/sdram_timing/config.xscope diff --git a/tools/sdram_timing/results.txt b/tools/sdram_timing/results.txt new file mode 100644 index 0000000..1d37771 --- /dev/null +++ b/tools/sdram_timing/results.txt @@ -0,0 +1,714 @@ +SDRAM timing calculation and test results +========================================= + +The default delays selected in lib_sdram/src/server.xc +are marked with ***. + +XS2 Results +----------- + +Tested on a XP-SKC-X200 sliceboard (XE216-512-FB236 CPU) +with XA-SK-SDRAM slice (64Mbit IS42S16400F-7). + +Using 64Mb SDRAM +Round trip time min: 12400 ps, max: 22700 ps +starting SDRAM timing + +F_core: 500 MHz, clock divider: 4, F_clk: 62.50 MHz +div: 4 read: 0 sample: 0 pad: 5 [46.700 (-38.700) 8.000 ( 40.900) 48.900] calc: 0 test: 0 +div: 4 read: 0 sample: 0 pad: 4 [44.700 (-36.700) 8.000 ( 38.900) 46.900] calc: 0 test: 0 +div: 4 read: 0 sample: 0 pad: 3 [42.700 (-34.700) 8.000 ( 36.900) 44.900] calc: 0 test: 0 +div: 4 read: 0 sample: 0 pad: 2 [40.700 (-32.700) 8.000 ( 34.900) 42.900] calc: 0 test: 0 +div: 4 read: 0 sample: 0 pad: 1 [38.700 (-30.700) 8.000 ( 32.900) 40.900] calc: 0 test: 0 +div: 4 read: 0 sample: 0 pad: 0 [36.700 (-28.700) 8.000 ( 30.900) 38.900] calc: 0 test: 0 +div: 4 read: 0 sample: 1 pad: 5 [46.700 (-30.700) 16.000 ( 32.900) 48.900] calc: 0 test: 0 +div: 4 read: 0 sample: 1 pad: 4 [44.700 (-28.700) 16.000 ( 30.900) 46.900] calc: 0 test: 0 +div: 4 read: 0 sample: 1 pad: 3 [42.700 (-26.700) 16.000 ( 28.900) 44.900] calc: 0 test: 0 +div: 4 read: 0 sample: 1 pad: 2 [40.700 (-24.700) 16.000 ( 26.900) 42.900] calc: 0 test: 0 +div: 4 read: 0 sample: 1 pad: 1 [38.700 (-22.700) 16.000 ( 24.900) 40.900] calc: 0 test: 0 +div: 4 read: 0 sample: 1 pad: 0 [36.700 (-20.700) 16.000 ( 22.900) 38.900] calc: 0 test: 0 +div: 4 read: 1 sample: 0 pad: 5 [46.700 (-22.700) 24.000 ( 24.900) 48.900] calc: 0 test: 0 +div: 4 read: 1 sample: 0 pad: 4 [44.700 (-20.700) 24.000 ( 22.900) 46.900] calc: 0 test: 0 +div: 4 read: 1 sample: 0 pad: 3 [42.700 (-18.700) 24.000 ( 20.900) 44.900] calc: 0 test: 0 +div: 4 read: 1 sample: 0 pad: 2 [40.700 (-16.700) 24.000 ( 18.900) 42.900] calc: 0 test: 0 +div: 4 read: 1 sample: 0 pad: 1 [38.700 (-14.700) 24.000 ( 16.900) 40.900] calc: 0 test: 0 +div: 4 read: 1 sample: 0 pad: 0 [36.700 (-12.700) 24.000 ( 14.900) 38.900] calc: 0 test: 0 +div: 4 read: 1 sample: 1 pad: 5 [46.700 (-14.700) 32.000 ( 16.900) 48.900] calc: 0 test: 0 +div: 4 read: 1 sample: 1 pad: 4 [44.700 (-12.700) 32.000 ( 14.900) 46.900] calc: 0 test: 0 +div: 4 read: 1 sample: 1 pad: 3 [42.700 (-10.700) 32.000 ( 12.900) 44.900] calc: 0 test: 1 +div: 4 read: 1 sample: 1 pad: 2 [40.700 ( -8.700) 32.000 ( 10.900) 42.900] calc: 0 test: 1 +div: 4 read: 1 sample: 1 pad: 1 [38.700 ( -6.700) 32.000 ( 8.900) 40.900] calc: 0 test: 1 +div: 4 read: 1 sample: 1 pad: 0 [36.700 ( -4.700) 32.000 ( 6.900) 38.900] calc: 0 test: 1 +div: 4 read: 2 sample: 0 pad: 5 [46.700 ( -6.700) 40.000 ( 8.900) 48.900] calc: 0 test: 1 +div: 4 read: 2 sample: 0 pad: 4 [44.700 ( -4.700) 40.000 ( 6.900) 46.900] calc: 0 test: 1 +div: 4 read: 2 sample: 0 pad: 3 [42.700 ( -2.700) 40.000 ( 4.900) 44.900] calc: 0 test: 1 +div: 4 read: 2 sample: 0 pad: 2 [40.700 ( -0.700) 40.000 ( 2.900) 42.900] calc: 0 test: 1 *** +div: 4 read: 2 sample: 0 pad: 1 [38.700 ( 1.300) 40.000 ( 0.900) 40.900] calc: 1 test: 0 +div: 4 read: 2 sample: 0 pad: 0 [36.700 ( 3.300) 40.000 ( -1.100) 38.900] calc: 0 test: 0 +div: 4 read: 2 sample: 1 pad: 5 [46.700 ( 1.300) 48.000 ( 0.900) 48.900] calc: 1 test: 0 +div: 4 read: 2 sample: 1 pad: 4 [44.700 ( 3.300) 48.000 ( -1.100) 46.900] calc: 0 test: 0 +div: 4 read: 2 sample: 1 pad: 3 [42.700 ( 5.300) 48.000 ( -3.100) 44.900] calc: 0 test: 0 +div: 4 read: 2 sample: 1 pad: 2 [40.700 ( 7.300) 48.000 ( -5.100) 42.900] calc: 0 test: 0 +div: 4 read: 2 sample: 1 pad: 1 [38.700 ( 9.300) 48.000 ( -7.100) 40.900] calc: 0 test: 0 +div: 4 read: 2 sample: 1 pad: 0 [36.700 ( 11.300) 48.000 ( -9.100) 38.900] calc: 0 test: 0 + +F_core: 500 MHz, clock divider: 5, F_clk: 50.00 MHz +div: 5 read: 0 sample: 0 pad: 5 [48.700 (-38.700) 10.000 ( 44.900) 54.900] calc: 0 test: 0 +div: 5 read: 0 sample: 0 pad: 4 [46.700 (-36.700) 10.000 ( 42.900) 52.900] calc: 0 test: 0 +div: 5 read: 0 sample: 0 pad: 3 [44.700 (-34.700) 10.000 ( 40.900) 50.900] calc: 0 test: 0 +div: 5 read: 0 sample: 0 pad: 2 [42.700 (-32.700) 10.000 ( 38.900) 48.900] calc: 0 test: 0 +div: 5 read: 0 sample: 0 pad: 1 [40.700 (-30.700) 10.000 ( 36.900) 46.900] calc: 0 test: 0 +div: 5 read: 0 sample: 0 pad: 0 [38.700 (-28.700) 10.000 ( 34.900) 44.900] calc: 0 test: 0 +div: 5 read: 0 sample: 1 pad: 5 [48.700 (-28.700) 20.000 ( 34.900) 54.900] calc: 0 test: 0 +div: 5 read: 0 sample: 1 pad: 4 [46.700 (-26.700) 20.000 ( 32.900) 52.900] calc: 0 test: 0 +div: 5 read: 0 sample: 1 pad: 3 [44.700 (-24.700) 20.000 ( 30.900) 50.900] calc: 0 test: 0 +div: 5 read: 0 sample: 1 pad: 2 [42.700 (-22.700) 20.000 ( 28.900) 48.900] calc: 0 test: 0 +div: 5 read: 0 sample: 1 pad: 1 [40.700 (-20.700) 20.000 ( 26.900) 46.900] calc: 0 test: 0 +div: 5 read: 0 sample: 1 pad: 0 [38.700 (-18.700) 20.000 ( 24.900) 44.900] calc: 0 test: 0 +div: 5 read: 1 sample: 0 pad: 5 [48.700 (-18.700) 30.000 ( 24.900) 54.900] calc: 0 test: 0 +div: 5 read: 1 sample: 0 pad: 4 [46.700 (-16.700) 30.000 ( 22.900) 52.900] calc: 0 test: 0 +div: 5 read: 1 sample: 0 pad: 3 [44.700 (-14.700) 30.000 ( 20.900) 50.900] calc: 0 test: 0 +div: 5 read: 1 sample: 0 pad: 2 [42.700 (-12.700) 30.000 ( 18.900) 48.900] calc: 0 test: 0 +div: 5 read: 1 sample: 0 pad: 1 [40.700 (-10.700) 30.000 ( 16.900) 46.900] calc: 0 test: 1 +div: 5 read: 1 sample: 0 pad: 0 [38.700 ( -8.700) 30.000 ( 14.900) 44.900] calc: 0 test: 1 +div: 5 read: 1 sample: 1 pad: 5 [48.700 ( -8.700) 40.000 ( 14.900) 54.900] calc: 0 test: 1 +div: 5 read: 1 sample: 1 pad: 4 [46.700 ( -6.700) 40.000 ( 12.900) 52.900] calc: 0 test: 1 +div: 5 read: 1 sample: 1 pad: 3 [44.700 ( -4.700) 40.000 ( 10.900) 50.900] calc: 0 test: 1 +div: 5 read: 1 sample: 1 pad: 2 [42.700 ( -2.700) 40.000 ( 8.900) 48.900] calc: 0 test: 1 +div: 5 read: 1 sample: 1 pad: 1 [40.700 ( -0.700) 40.000 ( 6.900) 46.900] calc: 0 test: 1 *** +div: 5 read: 1 sample: 1 pad: 0 [38.700 ( 1.300) 40.000 ( 4.900) 44.900] calc: 1 test: 1 +div: 5 read: 2 sample: 0 pad: 5 [48.700 ( 1.300) 50.000 ( 4.900) 54.900] calc: 1 test: 1 +div: 5 read: 2 sample: 0 pad: 4 [46.700 ( 3.300) 50.000 ( 2.900) 52.900] calc: 1 test: 1 +div: 5 read: 2 sample: 0 pad: 3 [44.700 ( 5.300) 50.000 ( 0.900) 50.900] calc: 1 test: 0 +div: 5 read: 2 sample: 0 pad: 2 [42.700 ( 7.300) 50.000 ( -1.100) 48.900] calc: 0 test: 0 +div: 5 read: 2 sample: 0 pad: 1 [40.700 ( 9.300) 50.000 ( -3.100) 46.900] calc: 0 test: 0 +div: 5 read: 2 sample: 0 pad: 0 [38.700 ( 11.300) 50.000 ( -5.100) 44.900] calc: 0 test: 0 +div: 5 read: 2 sample: 1 pad: 5 [48.700 ( 11.300) 60.000 ( -5.100) 54.900] calc: 0 test: 0 +div: 5 read: 2 sample: 1 pad: 4 [46.700 ( 13.300) 60.000 ( -7.100) 52.900] calc: 0 test: 0 +div: 5 read: 2 sample: 1 pad: 3 [44.700 ( 15.300) 60.000 ( -9.100) 50.900] calc: 0 test: 0 +div: 5 read: 2 sample: 1 pad: 2 [42.700 ( 17.300) 60.000 (-11.100) 48.900] calc: 0 test: 0 +div: 5 read: 2 sample: 1 pad: 1 [40.700 ( 19.300) 60.000 (-13.100) 46.900] calc: 0 test: 0 +div: 5 read: 2 sample: 1 pad: 0 [38.700 ( 21.300) 60.000 (-15.100) 44.900] calc: 0 test: 0 + +F_core: 500 MHz, clock divider: 6, F_clk: 41.66 MHz +div: 6 read: 0 sample: 0 pad: 5 [50.700 (-38.700) 12.000 ( 48.900) 60.900] calc: 0 test: 0 +div: 6 read: 0 sample: 0 pad: 4 [48.700 (-36.700) 12.000 ( 46.900) 58.900] calc: 0 test: 0 +div: 6 read: 0 sample: 0 pad: 3 [46.700 (-34.700) 12.000 ( 44.900) 56.900] calc: 0 test: 0 +div: 6 read: 0 sample: 0 pad: 2 [44.700 (-32.700) 12.000 ( 42.900) 54.900] calc: 0 test: 0 +div: 6 read: 0 sample: 0 pad: 1 [42.700 (-30.700) 12.000 ( 40.900) 52.900] calc: 0 test: 0 +div: 6 read: 0 sample: 0 pad: 0 [40.700 (-28.700) 12.000 ( 38.900) 50.900] calc: 0 test: 0 +div: 6 read: 0 sample: 1 pad: 5 [50.700 (-26.700) 24.000 ( 36.900) 60.900] calc: 0 test: 0 +div: 6 read: 0 sample: 1 pad: 4 [48.700 (-24.700) 24.000 ( 34.900) 58.900] calc: 0 test: 0 +div: 6 read: 0 sample: 1 pad: 3 [46.700 (-22.700) 24.000 ( 32.900) 56.900] calc: 0 test: 0 +div: 6 read: 0 sample: 1 pad: 2 [44.700 (-20.700) 24.000 ( 30.900) 54.900] calc: 0 test: 0 +div: 6 read: 0 sample: 1 pad: 1 [42.700 (-18.700) 24.000 ( 28.900) 52.900] calc: 0 test: 0 +div: 6 read: 0 sample: 1 pad: 0 [40.700 (-16.700) 24.000 ( 26.900) 50.900] calc: 0 test: 0 +div: 6 read: 1 sample: 0 pad: 5 [50.700 (-14.700) 36.000 ( 24.900) 60.900] calc: 0 test: 0 +div: 6 read: 1 sample: 0 pad: 4 [48.700 (-12.700) 36.000 ( 22.900) 58.900] calc: 0 test: 0 +div: 6 read: 1 sample: 0 pad: 3 [46.700 (-10.700) 36.000 ( 20.900) 56.900] calc: 0 test: 1 +div: 6 read: 1 sample: 0 pad: 2 [44.700 ( -8.700) 36.000 ( 18.900) 54.900] calc: 0 test: 1 +div: 6 read: 1 sample: 0 pad: 1 [42.700 ( -6.700) 36.000 ( 16.900) 52.900] calc: 0 test: 1 +div: 6 read: 1 sample: 0 pad: 0 [40.700 ( -4.700) 36.000 ( 14.900) 50.900] calc: 0 test: 1 +div: 6 read: 1 sample: 1 pad: 5 [50.700 ( -2.700) 48.000 ( 12.900) 60.900] calc: 0 test: 1 +div: 6 read: 1 sample: 1 pad: 4 [48.700 ( -0.700) 48.000 ( 10.900) 58.900] calc: 0 test: 1 +div: 6 read: 1 sample: 1 pad: 3 [46.700 ( 1.300) 48.000 ( 8.900) 56.900] calc: 1 test: 1 *** +div: 6 read: 1 sample: 1 pad: 2 [44.700 ( 3.300) 48.000 ( 6.900) 54.900] calc: 1 test: 1 +div: 6 read: 1 sample: 1 pad: 1 [42.700 ( 5.300) 48.000 ( 4.900) 52.900] calc: 1 test: 1 +div: 6 read: 1 sample: 1 pad: 0 [40.700 ( 7.300) 48.000 ( 2.900) 50.900] calc: 1 test: 1 +div: 6 read: 2 sample: 0 pad: 5 [50.700 ( 9.300) 60.000 ( 0.900) 60.900] calc: 1 test: 0 +div: 6 read: 2 sample: 0 pad: 4 [48.700 ( 11.300) 60.000 ( -1.100) 58.900] calc: 0 test: 0 +div: 6 read: 2 sample: 0 pad: 3 [46.700 ( 13.300) 60.000 ( -3.100) 56.900] calc: 0 test: 0 +div: 6 read: 2 sample: 0 pad: 2 [44.700 ( 15.300) 60.000 ( -5.100) 54.900] calc: 0 test: 0 +div: 6 read: 2 sample: 0 pad: 1 [42.700 ( 17.300) 60.000 ( -7.100) 52.900] calc: 0 test: 0 +div: 6 read: 2 sample: 0 pad: 0 [40.700 ( 19.300) 60.000 ( -9.100) 50.900] calc: 0 test: 0 +div: 6 read: 2 sample: 1 pad: 5 [50.700 ( 21.300) 72.000 (-11.100) 60.900] calc: 0 test: 0 +div: 6 read: 2 sample: 1 pad: 4 [48.700 ( 23.300) 72.000 (-13.100) 58.900] calc: 0 test: 0 +div: 6 read: 2 sample: 1 pad: 3 [46.700 ( 25.300) 72.000 (-15.100) 56.900] calc: 0 test: 0 +div: 6 read: 2 sample: 1 pad: 2 [44.700 ( 27.300) 72.000 (-17.100) 54.900] calc: 0 test: 0 +div: 6 read: 2 sample: 1 pad: 1 [42.700 ( 29.300) 72.000 (-19.100) 52.900] calc: 0 test: 0 +div: 6 read: 2 sample: 1 pad: 0 [40.700 ( 31.300) 72.000 (-21.100) 50.900] calc: 0 test: 0 + +F_core: 500 MHz, clock divider: 7, F_clk: 35.71 MHz +div: 7 read: 0 sample: 0 pad: 5 [52.700 (-38.700) 14.000 ( 52.900) 66.900] calc: 0 test: 0 +div: 7 read: 0 sample: 0 pad: 4 [50.700 (-36.700) 14.000 ( 50.900) 64.900] calc: 0 test: 0 +div: 7 read: 0 sample: 0 pad: 3 [48.700 (-34.700) 14.000 ( 48.900) 62.900] calc: 0 test: 0 +div: 7 read: 0 sample: 0 pad: 2 [46.700 (-32.700) 14.000 ( 46.900) 60.900] calc: 0 test: 0 +div: 7 read: 0 sample: 0 pad: 1 [44.700 (-30.700) 14.000 ( 44.900) 58.900] calc: 0 test: 0 +div: 7 read: 0 sample: 0 pad: 0 [42.700 (-28.700) 14.000 ( 42.900) 56.900] calc: 0 test: 0 +div: 7 read: 0 sample: 1 pad: 5 [52.700 (-24.700) 28.000 ( 38.900) 66.900] calc: 0 test: 0 +div: 7 read: 0 sample: 1 pad: 4 [50.700 (-22.700) 28.000 ( 36.900) 64.900] calc: 0 test: 0 +div: 7 read: 0 sample: 1 pad: 3 [48.700 (-20.700) 28.000 ( 34.900) 62.900] calc: 0 test: 0 +div: 7 read: 0 sample: 1 pad: 2 [46.700 (-18.700) 28.000 ( 32.900) 60.900] calc: 0 test: 0 +div: 7 read: 0 sample: 1 pad: 1 [44.700 (-16.700) 28.000 ( 30.900) 58.900] calc: 0 test: 0 +div: 7 read: 0 sample: 1 pad: 0 [42.700 (-14.700) 28.000 ( 28.900) 56.900] calc: 0 test: 0 +div: 7 read: 1 sample: 0 pad: 5 [52.700 (-10.700) 42.000 ( 24.900) 66.900] calc: 0 test: 1 +div: 7 read: 1 sample: 0 pad: 4 [50.700 ( -8.700) 42.000 ( 22.900) 64.900] calc: 0 test: 1 +div: 7 read: 1 sample: 0 pad: 3 [48.700 ( -6.700) 42.000 ( 20.900) 62.900] calc: 0 test: 1 +div: 7 read: 1 sample: 0 pad: 2 [46.700 ( -4.700) 42.000 ( 18.900) 60.900] calc: 0 test: 1 +div: 7 read: 1 sample: 0 pad: 1 [44.700 ( -2.700) 42.000 ( 16.900) 58.900] calc: 0 test: 1 +div: 7 read: 1 sample: 0 pad: 0 [42.700 ( -0.700) 42.000 ( 14.900) 56.900] calc: 0 test: 1 +div: 7 read: 1 sample: 1 pad: 5 [52.700 ( 3.300) 56.000 ( 10.900) 66.900] calc: 1 test: 1 *** +div: 7 read: 1 sample: 1 pad: 4 [50.700 ( 5.300) 56.000 ( 8.900) 64.900] calc: 1 test: 1 +div: 7 read: 1 sample: 1 pad: 3 [48.700 ( 7.300) 56.000 ( 6.900) 62.900] calc: 1 test: 1 +div: 7 read: 1 sample: 1 pad: 2 [46.700 ( 9.300) 56.000 ( 4.900) 60.900] calc: 1 test: 1 +div: 7 read: 1 sample: 1 pad: 1 [44.700 ( 11.300) 56.000 ( 2.900) 58.900] calc: 1 test: 1 +div: 7 read: 1 sample: 1 pad: 0 [42.700 ( 13.300) 56.000 ( 0.900) 56.900] calc: 1 test: 0 +div: 7 read: 2 sample: 0 pad: 5 [52.700 ( 17.300) 70.000 ( -3.100) 66.900] calc: 0 test: 0 +div: 7 read: 2 sample: 0 pad: 4 [50.700 ( 19.300) 70.000 ( -5.100) 64.900] calc: 0 test: 0 +div: 7 read: 2 sample: 0 pad: 3 [48.700 ( 21.300) 70.000 ( -7.100) 62.900] calc: 0 test: 0 +div: 7 read: 2 sample: 0 pad: 2 [46.700 ( 23.300) 70.000 ( -9.100) 60.900] calc: 0 test: 0 +div: 7 read: 2 sample: 0 pad: 1 [44.700 ( 25.300) 70.000 (-11.100) 58.900] calc: 0 test: 0 +div: 7 read: 2 sample: 0 pad: 0 [42.700 ( 27.300) 70.000 (-13.100) 56.900] calc: 0 test: 0 +div: 7 read: 2 sample: 1 pad: 5 [52.700 ( 31.300) 84.000 (-17.100) 66.900] calc: 0 test: 0 +div: 7 read: 2 sample: 1 pad: 4 [50.700 ( 33.300) 84.000 (-19.100) 64.900] calc: 0 test: 0 +div: 7 read: 2 sample: 1 pad: 3 [48.700 ( 35.300) 84.000 (-21.100) 62.900] calc: 0 test: 0 +div: 7 read: 2 sample: 1 pad: 2 [46.700 ( 37.300) 84.000 (-23.100) 60.900] calc: 0 test: 0 +div: 7 read: 2 sample: 1 pad: 1 [44.700 ( 39.300) 84.000 (-25.100) 58.900] calc: 0 test: 0 +div: 7 read: 2 sample: 1 pad: 0 [42.700 ( 41.300) 84.000 (-27.100) 56.900] calc: 0 test: 0 + +F_core: 500 MHz, clock divider: 8, F_clk: 31.25 MHz +div: 8 read: 0 sample: 0 pad: 5 [54.700 (-38.700) 16.000 ( 56.900) 72.900] calc: 0 test: 0 +div: 8 read: 0 sample: 0 pad: 4 [52.700 (-36.700) 16.000 ( 54.900) 70.900] calc: 0 test: 0 +div: 8 read: 0 sample: 0 pad: 3 [50.700 (-34.700) 16.000 ( 52.900) 68.900] calc: 0 test: 0 +div: 8 read: 0 sample: 0 pad: 2 [48.700 (-32.700) 16.000 ( 50.900) 66.900] calc: 0 test: 0 +div: 8 read: 0 sample: 0 pad: 1 [46.700 (-30.700) 16.000 ( 48.900) 64.900] calc: 0 test: 0 +div: 8 read: 0 sample: 0 pad: 0 [44.700 (-28.700) 16.000 ( 46.900) 62.900] calc: 0 test: 0 +div: 8 read: 0 sample: 1 pad: 5 [54.700 (-22.700) 32.000 ( 40.900) 72.900] calc: 0 test: 0 +div: 8 read: 0 sample: 1 pad: 4 [52.700 (-20.700) 32.000 ( 38.900) 70.900] calc: 0 test: 0 +div: 8 read: 0 sample: 1 pad: 3 [50.700 (-18.700) 32.000 ( 36.900) 68.900] calc: 0 test: 0 +div: 8 read: 0 sample: 1 pad: 2 [48.700 (-16.700) 32.000 ( 34.900) 66.900] calc: 0 test: 0 +div: 8 read: 0 sample: 1 pad: 1 [46.700 (-14.700) 32.000 ( 32.900) 64.900] calc: 0 test: 0 +div: 8 read: 0 sample: 1 pad: 0 [44.700 (-12.700) 32.000 ( 30.900) 62.900] calc: 0 test: 0 +div: 8 read: 1 sample: 0 pad: 5 [54.700 ( -6.700) 48.000 ( 24.900) 72.900] calc: 0 test: 1 +div: 8 read: 1 sample: 0 pad: 4 [52.700 ( -4.700) 48.000 ( 22.900) 70.900] calc: 0 test: 1 +div: 8 read: 1 sample: 0 pad: 3 [50.700 ( -2.700) 48.000 ( 20.900) 68.900] calc: 0 test: 1 +div: 8 read: 1 sample: 0 pad: 2 [48.700 ( -0.700) 48.000 ( 18.900) 66.900] calc: 0 test: 1 +div: 8 read: 1 sample: 0 pad: 1 [46.700 ( 1.300) 48.000 ( 16.900) 64.900] calc: 1 test: 1 +div: 8 read: 1 sample: 0 pad: 0 [44.700 ( 3.300) 48.000 ( 14.900) 62.900] calc: 1 test: 1 *** +div: 8 read: 1 sample: 1 pad: 5 [54.700 ( 9.300) 64.000 ( 8.900) 72.900] calc: 1 test: 1 +div: 8 read: 1 sample: 1 pad: 4 [52.700 ( 11.300) 64.000 ( 6.900) 70.900] calc: 1 test: 1 +div: 8 read: 1 sample: 1 pad: 3 [50.700 ( 13.300) 64.000 ( 4.900) 68.900] calc: 1 test: 1 +div: 8 read: 1 sample: 1 pad: 2 [48.700 ( 15.300) 64.000 ( 2.900) 66.900] calc: 1 test: 1 +div: 8 read: 1 sample: 1 pad: 1 [46.700 ( 17.300) 64.000 ( 0.900) 64.900] calc: 1 test: 0 +div: 8 read: 1 sample: 1 pad: 0 [44.700 ( 19.300) 64.000 ( -1.100) 62.900] calc: 0 test: 0 +div: 8 read: 2 sample: 0 pad: 5 [54.700 ( 25.300) 80.000 ( -7.100) 72.900] calc: 0 test: 0 +div: 8 read: 2 sample: 0 pad: 4 [52.700 ( 27.300) 80.000 ( -9.100) 70.900] calc: 0 test: 0 +div: 8 read: 2 sample: 0 pad: 3 [50.700 ( 29.300) 80.000 (-11.100) 68.900] calc: 0 test: 0 +div: 8 read: 2 sample: 0 pad: 2 [48.700 ( 31.300) 80.000 (-13.100) 66.900] calc: 0 test: 0 +div: 8 read: 2 sample: 0 pad: 1 [46.700 ( 33.300) 80.000 (-15.100) 64.900] calc: 0 test: 0 +div: 8 read: 2 sample: 0 pad: 0 [44.700 ( 35.300) 80.000 (-17.100) 62.900] calc: 0 test: 0 +div: 8 read: 2 sample: 1 pad: 5 [54.700 ( 41.300) 96.000 (-23.100) 72.900] calc: 0 test: 0 +div: 8 read: 2 sample: 1 pad: 4 [52.700 ( 43.300) 96.000 (-25.100) 70.900] calc: 0 test: 0 +div: 8 read: 2 sample: 1 pad: 3 [50.700 ( 45.300) 96.000 (-27.100) 68.900] calc: 0 test: 0 +div: 8 read: 2 sample: 1 pad: 2 [48.700 ( 47.300) 96.000 (-29.100) 66.900] calc: 0 test: 0 +div: 8 read: 2 sample: 1 pad: 1 [46.700 ( 49.300) 96.000 (-31.100) 64.900] calc: 0 test: 0 +div: 8 read: 2 sample: 1 pad: 0 [44.700 ( 51.300) 96.000 (-33.100) 62.900] calc: 0 test: 0 + +F_core: 500 MHz, clock divider: 9, F_clk: 27.77 MHz +div: 9 read: 0 sample: 0 pad: 5 [56.700 (-38.700) 18.000 ( 60.900) 78.900] calc: 0 test: 0 +div: 9 read: 0 sample: 0 pad: 4 [54.700 (-36.700) 18.000 ( 58.900) 76.900] calc: 0 test: 0 +div: 9 read: 0 sample: 0 pad: 3 [52.700 (-34.700) 18.000 ( 56.900) 74.900] calc: 0 test: 0 +div: 9 read: 0 sample: 0 pad: 2 [50.700 (-32.700) 18.000 ( 54.900) 72.900] calc: 0 test: 0 +div: 9 read: 0 sample: 0 pad: 1 [48.700 (-30.700) 18.000 ( 52.900) 70.900] calc: 0 test: 0 +div: 9 read: 0 sample: 0 pad: 0 [46.700 (-28.700) 18.000 ( 50.900) 68.900] calc: 0 test: 0 +div: 9 read: 0 sample: 1 pad: 5 [56.700 (-20.700) 36.000 ( 42.900) 78.900] calc: 0 test: 0 +div: 9 read: 0 sample: 1 pad: 4 [54.700 (-18.700) 36.000 ( 40.900) 76.900] calc: 0 test: 0 +div: 9 read: 0 sample: 1 pad: 3 [52.700 (-16.700) 36.000 ( 38.900) 74.900] calc: 0 test: 0 +div: 9 read: 0 sample: 1 pad: 2 [50.700 (-14.700) 36.000 ( 36.900) 72.900] calc: 0 test: 0 +div: 9 read: 0 sample: 1 pad: 1 [48.700 (-12.700) 36.000 ( 34.900) 70.900] calc: 0 test: 0 +div: 9 read: 0 sample: 1 pad: 0 [46.700 (-10.700) 36.000 ( 32.900) 68.900] calc: 0 test: 1 +div: 9 read: 1 sample: 0 pad: 5 [56.700 ( -2.700) 54.000 ( 24.900) 78.900] calc: 0 test: 1 +div: 9 read: 1 sample: 0 pad: 4 [54.700 ( -0.700) 54.000 ( 22.900) 76.900] calc: 0 test: 1 +div: 9 read: 1 sample: 0 pad: 3 [52.700 ( 1.300) 54.000 ( 20.900) 74.900] calc: 1 test: 1 +div: 9 read: 1 sample: 0 pad: 2 [50.700 ( 3.300) 54.000 ( 18.900) 72.900] calc: 1 test: 1 +div: 9 read: 1 sample: 0 pad: 1 [48.700 ( 5.300) 54.000 ( 16.900) 70.900] calc: 1 test: 1 +div: 9 read: 1 sample: 0 pad: 0 [46.700 ( 7.300) 54.000 ( 14.900) 68.900] calc: 1 test: 1 *** +div: 9 read: 1 sample: 1 pad: 5 [56.700 ( 15.300) 72.000 ( 6.900) 78.900] calc: 1 test: 1 +div: 9 read: 1 sample: 1 pad: 4 [54.700 ( 17.300) 72.000 ( 4.900) 76.900] calc: 1 test: 1 +div: 9 read: 1 sample: 1 pad: 3 [52.700 ( 19.300) 72.000 ( 2.900) 74.900] calc: 1 test: 1 +div: 9 read: 1 sample: 1 pad: 2 [50.700 ( 21.300) 72.000 ( 0.900) 72.900] calc: 1 test: 0 +div: 9 read: 1 sample: 1 pad: 1 [48.700 ( 23.300) 72.000 ( -1.100) 70.900] calc: 0 test: 0 +div: 9 read: 1 sample: 1 pad: 0 [46.700 ( 25.300) 72.000 ( -3.100) 68.900] calc: 0 test: 0 +div: 9 read: 2 sample: 0 pad: 5 [56.700 ( 33.300) 90.000 (-11.100) 78.900] calc: 0 test: 0 +div: 9 read: 2 sample: 0 pad: 4 [54.700 ( 35.300) 90.000 (-13.100) 76.900] calc: 0 test: 0 +div: 9 read: 2 sample: 0 pad: 3 [52.700 ( 37.300) 90.000 (-15.100) 74.900] calc: 0 test: 0 +div: 9 read: 2 sample: 0 pad: 2 [50.700 ( 39.300) 90.000 (-17.100) 72.900] calc: 0 test: 0 +div: 9 read: 2 sample: 0 pad: 1 [48.700 ( 41.300) 90.000 (-19.100) 70.900] calc: 0 test: 0 +div: 9 read: 2 sample: 0 pad: 0 [46.700 ( 43.300) 90.000 (-21.100) 68.900] calc: 0 test: 0 +div: 9 read: 2 sample: 1 pad: 5 [56.700 ( 51.300) 108.000 (-29.100) 78.900] calc: 0 test: 0 +div: 9 read: 2 sample: 1 pad: 4 [54.700 ( 53.300) 108.000 (-31.100) 76.900] calc: 0 test: 0 +div: 9 read: 2 sample: 1 pad: 3 [52.700 ( 55.300) 108.000 (-33.100) 74.900] calc: 0 test: 0 +div: 9 read: 2 sample: 1 pad: 2 [50.700 ( 57.300) 108.000 (-35.100) 72.900] calc: 0 test: 0 +div: 9 read: 2 sample: 1 pad: 1 [48.700 ( 59.300) 108.000 (-37.100) 70.900] calc: 0 test: 0 +div: 9 read: 2 sample: 1 pad: 0 [46.700 ( 61.300) 108.000 (-39.100) 68.900] calc: 0 test: 0 + +F_core: 500 MHz, clock divider: 10, F_clk: 25.00 MHz +div: 10 read: 0 sample: 0 pad: 5 [58.700 (-38.700) 20.000 ( 64.900) 84.900] calc: 0 test: 0 +div: 10 read: 0 sample: 0 pad: 4 [56.700 (-36.700) 20.000 ( 62.900) 82.900] calc: 0 test: 0 +div: 10 read: 0 sample: 0 pad: 3 [54.700 (-34.700) 20.000 ( 60.900) 80.900] calc: 0 test: 0 +div: 10 read: 0 sample: 0 pad: 2 [52.700 (-32.700) 20.000 ( 58.900) 78.900] calc: 0 test: 0 +div: 10 read: 0 sample: 0 pad: 1 [50.700 (-30.700) 20.000 ( 56.900) 76.900] calc: 0 test: 0 +div: 10 read: 0 sample: 0 pad: 0 [48.700 (-28.700) 20.000 ( 54.900) 74.900] calc: 0 test: 0 +div: 10 read: 0 sample: 1 pad: 5 [58.700 (-18.700) 40.000 ( 44.900) 84.900] calc: 0 test: 0 +div: 10 read: 0 sample: 1 pad: 4 [56.700 (-16.700) 40.000 ( 42.900) 82.900] calc: 0 test: 0 +div: 10 read: 0 sample: 1 pad: 3 [54.700 (-14.700) 40.000 ( 40.900) 80.900] calc: 0 test: 0 +div: 10 read: 0 sample: 1 pad: 2 [52.700 (-12.700) 40.000 ( 38.900) 78.900] calc: 0 test: 0 +div: 10 read: 0 sample: 1 pad: 1 [50.700 (-10.700) 40.000 ( 36.900) 76.900] calc: 0 test: 1 +div: 10 read: 0 sample: 1 pad: 0 [48.700 ( -8.700) 40.000 ( 34.900) 74.900] calc: 0 test: 1 +div: 10 read: 1 sample: 0 pad: 5 [58.700 ( 1.300) 60.000 ( 24.900) 84.900] calc: 1 test: 1 +div: 10 read: 1 sample: 0 pad: 4 [56.700 ( 3.300) 60.000 ( 22.900) 82.900] calc: 1 test: 1 +div: 10 read: 1 sample: 0 pad: 3 [54.700 ( 5.300) 60.000 ( 20.900) 80.900] calc: 1 test: 1 +div: 10 read: 1 sample: 0 pad: 2 [52.700 ( 7.300) 60.000 ( 18.900) 78.900] calc: 1 test: 1 +div: 10 read: 1 sample: 0 pad: 1 [50.700 ( 9.300) 60.000 ( 16.900) 76.900] calc: 1 test: 1 +div: 10 read: 1 sample: 0 pad: 0 [48.700 ( 11.300) 60.000 ( 14.900) 74.900] calc: 1 test: 1 *** +div: 10 read: 1 sample: 1 pad: 5 [58.700 ( 21.300) 80.000 ( 4.900) 84.900] calc: 1 test: 1 +div: 10 read: 1 sample: 1 pad: 4 [56.700 ( 23.300) 80.000 ( 2.900) 82.900] calc: 1 test: 1 +div: 10 read: 1 sample: 1 pad: 3 [54.700 ( 25.300) 80.000 ( 0.900) 80.900] calc: 1 test: 0 +div: 10 read: 1 sample: 1 pad: 2 [52.700 ( 27.300) 80.000 ( -1.100) 78.900] calc: 0 test: 0 +div: 10 read: 1 sample: 1 pad: 1 [50.700 ( 29.300) 80.000 ( -3.100) 76.900] calc: 0 test: 0 +div: 10 read: 1 sample: 1 pad: 0 [48.700 ( 31.300) 80.000 ( -5.100) 74.900] calc: 0 test: 0 +div: 10 read: 2 sample: 0 pad: 5 [58.700 ( 41.300) 100.000 (-15.100) 84.900] calc: 0 test: 0 +div: 10 read: 2 sample: 0 pad: 4 [56.700 ( 43.300) 100.000 (-17.100) 82.900] calc: 0 test: 0 +div: 10 read: 2 sample: 0 pad: 3 [54.700 ( 45.300) 100.000 (-19.100) 80.900] calc: 0 test: 0 +div: 10 read: 2 sample: 0 pad: 2 [52.700 ( 47.300) 100.000 (-21.100) 78.900] calc: 0 test: 0 +div: 10 read: 2 sample: 0 pad: 1 [50.700 ( 49.300) 100.000 (-23.100) 76.900] calc: 0 test: 0 +div: 10 read: 2 sample: 0 pad: 0 [48.700 ( 51.300) 100.000 (-25.100) 74.900] calc: 0 test: 0 +div: 10 read: 2 sample: 1 pad: 5 [58.700 ( 61.300) 120.000 (-35.100) 84.900] calc: 0 test: 0 +div: 10 read: 2 sample: 1 pad: 4 [56.700 ( 63.300) 120.000 (-37.100) 82.900] calc: 0 test: 0 +div: 10 read: 2 sample: 1 pad: 3 [54.700 ( 65.300) 120.000 (-39.100) 80.900] calc: 0 test: 0 +div: 10 read: 2 sample: 1 pad: 2 [52.700 ( 67.300) 120.000 (-41.100) 78.900] calc: 0 test: 0 +div: 10 read: 2 sample: 1 pad: 1 [50.700 ( 69.300) 120.000 (-43.100) 76.900] calc: 0 test: 0 +div: 10 read: 2 sample: 1 pad: 0 [48.700 ( 71.300) 120.000 (-45.100) 74.900] calc: 0 test: 0 + +F_core: 500 MHz, clock divider: 11, F_clk: 22.72 MHz +div: 11 read: 0 sample: 0 pad: 5 [60.700 (-38.700) 22.000 ( 68.900) 90.900] calc: 0 test: 0 +div: 11 read: 0 sample: 0 pad: 4 [58.700 (-36.700) 22.000 ( 66.900) 88.900] calc: 0 test: 0 +div: 11 read: 0 sample: 0 pad: 3 [56.700 (-34.700) 22.000 ( 64.900) 86.900] calc: 0 test: 0 +div: 11 read: 0 sample: 0 pad: 2 [54.700 (-32.700) 22.000 ( 62.900) 84.900] calc: 0 test: 0 +div: 11 read: 0 sample: 0 pad: 1 [52.700 (-30.700) 22.000 ( 60.900) 82.900] calc: 0 test: 0 +div: 11 read: 0 sample: 0 pad: 0 [50.700 (-28.700) 22.000 ( 58.900) 80.900] calc: 0 test: 0 +div: 11 read: 0 sample: 1 pad: 5 [60.700 (-16.700) 44.000 ( 46.900) 90.900] calc: 0 test: 0 +div: 11 read: 0 sample: 1 pad: 4 [58.700 (-14.700) 44.000 ( 44.900) 88.900] calc: 0 test: 0 +div: 11 read: 0 sample: 1 pad: 3 [56.700 (-12.700) 44.000 ( 42.900) 86.900] calc: 0 test: 0 +div: 11 read: 0 sample: 1 pad: 2 [54.700 (-10.700) 44.000 ( 40.900) 84.900] calc: 0 test: 1 +div: 11 read: 0 sample: 1 pad: 1 [52.700 ( -8.700) 44.000 ( 38.900) 82.900] calc: 0 test: 1 +div: 11 read: 0 sample: 1 pad: 0 [50.700 ( -6.700) 44.000 ( 36.900) 80.900] calc: 0 test: 1 +div: 11 read: 1 sample: 0 pad: 5 [60.700 ( 5.300) 66.000 ( 24.900) 90.900] calc: 1 test: 1 +div: 11 read: 1 sample: 0 pad: 4 [58.700 ( 7.300) 66.000 ( 22.900) 88.900] calc: 1 test: 1 +div: 11 read: 1 sample: 0 pad: 3 [56.700 ( 9.300) 66.000 ( 20.900) 86.900] calc: 1 test: 1 +div: 11 read: 1 sample: 0 pad: 2 [54.700 ( 11.300) 66.000 ( 18.900) 84.900] calc: 1 test: 1 +div: 11 read: 1 sample: 0 pad: 1 [52.700 ( 13.300) 66.000 ( 16.900) 82.900] calc: 1 test: 1 +div: 11 read: 1 sample: 0 pad: 0 [50.700 ( 15.300) 66.000 ( 14.900) 80.900] calc: 1 test: 1 +div: 11 read: 1 sample: 1 pad: 5 [60.700 ( 27.300) 88.000 ( 2.900) 90.900] calc: 1 test: 1 +div: 11 read: 1 sample: 1 pad: 4 [58.700 ( 29.300) 88.000 ( 0.900) 88.900] calc: 1 test: 0 +div: 11 read: 1 sample: 1 pad: 3 [56.700 ( 31.300) 88.000 ( -1.100) 86.900] calc: 0 test: 0 +div: 11 read: 1 sample: 1 pad: 2 [54.700 ( 33.300) 88.000 ( -3.100) 84.900] calc: 0 test: 0 +div: 11 read: 1 sample: 1 pad: 1 [52.700 ( 35.300) 88.000 ( -5.100) 82.900] calc: 0 test: 0 +div: 11 read: 1 sample: 1 pad: 0 [50.700 ( 37.300) 88.000 ( -7.100) 80.900] calc: 0 test: 0 +div: 11 read: 2 sample: 0 pad: 5 [60.700 ( 49.300) 110.000 (-19.100) 90.900] calc: 0 test: 0 +div: 11 read: 2 sample: 0 pad: 4 [58.700 ( 51.300) 110.000 (-21.100) 88.900] calc: 0 test: 0 +div: 11 read: 2 sample: 0 pad: 3 [56.700 ( 53.300) 110.000 (-23.100) 86.900] calc: 0 test: 0 +div: 11 read: 2 sample: 0 pad: 2 [54.700 ( 55.300) 110.000 (-25.100) 84.900] calc: 0 test: 0 +div: 11 read: 2 sample: 0 pad: 1 [52.700 ( 57.300) 110.000 (-27.100) 82.900] calc: 0 test: 0 +div: 11 read: 2 sample: 0 pad: 0 [50.700 ( 59.300) 110.000 (-29.100) 80.900] calc: 0 test: 0 +div: 11 read: 2 sample: 1 pad: 5 [60.700 ( 71.300) 132.000 (-41.100) 90.900] calc: 0 test: 0 +div: 11 read: 2 sample: 1 pad: 4 [58.700 ( 73.300) 132.000 (-43.100) 88.900] calc: 0 test: 0 +div: 11 read: 2 sample: 1 pad: 3 [56.700 ( 75.300) 132.000 (-45.100) 86.900] calc: 0 test: 0 +div: 11 read: 2 sample: 1 pad: 2 [54.700 ( 77.300) 132.000 (-47.100) 84.900] calc: 0 test: 0 +div: 11 read: 2 sample: 1 pad: 1 [52.700 ( 79.300) 132.000 (-49.100) 82.900] calc: 0 test: 0 +div: 11 read: 2 sample: 1 pad: 0 [50.700 ( 81.300) 132.000 (-51.100) 80.900] calc: 0 test: 0 + +F_core: 500 MHz, clock divider: 12, F_clk: 20.83 MHz +div: 12 read: 0 sample: 0 pad: 5 [62.700 (-38.700) 24.000 ( 72.900) 96.900] calc: 0 test: 0 +div: 12 read: 0 sample: 0 pad: 4 [60.700 (-36.700) 24.000 ( 70.900) 94.900] calc: 0 test: 0 +div: 12 read: 0 sample: 0 pad: 3 [58.700 (-34.700) 24.000 ( 68.900) 92.900] calc: 0 test: 0 +div: 12 read: 0 sample: 0 pad: 2 [56.700 (-32.700) 24.000 ( 66.900) 90.900] calc: 0 test: 0 +div: 12 read: 0 sample: 0 pad: 1 [54.700 (-30.700) 24.000 ( 64.900) 88.900] calc: 0 test: 0 +div: 12 read: 0 sample: 0 pad: 0 [52.700 (-28.700) 24.000 ( 62.900) 86.900] calc: 0 test: 0 +div: 12 read: 0 sample: 1 pad: 5 [62.700 (-14.700) 48.000 ( 48.900) 96.900] calc: 0 test: 0 +div: 12 read: 0 sample: 1 pad: 4 [60.700 (-12.700) 48.000 ( 46.900) 94.900] calc: 0 test: 0 +div: 12 read: 0 sample: 1 pad: 3 [58.700 (-10.700) 48.000 ( 44.900) 92.900] calc: 0 test: 1 +div: 12 read: 0 sample: 1 pad: 2 [56.700 ( -8.700) 48.000 ( 42.900) 90.900] calc: 0 test: 1 +div: 12 read: 0 sample: 1 pad: 1 [54.700 ( -6.700) 48.000 ( 40.900) 88.900] calc: 0 test: 1 +div: 12 read: 0 sample: 1 pad: 0 [52.700 ( -4.700) 48.000 ( 38.900) 86.900] calc: 0 test: 1 +div: 12 read: 1 sample: 0 pad: 5 [62.700 ( 9.300) 72.000 ( 24.900) 96.900] calc: 1 test: 1 +div: 12 read: 1 sample: 0 pad: 4 [60.700 ( 11.300) 72.000 ( 22.900) 94.900] calc: 1 test: 1 +div: 12 read: 1 sample: 0 pad: 3 [58.700 ( 13.300) 72.000 ( 20.900) 92.900] calc: 1 test: 1 +div: 12 read: 1 sample: 0 pad: 2 [56.700 ( 15.300) 72.000 ( 18.900) 90.900] calc: 1 test: 1 +div: 12 read: 1 sample: 0 pad: 1 [54.700 ( 17.300) 72.000 ( 16.900) 88.900] calc: 1 test: 1 +div: 12 read: 1 sample: 0 pad: 0 [52.700 ( 19.300) 72.000 ( 14.900) 86.900] calc: 1 test: 1 +div: 12 read: 1 sample: 1 pad: 5 [62.700 ( 33.300) 96.000 ( 0.900) 96.900] calc: 1 test: 0 +div: 12 read: 1 sample: 1 pad: 4 [60.700 ( 35.300) 96.000 ( -1.100) 94.900] calc: 0 test: 0 +div: 12 read: 1 sample: 1 pad: 3 [58.700 ( 37.300) 96.000 ( -3.100) 92.900] calc: 0 test: 0 +div: 12 read: 1 sample: 1 pad: 2 [56.700 ( 39.300) 96.000 ( -5.100) 90.900] calc: 0 test: 0 +div: 12 read: 1 sample: 1 pad: 1 [54.700 ( 41.300) 96.000 ( -7.100) 88.900] calc: 0 test: 0 +div: 12 read: 1 sample: 1 pad: 0 [52.700 ( 43.300) 96.000 ( -9.100) 86.900] calc: 0 test: 0 +div: 12 read: 2 sample: 0 pad: 5 [62.700 ( 57.300) 120.000 (-23.100) 96.900] calc: 0 test: 0 +div: 12 read: 2 sample: 0 pad: 4 [60.700 ( 59.300) 120.000 (-25.100) 94.900] calc: 0 test: 0 +div: 12 read: 2 sample: 0 pad: 3 [58.700 ( 61.300) 120.000 (-27.100) 92.900] calc: 0 test: 0 +div: 12 read: 2 sample: 0 pad: 2 [56.700 ( 63.300) 120.000 (-29.100) 90.900] calc: 0 test: 0 +div: 12 read: 2 sample: 0 pad: 1 [54.700 ( 65.300) 120.000 (-31.100) 88.900] calc: 0 test: 0 +div: 12 read: 2 sample: 0 pad: 0 [52.700 ( 67.300) 120.000 (-33.100) 86.900] calc: 0 test: 0 +div: 12 read: 2 sample: 1 pad: 5 [62.700 ( 81.300) 144.000 (-47.100) 96.900] calc: 0 test: 0 +div: 12 read: 2 sample: 1 pad: 4 [60.700 ( 83.300) 144.000 (-49.100) 94.900] calc: 0 test: 0 +div: 12 read: 2 sample: 1 pad: 3 [58.700 ( 85.300) 144.000 (-51.100) 92.900] calc: 0 test: 0 +div: 12 read: 2 sample: 1 pad: 2 [56.700 ( 87.300) 144.000 (-53.100) 90.900] calc: 0 test: 0 +div: 12 read: 2 sample: 1 pad: 1 [54.700 ( 89.300) 144.000 (-55.100) 88.900] calc: 0 test: 0 +div: 12 read: 2 sample: 1 pad: 0 [52.700 ( 91.300) 144.000 (-57.100) 86.900] calc: 0 test: 0 +SDRAM timing finished + + + + +XS3 results +----------- + +Tested using a XU316 xcore-ai onboard SDRAM test board (XU316-1024-FB265-C24 CPU) +with 64Mbit Winbond W9864G6KH-6 (equivalent to an ISSI IS42S16400D-7). + +Using 64Mb SDRAM +Round trip time min: 8764 ps, max: 21830 ps +starting SDRAM timing + +F_core: 600 MHz, clock divider: 4, F_clk: 75.00 MHz +div: 4 read: 0 sample: 0 pad: 5 [42.224 (-35.560) 6.664 ( 32.922) 39.586] calc: 0 test: 0 +div: 4 read: 0 sample: 0 pad: 4 [40.558 (-33.894) 6.664 ( 31.256) 37.920] calc: 0 test: 0 +div: 4 read: 0 sample: 0 pad: 3 [38.892 (-32.228) 6.664 ( 29.590) 36.254] calc: 0 test: 0 +div: 4 read: 0 sample: 0 pad: 2 [37.226 (-30.562) 6.664 ( 27.924) 34.588] calc: 0 test: 0 +div: 4 read: 0 sample: 0 pad: 1 [35.560 (-28.896) 6.664 ( 26.258) 32.922] calc: 0 test: 0 +div: 4 read: 0 sample: 0 pad: 0 [33.894 (-27.230) 6.664 ( 24.592) 31.256] calc: 0 test: 0 +div: 4 read: 0 sample: 1 pad: 5 [42.224 (-28.896) 13.328 ( 26.258) 39.586] calc: 0 test: 0 +div: 4 read: 0 sample: 1 pad: 4 [40.558 (-27.230) 13.328 ( 24.592) 37.920] calc: 0 test: 0 +div: 4 read: 0 sample: 1 pad: 3 [38.892 (-25.564) 13.328 ( 22.926) 36.254] calc: 0 test: 0 +div: 4 read: 0 sample: 1 pad: 2 [37.226 (-23.898) 13.328 ( 21.260) 34.588] calc: 0 test: 0 +div: 4 read: 0 sample: 1 pad: 1 [35.560 (-22.232) 13.328 ( 19.594) 32.922] calc: 0 test: 0 +div: 4 read: 0 sample: 1 pad: 0 [33.894 (-20.566) 13.328 ( 17.928) 31.256] calc: 0 test: 0 +div: 4 read: 1 sample: 0 pad: 5 [42.224 (-22.232) 19.992 ( 19.594) 39.586] calc: 0 test: 0 +div: 4 read: 1 sample: 0 pad: 4 [40.558 (-20.566) 19.992 ( 17.928) 37.920] calc: 0 test: 0 +div: 4 read: 1 sample: 0 pad: 3 [38.892 (-18.900) 19.992 ( 16.262) 36.254] calc: 0 test: 0 +div: 4 read: 1 sample: 0 pad: 2 [37.226 (-17.234) 19.992 ( 14.596) 34.588] calc: 0 test: 0 +div: 4 read: 1 sample: 0 pad: 1 [35.560 (-15.568) 19.992 ( 12.930) 32.922] calc: 0 test: 0 +div: 4 read: 1 sample: 0 pad: 0 [33.894 (-13.902) 19.992 ( 11.264) 31.256] calc: 0 test: 0 +div: 4 read: 1 sample: 1 pad: 5 [42.224 (-15.568) 26.656 ( 12.930) 39.586] calc: 0 test: 0 +div: 4 read: 1 sample: 1 pad: 4 [40.558 (-13.902) 26.656 ( 11.264) 37.920] calc: 0 test: 0 +div: 4 read: 1 sample: 1 pad: 3 [38.892 (-12.236) 26.656 ( 9.598) 36.254] calc: 0 test: 0 +div: 4 read: 1 sample: 1 pad: 2 [37.226 (-10.570) 26.656 ( 7.932) 34.588] calc: 0 test: 0 +div: 4 read: 1 sample: 1 pad: 1 [35.560 ( -8.904) 26.656 ( 6.266) 32.922] calc: 0 test: 1 +div: 4 read: 1 sample: 1 pad: 0 [33.894 ( -7.238) 26.656 ( 4.600) 31.256] calc: 0 test: 1 +div: 4 read: 2 sample: 0 pad: 5 [42.224 ( -8.904) 33.320 ( 6.266) 39.586] calc: 0 test: 1 +div: 4 read: 2 sample: 0 pad: 4 [40.558 ( -7.238) 33.320 ( 4.600) 37.920] calc: 0 test: 1 +div: 4 read: 2 sample: 0 pad: 3 [38.892 ( -5.572) 33.320 ( 2.934) 36.254] calc: 0 test: 1 +div: 4 read: 2 sample: 0 pad: 2 [37.226 ( -3.906) 33.320 ( 1.268) 34.588] calc: 0 test: 1 +div: 4 read: 2 sample: 0 pad: 1 [35.560 ( -2.240) 33.320 ( -0.398) 32.922] calc: 0 test: 1 +div: 4 read: 2 sample: 0 pad: 0 [33.894 ( -0.574) 33.320 ( -2.064) 31.256] calc: 0 test: 0 +div: 4 read: 2 sample: 1 pad: 5 [42.224 ( -2.240) 39.984 ( -0.398) 39.586] calc: 0 test: 1 +div: 4 read: 2 sample: 1 pad: 4 [40.558 ( -0.574) 39.984 ( -2.064) 37.920] calc: 0 test: 0 +div: 4 read: 2 sample: 1 pad: 3 [38.892 ( 1.092) 39.984 ( -3.730) 36.254] calc: 0 test: 0 +div: 4 read: 2 sample: 1 pad: 2 [37.226 ( 2.758) 39.984 ( -5.396) 34.588] calc: 0 test: 0 +div: 4 read: 2 sample: 1 pad: 1 [35.560 ( 4.424) 39.984 ( -7.062) 32.922] calc: 0 test: 0 +div: 4 read: 2 sample: 1 pad: 0 [33.894 ( 6.090) 39.984 ( -8.728) 31.256] calc: 0 test: 0 + +F_core: 600 MHz, clock divider: 5, F_clk: 60.00 MHz +div: 5 read: 0 sample: 0 pad: 5 [43.890 (-35.560) 8.330 ( 36.254) 44.584] calc: 0 test: 0 +div: 5 read: 0 sample: 0 pad: 4 [42.224 (-33.894) 8.330 ( 34.588) 42.918] calc: 0 test: 0 +div: 5 read: 0 sample: 0 pad: 3 [40.558 (-32.228) 8.330 ( 32.922) 41.252] calc: 0 test: 0 +div: 5 read: 0 sample: 0 pad: 2 [38.892 (-30.562) 8.330 ( 31.256) 39.586] calc: 0 test: 0 +div: 5 read: 0 sample: 0 pad: 1 [37.226 (-28.896) 8.330 ( 29.590) 37.920] calc: 0 test: 0 +div: 5 read: 0 sample: 0 pad: 0 [35.560 (-27.230) 8.330 ( 27.924) 36.254] calc: 0 test: 0 +div: 5 read: 0 sample: 1 pad: 5 [43.890 (-27.230) 16.660 ( 27.924) 44.584] calc: 0 test: 0 +div: 5 read: 0 sample: 1 pad: 4 [42.224 (-25.564) 16.660 ( 26.258) 42.918] calc: 0 test: 0 +div: 5 read: 0 sample: 1 pad: 3 [40.558 (-23.898) 16.660 ( 24.592) 41.252] calc: 0 test: 0 +div: 5 read: 0 sample: 1 pad: 2 [38.892 (-22.232) 16.660 ( 22.926) 39.586] calc: 0 test: 0 +div: 5 read: 0 sample: 1 pad: 1 [37.226 (-20.566) 16.660 ( 21.260) 37.920] calc: 0 test: 0 +div: 5 read: 0 sample: 1 pad: 0 [35.560 (-18.900) 16.660 ( 19.594) 36.254] calc: 0 test: 0 +div: 5 read: 1 sample: 0 pad: 5 [43.890 (-18.900) 24.990 ( 19.594) 44.584] calc: 0 test: 0 +div: 5 read: 1 sample: 0 pad: 4 [42.224 (-17.234) 24.990 ( 17.928) 42.918] calc: 0 test: 0 +div: 5 read: 1 sample: 0 pad: 3 [40.558 (-15.568) 24.990 ( 16.262) 41.252] calc: 0 test: 0 +div: 5 read: 1 sample: 0 pad: 2 [38.892 (-13.902) 24.990 ( 14.596) 39.586] calc: 0 test: 0 +div: 5 read: 1 sample: 0 pad: 1 [37.226 (-12.236) 24.990 ( 12.930) 37.920] calc: 0 test: 0 +div: 5 read: 1 sample: 0 pad: 0 [35.560 (-10.570) 24.990 ( 11.264) 36.254] calc: 0 test: 0 +div: 5 read: 1 sample: 1 pad: 5 [43.890 (-10.570) 33.320 ( 11.264) 44.584] calc: 0 test: 0 +div: 5 read: 1 sample: 1 pad: 4 [42.224 ( -8.904) 33.320 ( 9.598) 42.918] calc: 0 test: 1 +div: 5 read: 1 sample: 1 pad: 3 [40.558 ( -7.238) 33.320 ( 7.932) 41.252] calc: 0 test: 1 +div: 5 read: 1 sample: 1 pad: 2 [38.892 ( -5.572) 33.320 ( 6.266) 39.586] calc: 0 test: 1 +div: 5 read: 1 sample: 1 pad: 1 [37.226 ( -3.906) 33.320 ( 4.600) 37.920] calc: 0 test: 1 +div: 5 read: 1 sample: 1 pad: 0 [35.560 ( -2.240) 33.320 ( 2.934) 36.254] calc: 0 test: 1 *** +div: 5 read: 2 sample: 0 pad: 5 [43.890 ( -2.240) 41.650 ( 2.934) 44.584] calc: 0 test: 1 +div: 5 read: 2 sample: 0 pad: 4 [42.224 ( -0.574) 41.650 ( 1.268) 42.918] calc: 0 test: 1 +div: 5 read: 2 sample: 0 pad: 3 [40.558 ( 1.092) 41.650 ( -0.398) 41.252] calc: 0 test: 1 +div: 5 read: 2 sample: 0 pad: 2 [38.892 ( 2.758) 41.650 ( -2.064) 39.586] calc: 0 test: 0 +div: 5 read: 2 sample: 0 pad: 1 [37.226 ( 4.424) 41.650 ( -3.730) 37.920] calc: 0 test: 0 +div: 5 read: 2 sample: 0 pad: 0 [35.560 ( 6.090) 41.650 ( -5.396) 36.254] calc: 0 test: 0 +div: 5 read: 2 sample: 1 pad: 5 [43.890 ( 6.090) 49.980 ( -5.396) 44.584] calc: 0 test: 0 +div: 5 read: 2 sample: 1 pad: 4 [42.224 ( 7.756) 49.980 ( -7.062) 42.918] calc: 0 test: 0 +div: 5 read: 2 sample: 1 pad: 3 [40.558 ( 9.422) 49.980 ( -8.728) 41.252] calc: 0 test: 0 +div: 5 read: 2 sample: 1 pad: 2 [38.892 ( 11.088) 49.980 (-10.394) 39.586] calc: 0 test: 0 +div: 5 read: 2 sample: 1 pad: 1 [37.226 ( 12.754) 49.980 (-12.060) 37.920] calc: 0 test: 0 +div: 5 read: 2 sample: 1 pad: 0 [35.560 ( 14.420) 49.980 (-13.726) 36.254] calc: 0 test: 0 + +F_core: 600 MHz, clock divider: 6, F_clk: 50.00 MHz +div: 6 read: 0 sample: 0 pad: 5 [45.556 (-35.560) 9.996 ( 39.586) 49.582] calc: 0 test: 0 +div: 6 read: 0 sample: 0 pad: 4 [43.890 (-33.894) 9.996 ( 37.920) 47.916] calc: 0 test: 0 +div: 6 read: 0 sample: 0 pad: 3 [42.224 (-32.228) 9.996 ( 36.254) 46.250] calc: 0 test: 0 +div: 6 read: 0 sample: 0 pad: 2 [40.558 (-30.562) 9.996 ( 34.588) 44.584] calc: 0 test: 0 +div: 6 read: 0 sample: 0 pad: 1 [38.892 (-28.896) 9.996 ( 32.922) 42.918] calc: 0 test: 0 +div: 6 read: 0 sample: 0 pad: 0 [37.226 (-27.230) 9.996 ( 31.256) 41.252] calc: 0 test: 0 +div: 6 read: 0 sample: 1 pad: 5 [45.556 (-25.564) 19.992 ( 29.590) 49.582] calc: 0 test: 0 +div: 6 read: 0 sample: 1 pad: 4 [43.890 (-23.898) 19.992 ( 27.924) 47.916] calc: 0 test: 0 +div: 6 read: 0 sample: 1 pad: 3 [42.224 (-22.232) 19.992 ( 26.258) 46.250] calc: 0 test: 0 +div: 6 read: 0 sample: 1 pad: 2 [40.558 (-20.566) 19.992 ( 24.592) 44.584] calc: 0 test: 0 +div: 6 read: 0 sample: 1 pad: 1 [38.892 (-18.900) 19.992 ( 22.926) 42.918] calc: 0 test: 0 +div: 6 read: 0 sample: 1 pad: 0 [37.226 (-17.234) 19.992 ( 21.260) 41.252] calc: 0 test: 0 +div: 6 read: 1 sample: 0 pad: 5 [45.556 (-15.568) 29.988 ( 19.594) 49.582] calc: 0 test: 0 +div: 6 read: 1 sample: 0 pad: 4 [43.890 (-13.902) 29.988 ( 17.928) 47.916] calc: 0 test: 0 +div: 6 read: 1 sample: 0 pad: 3 [42.224 (-12.236) 29.988 ( 16.262) 46.250] calc: 0 test: 0 +div: 6 read: 1 sample: 0 pad: 2 [40.558 (-10.570) 29.988 ( 14.596) 44.584] calc: 0 test: 0 +div: 6 read: 1 sample: 0 pad: 1 [38.892 ( -8.904) 29.988 ( 12.930) 42.918] calc: 0 test: 1 +div: 6 read: 1 sample: 0 pad: 0 [37.226 ( -7.238) 29.988 ( 11.264) 41.252] calc: 0 test: 1 +div: 6 read: 1 sample: 1 pad: 5 [45.556 ( -5.572) 39.984 ( 9.598) 49.582] calc: 0 test: 1 +div: 6 read: 1 sample: 1 pad: 4 [43.890 ( -3.906) 39.984 ( 7.932) 47.916] calc: 0 test: 1 +div: 6 read: 1 sample: 1 pad: 3 [42.224 ( -2.240) 39.984 ( 6.266) 46.250] calc: 0 test: 1 +div: 6 read: 1 sample: 1 pad: 2 [40.558 ( -0.574) 39.984 ( 4.600) 44.584] calc: 0 test: 1 *** +div: 6 read: 1 sample: 1 pad: 1 [38.892 ( 1.092) 39.984 ( 2.934) 42.918] calc: 1 test: 1 +div: 6 read: 1 sample: 1 pad: 0 [37.226 ( 2.758) 39.984 ( 1.268) 41.252] calc: 1 test: 1 +div: 6 read: 2 sample: 0 pad: 5 [45.556 ( 4.424) 49.980 ( -0.398) 49.582] calc: 0 test: 1 +div: 6 read: 2 sample: 0 pad: 4 [43.890 ( 6.090) 49.980 ( -2.064) 47.916] calc: 0 test: 0 +div: 6 read: 2 sample: 0 pad: 3 [42.224 ( 7.756) 49.980 ( -3.730) 46.250] calc: 0 test: 0 +div: 6 read: 2 sample: 0 pad: 2 [40.558 ( 9.422) 49.980 ( -5.396) 44.584] calc: 0 test: 0 +div: 6 read: 2 sample: 0 pad: 1 [38.892 ( 11.088) 49.980 ( -7.062) 42.918] calc: 0 test: 0 +div: 6 read: 2 sample: 0 pad: 0 [37.226 ( 12.754) 49.980 ( -8.728) 41.252] calc: 0 test: 0 +div: 6 read: 2 sample: 1 pad: 5 [45.556 ( 14.420) 59.976 (-10.394) 49.582] calc: 0 test: 0 +div: 6 read: 2 sample: 1 pad: 4 [43.890 ( 16.086) 59.976 (-12.060) 47.916] calc: 0 test: 0 +div: 6 read: 2 sample: 1 pad: 3 [42.224 ( 17.752) 59.976 (-13.726) 46.250] calc: 0 test: 0 +div: 6 read: 2 sample: 1 pad: 2 [40.558 ( 19.418) 59.976 (-15.392) 44.584] calc: 0 test: 0 +div: 6 read: 2 sample: 1 pad: 1 [38.892 ( 21.084) 59.976 (-17.058) 42.918] calc: 0 test: 0 +div: 6 read: 2 sample: 1 pad: 0 [37.226 ( 22.750) 59.976 (-18.724) 41.252] calc: 0 test: 0 + +F_core: 600 MHz, clock divider: 7, F_clk: 42.85 MHz +div: 7 read: 0 sample: 0 pad: 5 [47.222 (-35.560) 11.662 ( 42.918) 54.580] calc: 0 test: 0 +div: 7 read: 0 sample: 0 pad: 4 [45.556 (-33.894) 11.662 ( 41.252) 52.914] calc: 0 test: 0 +div: 7 read: 0 sample: 0 pad: 3 [43.890 (-32.228) 11.662 ( 39.586) 51.248] calc: 0 test: 0 +div: 7 read: 0 sample: 0 pad: 2 [42.224 (-30.562) 11.662 ( 37.920) 49.582] calc: 0 test: 0 +div: 7 read: 0 sample: 0 pad: 1 [40.558 (-28.896) 11.662 ( 36.254) 47.916] calc: 0 test: 0 +div: 7 read: 0 sample: 0 pad: 0 [38.892 (-27.230) 11.662 ( 34.588) 46.250] calc: 0 test: 0 +div: 7 read: 0 sample: 1 pad: 5 [47.222 (-23.898) 23.324 ( 31.256) 54.580] calc: 0 test: 0 +div: 7 read: 0 sample: 1 pad: 4 [45.556 (-22.232) 23.324 ( 29.590) 52.914] calc: 0 test: 0 +div: 7 read: 0 sample: 1 pad: 3 [43.890 (-20.566) 23.324 ( 27.924) 51.248] calc: 0 test: 0 +div: 7 read: 0 sample: 1 pad: 2 [42.224 (-18.900) 23.324 ( 26.258) 49.582] calc: 0 test: 0 +div: 7 read: 0 sample: 1 pad: 1 [40.558 (-17.234) 23.324 ( 24.592) 47.916] calc: 0 test: 0 +div: 7 read: 0 sample: 1 pad: 0 [38.892 (-15.568) 23.324 ( 22.926) 46.250] calc: 0 test: 0 +div: 7 read: 1 sample: 0 pad: 5 [47.222 (-12.236) 34.986 ( 19.594) 54.580] calc: 0 test: 0 +div: 7 read: 1 sample: 0 pad: 4 [45.556 (-10.570) 34.986 ( 17.928) 52.914] calc: 0 test: 0 +div: 7 read: 1 sample: 0 pad: 3 [43.890 ( -8.904) 34.986 ( 16.262) 51.248] calc: 0 test: 1 +div: 7 read: 1 sample: 0 pad: 2 [42.224 ( -7.238) 34.986 ( 14.596) 49.582] calc: 0 test: 1 +div: 7 read: 1 sample: 0 pad: 1 [40.558 ( -5.572) 34.986 ( 12.930) 47.916] calc: 0 test: 1 +div: 7 read: 1 sample: 0 pad: 0 [38.892 ( -3.906) 34.986 ( 11.264) 46.250] calc: 0 test: 1 +div: 7 read: 1 sample: 1 pad: 5 [47.222 ( -0.574) 46.648 ( 7.932) 54.580] calc: 0 test: 1 +div: 7 read: 1 sample: 1 pad: 4 [45.556 ( 1.092) 46.648 ( 6.266) 52.914] calc: 1 test: 1 *** +div: 7 read: 1 sample: 1 pad: 3 [43.890 ( 2.758) 46.648 ( 4.600) 51.248] calc: 1 test: 1 +div: 7 read: 1 sample: 1 pad: 2 [42.224 ( 4.424) 46.648 ( 2.934) 49.582] calc: 1 test: 1 +div: 7 read: 1 sample: 1 pad: 1 [40.558 ( 6.090) 46.648 ( 1.268) 47.916] calc: 1 test: 1 +div: 7 read: 1 sample: 1 pad: 0 [38.892 ( 7.756) 46.648 ( -0.398) 46.250] calc: 0 test: 1 +div: 7 read: 2 sample: 0 pad: 5 [47.222 ( 11.088) 58.310 ( -3.730) 54.580] calc: 0 test: 0 +div: 7 read: 2 sample: 0 pad: 4 [45.556 ( 12.754) 58.310 ( -5.396) 52.914] calc: 0 test: 0 +div: 7 read: 2 sample: 0 pad: 3 [43.890 ( 14.420) 58.310 ( -7.062) 51.248] calc: 0 test: 0 +div: 7 read: 2 sample: 0 pad: 2 [42.224 ( 16.086) 58.310 ( -8.728) 49.582] calc: 0 test: 0 +div: 7 read: 2 sample: 0 pad: 1 [40.558 ( 17.752) 58.310 (-10.394) 47.916] calc: 0 test: 0 +div: 7 read: 2 sample: 0 pad: 0 [38.892 ( 19.418) 58.310 (-12.060) 46.250] calc: 0 test: 0 +div: 7 read: 2 sample: 1 pad: 5 [47.222 ( 22.750) 69.972 (-15.392) 54.580] calc: 0 test: 0 +div: 7 read: 2 sample: 1 pad: 4 [45.556 ( 24.416) 69.972 (-17.058) 52.914] calc: 0 test: 0 +div: 7 read: 2 sample: 1 pad: 3 [43.890 ( 26.082) 69.972 (-18.724) 51.248] calc: 0 test: 0 +div: 7 read: 2 sample: 1 pad: 2 [42.224 ( 27.748) 69.972 (-20.390) 49.582] calc: 0 test: 0 +div: 7 read: 2 sample: 1 pad: 1 [40.558 ( 29.414) 69.972 (-22.056) 47.916] calc: 0 test: 0 +div: 7 read: 2 sample: 1 pad: 0 [38.892 ( 31.080) 69.972 (-23.722) 46.250] calc: 0 test: 0 + +F_core: 600 MHz, clock divider: 8, F_clk: 37.50 MHz +div: 8 read: 0 sample: 0 pad: 5 [48.888 (-35.560) 13.328 ( 46.250) 59.578] calc: 0 test: 0 +div: 8 read: 0 sample: 0 pad: 4 [47.222 (-33.894) 13.328 ( 44.584) 57.912] calc: 0 test: 0 +div: 8 read: 0 sample: 0 pad: 3 [45.556 (-32.228) 13.328 ( 42.918) 56.246] calc: 0 test: 0 +div: 8 read: 0 sample: 0 pad: 2 [43.890 (-30.562) 13.328 ( 41.252) 54.580] calc: 0 test: 0 +div: 8 read: 0 sample: 0 pad: 1 [42.224 (-28.896) 13.328 ( 39.586) 52.914] calc: 0 test: 0 +div: 8 read: 0 sample: 0 pad: 0 [40.558 (-27.230) 13.328 ( 37.920) 51.248] calc: 0 test: 0 +div: 8 read: 0 sample: 1 pad: 5 [48.888 (-22.232) 26.656 ( 32.922) 59.578] calc: 0 test: 0 +div: 8 read: 0 sample: 1 pad: 4 [47.222 (-20.566) 26.656 ( 31.256) 57.912] calc: 0 test: 0 +div: 8 read: 0 sample: 1 pad: 3 [45.556 (-18.900) 26.656 ( 29.590) 56.246] calc: 0 test: 0 +div: 8 read: 0 sample: 1 pad: 2 [43.890 (-17.234) 26.656 ( 27.924) 54.580] calc: 0 test: 0 +div: 8 read: 0 sample: 1 pad: 1 [42.224 (-15.568) 26.656 ( 26.258) 52.914] calc: 0 test: 0 +div: 8 read: 0 sample: 1 pad: 0 [40.558 (-13.902) 26.656 ( 24.592) 51.248] calc: 0 test: 0 +div: 8 read: 1 sample: 0 pad: 5 [48.888 ( -8.904) 39.984 ( 19.594) 59.578] calc: 0 test: 1 +div: 8 read: 1 sample: 0 pad: 4 [47.222 ( -7.238) 39.984 ( 17.928) 57.912] calc: 0 test: 1 +div: 8 read: 1 sample: 0 pad: 3 [45.556 ( -5.572) 39.984 ( 16.262) 56.246] calc: 0 test: 1 +div: 8 read: 1 sample: 0 pad: 2 [43.890 ( -3.906) 39.984 ( 14.596) 54.580] calc: 0 test: 1 +div: 8 read: 1 sample: 0 pad: 1 [42.224 ( -2.240) 39.984 ( 12.930) 52.914] calc: 0 test: 1 +div: 8 read: 1 sample: 0 pad: 0 [40.558 ( -0.574) 39.984 ( 11.264) 51.248] calc: 0 test: 1 +div: 8 read: 1 sample: 1 pad: 5 [48.888 ( 4.424) 53.312 ( 6.266) 59.578] calc: 1 test: 1 *** +div: 8 read: 1 sample: 1 pad: 4 [47.222 ( 6.090) 53.312 ( 4.600) 57.912] calc: 1 test: 1 +div: 8 read: 1 sample: 1 pad: 3 [45.556 ( 7.756) 53.312 ( 2.934) 56.246] calc: 1 test: 1 +div: 8 read: 1 sample: 1 pad: 2 [43.890 ( 9.422) 53.312 ( 1.268) 54.580] calc: 1 test: 1 +div: 8 read: 1 sample: 1 pad: 1 [42.224 ( 11.088) 53.312 ( -0.398) 52.914] calc: 0 test: 1 +div: 8 read: 1 sample: 1 pad: 0 [40.558 ( 12.754) 53.312 ( -2.064) 51.248] calc: 0 test: 0 +div: 8 read: 2 sample: 0 pad: 5 [48.888 ( 17.752) 66.640 ( -7.062) 59.578] calc: 0 test: 0 +div: 8 read: 2 sample: 0 pad: 4 [47.222 ( 19.418) 66.640 ( -8.728) 57.912] calc: 0 test: 0 +div: 8 read: 2 sample: 0 pad: 3 [45.556 ( 21.084) 66.640 (-10.394) 56.246] calc: 0 test: 0 +div: 8 read: 2 sample: 0 pad: 2 [43.890 ( 22.750) 66.640 (-12.060) 54.580] calc: 0 test: 0 +div: 8 read: 2 sample: 0 pad: 1 [42.224 ( 24.416) 66.640 (-13.726) 52.914] calc: 0 test: 0 +div: 8 read: 2 sample: 0 pad: 0 [40.558 ( 26.082) 66.640 (-15.392) 51.248] calc: 0 test: 0 +div: 8 read: 2 sample: 1 pad: 5 [48.888 ( 31.080) 79.968 (-20.390) 59.578] calc: 0 test: 0 +div: 8 read: 2 sample: 1 pad: 4 [47.222 ( 32.746) 79.968 (-22.056) 57.912] calc: 0 test: 0 +div: 8 read: 2 sample: 1 pad: 3 [45.556 ( 34.412) 79.968 (-23.722) 56.246] calc: 0 test: 0 +div: 8 read: 2 sample: 1 pad: 2 [43.890 ( 36.078) 79.968 (-25.388) 54.580] calc: 0 test: 0 +div: 8 read: 2 sample: 1 pad: 1 [42.224 ( 37.744) 79.968 (-27.054) 52.914] calc: 0 test: 0 +div: 8 read: 2 sample: 1 pad: 0 [40.558 ( 39.410) 79.968 (-28.720) 51.248] calc: 0 test: 0 + +F_core: 600 MHz, clock divider: 9, F_clk: 33.33 MHz +div: 9 read: 0 sample: 0 pad: 5 [50.554 (-35.560) 14.994 ( 49.582) 64.576] calc: 0 test: 0 +div: 9 read: 0 sample: 0 pad: 4 [48.888 (-33.894) 14.994 ( 47.916) 62.910] calc: 0 test: 0 +div: 9 read: 0 sample: 0 pad: 3 [47.222 (-32.228) 14.994 ( 46.250) 61.244] calc: 0 test: 0 +div: 9 read: 0 sample: 0 pad: 2 [45.556 (-30.562) 14.994 ( 44.584) 59.578] calc: 0 test: 0 +div: 9 read: 0 sample: 0 pad: 1 [43.890 (-28.896) 14.994 ( 42.918) 57.912] calc: 0 test: 0 +div: 9 read: 0 sample: 0 pad: 0 [42.224 (-27.230) 14.994 ( 41.252) 56.246] calc: 0 test: 0 +div: 9 read: 0 sample: 1 pad: 5 [50.554 (-20.566) 29.988 ( 34.588) 64.576] calc: 0 test: 0 +div: 9 read: 0 sample: 1 pad: 4 [48.888 (-18.900) 29.988 ( 32.922) 62.910] calc: 0 test: 0 +div: 9 read: 0 sample: 1 pad: 3 [47.222 (-17.234) 29.988 ( 31.256) 61.244] calc: 0 test: 0 +div: 9 read: 0 sample: 1 pad: 2 [45.556 (-15.568) 29.988 ( 29.590) 59.578] calc: 0 test: 0 +div: 9 read: 0 sample: 1 pad: 1 [43.890 (-13.902) 29.988 ( 27.924) 57.912] calc: 0 test: 0 +div: 9 read: 0 sample: 1 pad: 0 [42.224 (-12.236) 29.988 ( 26.258) 56.246] calc: 0 test: 0 +div: 9 read: 1 sample: 0 pad: 5 [50.554 ( -5.572) 44.982 ( 19.594) 64.576] calc: 0 test: 1 +div: 9 read: 1 sample: 0 pad: 4 [48.888 ( -3.906) 44.982 ( 17.928) 62.910] calc: 0 test: 1 +div: 9 read: 1 sample: 0 pad: 3 [47.222 ( -2.240) 44.982 ( 16.262) 61.244] calc: 0 test: 1 +div: 9 read: 1 sample: 0 pad: 2 [45.556 ( -0.574) 44.982 ( 14.596) 59.578] calc: 0 test: 1 +div: 9 read: 1 sample: 0 pad: 1 [43.890 ( 1.092) 44.982 ( 12.930) 57.912] calc: 1 test: 1 +div: 9 read: 1 sample: 0 pad: 0 [42.224 ( 2.758) 44.982 ( 11.264) 56.246] calc: 1 test: 1 *** +div: 9 read: 1 sample: 1 pad: 5 [50.554 ( 9.422) 59.976 ( 4.600) 64.576] calc: 1 test: 1 +div: 9 read: 1 sample: 1 pad: 4 [48.888 ( 11.088) 59.976 ( 2.934) 62.910] calc: 1 test: 1 +div: 9 read: 1 sample: 1 pad: 3 [47.222 ( 12.754) 59.976 ( 1.268) 61.244] calc: 1 test: 1 +div: 9 read: 1 sample: 1 pad: 2 [45.556 ( 14.420) 59.976 ( -0.398) 59.578] calc: 0 test: 1 +div: 9 read: 1 sample: 1 pad: 1 [43.890 ( 16.086) 59.976 ( -2.064) 57.912] calc: 0 test: 0 +div: 9 read: 1 sample: 1 pad: 0 [42.224 ( 17.752) 59.976 ( -3.730) 56.246] calc: 0 test: 0 +div: 9 read: 2 sample: 0 pad: 5 [50.554 ( 24.416) 74.970 (-10.394) 64.576] calc: 0 test: 0 +div: 9 read: 2 sample: 0 pad: 4 [48.888 ( 26.082) 74.970 (-12.060) 62.910] calc: 0 test: 0 +div: 9 read: 2 sample: 0 pad: 3 [47.222 ( 27.748) 74.970 (-13.726) 61.244] calc: 0 test: 0 +div: 9 read: 2 sample: 0 pad: 2 [45.556 ( 29.414) 74.970 (-15.392) 59.578] calc: 0 test: 0 +div: 9 read: 2 sample: 0 pad: 1 [43.890 ( 31.080) 74.970 (-17.058) 57.912] calc: 0 test: 0 +div: 9 read: 2 sample: 0 pad: 0 [42.224 ( 32.746) 74.970 (-18.724) 56.246] calc: 0 test: 0 +div: 9 read: 2 sample: 1 pad: 5 [50.554 ( 39.410) 89.964 (-25.388) 64.576] calc: 0 test: 0 +div: 9 read: 2 sample: 1 pad: 4 [48.888 ( 41.076) 89.964 (-27.054) 62.910] calc: 0 test: 0 +div: 9 read: 2 sample: 1 pad: 3 [47.222 ( 42.742) 89.964 (-28.720) 61.244] calc: 0 test: 0 +div: 9 read: 2 sample: 1 pad: 2 [45.556 ( 44.408) 89.964 (-30.386) 59.578] calc: 0 test: 0 +div: 9 read: 2 sample: 1 pad: 1 [43.890 ( 46.074) 89.964 (-32.052) 57.912] calc: 0 test: 0 +div: 9 read: 2 sample: 1 pad: 0 [42.224 ( 47.740) 89.964 (-33.718) 56.246] calc: 0 test: 0 + +F_core: 600 MHz, clock divider: 10, F_clk: 30.00 MHz +div: 10 read: 0 sample: 0 pad: 5 [52.220 (-35.560) 16.660 ( 52.914) 69.574] calc: 0 test: 0 +div: 10 read: 0 sample: 0 pad: 4 [50.554 (-33.894) 16.660 ( 51.248) 67.908] calc: 0 test: 0 +div: 10 read: 0 sample: 0 pad: 3 [48.888 (-32.228) 16.660 ( 49.582) 66.242] calc: 0 test: 0 +div: 10 read: 0 sample: 0 pad: 2 [47.222 (-30.562) 16.660 ( 47.916) 64.576] calc: 0 test: 0 +div: 10 read: 0 sample: 0 pad: 1 [45.556 (-28.896) 16.660 ( 46.250) 62.910] calc: 0 test: 0 +div: 10 read: 0 sample: 0 pad: 0 [43.890 (-27.230) 16.660 ( 44.584) 61.244] calc: 0 test: 0 +div: 10 read: 0 sample: 1 pad: 5 [52.220 (-18.900) 33.320 ( 36.254) 69.574] calc: 0 test: 0 +div: 10 read: 0 sample: 1 pad: 4 [50.554 (-17.234) 33.320 ( 34.588) 67.908] calc: 0 test: 0 +div: 10 read: 0 sample: 1 pad: 3 [48.888 (-15.568) 33.320 ( 32.922) 66.242] calc: 0 test: 0 +div: 10 read: 0 sample: 1 pad: 2 [47.222 (-13.902) 33.320 ( 31.256) 64.576] calc: 0 test: 0 +div: 10 read: 0 sample: 1 pad: 1 [45.556 (-12.236) 33.320 ( 29.590) 62.910] calc: 0 test: 0 +div: 10 read: 0 sample: 1 pad: 0 [43.890 (-10.570) 33.320 ( 27.924) 61.244] calc: 0 test: 1 +div: 10 read: 1 sample: 0 pad: 5 [52.220 ( -2.240) 49.980 ( 19.594) 69.574] calc: 0 test: 1 +div: 10 read: 1 sample: 0 pad: 4 [50.554 ( -0.574) 49.980 ( 17.928) 67.908] calc: 0 test: 1 +div: 10 read: 1 sample: 0 pad: 3 [48.888 ( 1.092) 49.980 ( 16.262) 66.242] calc: 1 test: 1 +div: 10 read: 1 sample: 0 pad: 2 [47.222 ( 2.758) 49.980 ( 14.596) 64.576] calc: 1 test: 1 +div: 10 read: 1 sample: 0 pad: 1 [45.556 ( 4.424) 49.980 ( 12.930) 62.910] calc: 1 test: 1 *** +div: 10 read: 1 sample: 0 pad: 0 [43.890 ( 6.090) 49.980 ( 11.264) 61.244] calc: 1 test: 1 +div: 10 read: 1 sample: 1 pad: 5 [52.220 ( 14.420) 66.640 ( 2.934) 69.574] calc: 1 test: 1 +div: 10 read: 1 sample: 1 pad: 4 [50.554 ( 16.086) 66.640 ( 1.268) 67.908] calc: 1 test: 1 +div: 10 read: 1 sample: 1 pad: 3 [48.888 ( 17.752) 66.640 ( -0.398) 66.242] calc: 0 test: 1 +div: 10 read: 1 sample: 1 pad: 2 [47.222 ( 19.418) 66.640 ( -2.064) 64.576] calc: 0 test: 0 +div: 10 read: 1 sample: 1 pad: 1 [45.556 ( 21.084) 66.640 ( -3.730) 62.910] calc: 0 test: 0 +div: 10 read: 1 sample: 1 pad: 0 [43.890 ( 22.750) 66.640 ( -5.396) 61.244] calc: 0 test: 0 +div: 10 read: 2 sample: 0 pad: 5 [52.220 ( 31.080) 83.300 (-13.726) 69.574] calc: 0 test: 0 +div: 10 read: 2 sample: 0 pad: 4 [50.554 ( 32.746) 83.300 (-15.392) 67.908] calc: 0 test: 0 +div: 10 read: 2 sample: 0 pad: 3 [48.888 ( 34.412) 83.300 (-17.058) 66.242] calc: 0 test: 0 +div: 10 read: 2 sample: 0 pad: 2 [47.222 ( 36.078) 83.300 (-18.724) 64.576] calc: 0 test: 0 +div: 10 read: 2 sample: 0 pad: 1 [45.556 ( 37.744) 83.300 (-20.390) 62.910] calc: 0 test: 0 +div: 10 read: 2 sample: 0 pad: 0 [43.890 ( 39.410) 83.300 (-22.056) 61.244] calc: 0 test: 0 +div: 10 read: 2 sample: 1 pad: 5 [52.220 ( 47.740) 99.960 (-30.386) 69.574] calc: 0 test: 0 +div: 10 read: 2 sample: 1 pad: 4 [50.554 ( 49.406) 99.960 (-32.052) 67.908] calc: 0 test: 0 +div: 10 read: 2 sample: 1 pad: 3 [48.888 ( 51.072) 99.960 (-33.718) 66.242] calc: 0 test: 0 +div: 10 read: 2 sample: 1 pad: 2 [47.222 ( 52.738) 99.960 (-35.384) 64.576] calc: 0 test: 0 +div: 10 read: 2 sample: 1 pad: 1 [45.556 ( 54.404) 99.960 (-37.050) 62.910] calc: 0 test: 0 +div: 10 read: 2 sample: 1 pad: 0 [43.890 ( 56.070) 99.960 (-38.716) 61.244] calc: 0 test: 0 + +F_core: 600 MHz, clock divider: 11, F_clk: 27.27 MHz +div: 11 read: 0 sample: 0 pad: 5 [53.886 (-35.560) 18.326 ( 56.246) 74.572] calc: 0 test: 0 +div: 11 read: 0 sample: 0 pad: 4 [52.220 (-33.894) 18.326 ( 54.580) 72.906] calc: 0 test: 0 +div: 11 read: 0 sample: 0 pad: 3 [50.554 (-32.228) 18.326 ( 52.914) 71.240] calc: 0 test: 0 +div: 11 read: 0 sample: 0 pad: 2 [48.888 (-30.562) 18.326 ( 51.248) 69.574] calc: 0 test: 0 +div: 11 read: 0 sample: 0 pad: 1 [47.222 (-28.896) 18.326 ( 49.582) 67.908] calc: 0 test: 0 +div: 11 read: 0 sample: 0 pad: 0 [45.556 (-27.230) 18.326 ( 47.916) 66.242] calc: 0 test: 0 +div: 11 read: 0 sample: 1 pad: 5 [53.886 (-17.234) 36.652 ( 37.920) 74.572] calc: 0 test: 0 +div: 11 read: 0 sample: 1 pad: 4 [52.220 (-15.568) 36.652 ( 36.254) 72.906] calc: 0 test: 0 +div: 11 read: 0 sample: 1 pad: 3 [50.554 (-13.902) 36.652 ( 34.588) 71.240] calc: 0 test: 0 +div: 11 read: 0 sample: 1 pad: 2 [48.888 (-12.236) 36.652 ( 32.922) 69.574] calc: 0 test: 0 +div: 11 read: 0 sample: 1 pad: 1 [47.222 (-10.570) 36.652 ( 31.256) 67.908] calc: 0 test: 0 +div: 11 read: 0 sample: 1 pad: 0 [45.556 ( -8.904) 36.652 ( 29.590) 66.242] calc: 0 test: 1 +div: 11 read: 1 sample: 0 pad: 5 [53.886 ( 1.092) 54.978 ( 19.594) 74.572] calc: 1 test: 1 +div: 11 read: 1 sample: 0 pad: 4 [52.220 ( 2.758) 54.978 ( 17.928) 72.906] calc: 1 test: 1 +div: 11 read: 1 sample: 0 pad: 3 [50.554 ( 4.424) 54.978 ( 16.262) 71.240] calc: 1 test: 1 +div: 11 read: 1 sample: 0 pad: 2 [48.888 ( 6.090) 54.978 ( 14.596) 69.574] calc: 1 test: 1 +div: 11 read: 1 sample: 0 pad: 1 [47.222 ( 7.756) 54.978 ( 12.930) 67.908] calc: 1 test: 1 +div: 11 read: 1 sample: 0 pad: 0 [45.556 ( 9.422) 54.978 ( 11.264) 66.242] calc: 1 test: 1 +div: 11 read: 1 sample: 1 pad: 5 [53.886 ( 19.418) 73.304 ( 1.268) 74.572] calc: 1 test: 1 +div: 11 read: 1 sample: 1 pad: 4 [52.220 ( 21.084) 73.304 ( -0.398) 72.906] calc: 0 test: 1 +div: 11 read: 1 sample: 1 pad: 3 [50.554 ( 22.750) 73.304 ( -2.064) 71.240] calc: 0 test: 0 +div: 11 read: 1 sample: 1 pad: 2 [48.888 ( 24.416) 73.304 ( -3.730) 69.574] calc: 0 test: 0 +div: 11 read: 1 sample: 1 pad: 1 [47.222 ( 26.082) 73.304 ( -5.396) 67.908] calc: 0 test: 0 +div: 11 read: 1 sample: 1 pad: 0 [45.556 ( 27.748) 73.304 ( -7.062) 66.242] calc: 0 test: 0 +div: 11 read: 2 sample: 0 pad: 5 [53.886 ( 37.744) 91.630 (-17.058) 74.572] calc: 0 test: 0 +div: 11 read: 2 sample: 0 pad: 4 [52.220 ( 39.410) 91.630 (-18.724) 72.906] calc: 0 test: 0 +div: 11 read: 2 sample: 0 pad: 3 [50.554 ( 41.076) 91.630 (-20.390) 71.240] calc: 0 test: 0 +div: 11 read: 2 sample: 0 pad: 2 [48.888 ( 42.742) 91.630 (-22.056) 69.574] calc: 0 test: 0 +div: 11 read: 2 sample: 0 pad: 1 [47.222 ( 44.408) 91.630 (-23.722) 67.908] calc: 0 test: 0 +div: 11 read: 2 sample: 0 pad: 0 [45.556 ( 46.074) 91.630 (-25.388) 66.242] calc: 0 test: 0 +div: 11 read: 2 sample: 1 pad: 5 [53.886 ( 56.070) 109.956 (-35.384) 74.572] calc: 0 test: 0 +div: 11 read: 2 sample: 1 pad: 4 [52.220 ( 57.736) 109.956 (-37.050) 72.906] calc: 0 test: 0 +div: 11 read: 2 sample: 1 pad: 3 [50.554 ( 59.402) 109.956 (-38.716) 71.240] calc: 0 test: 0 +div: 11 read: 2 sample: 1 pad: 2 [48.888 ( 61.068) 109.956 (-40.382) 69.574] calc: 0 test: 0 +div: 11 read: 2 sample: 1 pad: 1 [47.222 ( 62.734) 109.956 (-42.048) 67.908] calc: 0 test: 0 +div: 11 read: 2 sample: 1 pad: 0 [45.556 ( 64.400) 109.956 (-43.714) 66.242] calc: 0 test: 0 + +F_core: 600 MHz, clock divider: 12, F_clk: 25.00 MHz +div: 12 read: 0 sample: 0 pad: 5 [55.552 (-35.560) 19.992 ( 59.578) 79.570] calc: 0 test: 0 +div: 12 read: 0 sample: 0 pad: 4 [53.886 (-33.894) 19.992 ( 57.912) 77.904] calc: 0 test: 0 +div: 12 read: 0 sample: 0 pad: 3 [52.220 (-32.228) 19.992 ( 56.246) 76.238] calc: 0 test: 0 +div: 12 read: 0 sample: 0 pad: 2 [50.554 (-30.562) 19.992 ( 54.580) 74.572] calc: 0 test: 0 +div: 12 read: 0 sample: 0 pad: 1 [48.888 (-28.896) 19.992 ( 52.914) 72.906] calc: 0 test: 0 +div: 12 read: 0 sample: 0 pad: 0 [47.222 (-27.230) 19.992 ( 51.248) 71.240] calc: 0 test: 0 +div: 12 read: 0 sample: 1 pad: 5 [55.552 (-15.568) 39.984 ( 39.586) 79.570] calc: 0 test: 0 +div: 12 read: 0 sample: 1 pad: 4 [53.886 (-13.902) 39.984 ( 37.920) 77.904] calc: 0 test: 0 +div: 12 read: 0 sample: 1 pad: 3 [52.220 (-12.236) 39.984 ( 36.254) 76.238] calc: 0 test: 0 +div: 12 read: 0 sample: 1 pad: 2 [50.554 (-10.570) 39.984 ( 34.588) 74.572] calc: 0 test: 1 +div: 12 read: 0 sample: 1 pad: 1 [48.888 ( -8.904) 39.984 ( 32.922) 72.906] calc: 0 test: 1 +div: 12 read: 0 sample: 1 pad: 0 [47.222 ( -7.238) 39.984 ( 31.256) 71.240] calc: 0 test: 1 +div: 12 read: 1 sample: 0 pad: 5 [55.552 ( 4.424) 59.976 ( 19.594) 79.570] calc: 1 test: 1 +div: 12 read: 1 sample: 0 pad: 4 [53.886 ( 6.090) 59.976 ( 17.928) 77.904] calc: 1 test: 1 +div: 12 read: 1 sample: 0 pad: 3 [52.220 ( 7.756) 59.976 ( 16.262) 76.238] calc: 1 test: 1 +div: 12 read: 1 sample: 0 pad: 2 [50.554 ( 9.422) 59.976 ( 14.596) 74.572] calc: 1 test: 1 +div: 12 read: 1 sample: 0 pad: 1 [48.888 ( 11.088) 59.976 ( 12.930) 72.906] calc: 1 test: 1 +div: 12 read: 1 sample: 0 pad: 0 [47.222 ( 12.754) 59.976 ( 11.264) 71.240] calc: 1 test: 1 +div: 12 read: 1 sample: 1 pad: 5 [55.552 ( 24.416) 79.968 ( -0.398) 79.570] calc: 0 test: 1 +div: 12 read: 1 sample: 1 pad: 4 [53.886 ( 26.082) 79.968 ( -2.064) 77.904] calc: 0 test: 0 +div: 12 read: 1 sample: 1 pad: 3 [52.220 ( 27.748) 79.968 ( -3.730) 76.238] calc: 0 test: 0 +div: 12 read: 1 sample: 1 pad: 2 [50.554 ( 29.414) 79.968 ( -5.396) 74.572] calc: 0 test: 0 +div: 12 read: 1 sample: 1 pad: 1 [48.888 ( 31.080) 79.968 ( -7.062) 72.906] calc: 0 test: 0 +div: 12 read: 1 sample: 1 pad: 0 [47.222 ( 32.746) 79.968 ( -8.728) 71.240] calc: 0 test: 0 +div: 12 read: 2 sample: 0 pad: 5 [55.552 ( 44.408) 99.960 (-20.390) 79.570] calc: 0 test: 0 +div: 12 read: 2 sample: 0 pad: 4 [53.886 ( 46.074) 99.960 (-22.056) 77.904] calc: 0 test: 0 +div: 12 read: 2 sample: 0 pad: 3 [52.220 ( 47.740) 99.960 (-23.722) 76.238] calc: 0 test: 0 +div: 12 read: 2 sample: 0 pad: 2 [50.554 ( 49.406) 99.960 (-25.388) 74.572] calc: 0 test: 0 +div: 12 read: 2 sample: 0 pad: 1 [48.888 ( 51.072) 99.960 (-27.054) 72.906] calc: 0 test: 0 +div: 12 read: 2 sample: 0 pad: 0 [47.222 ( 52.738) 99.960 (-28.720) 71.240] calc: 0 test: 0 +div: 12 read: 2 sample: 1 pad: 5 [55.552 ( 64.400) 119.952 (-40.382) 79.570] calc: 0 test: 0 +div: 12 read: 2 sample: 1 pad: 4 [53.886 ( 66.066) 119.952 (-42.048) 77.904] calc: 0 test: 0 +div: 12 read: 2 sample: 1 pad: 3 [52.220 ( 67.732) 119.952 (-43.714) 76.238] calc: 0 test: 0 +div: 12 read: 2 sample: 1 pad: 2 [50.554 ( 69.398) 119.952 (-45.380) 74.572] calc: 0 test: 0 +div: 12 read: 2 sample: 1 pad: 1 [48.888 ( 71.064) 119.952 (-47.046) 72.906] calc: 0 test: 0 +div: 12 read: 2 sample: 1 pad: 0 [47.222 ( 72.730) 119.952 (-48.712) 71.240] calc: 0 test: 0 +SDRAM timing finished diff --git a/tools/sdram_timing/src/sdram_calc.h b/tools/sdram_timing/src/sdram_calc.h new file mode 100644 index 0000000..313aca9 --- /dev/null +++ b/tools/sdram_timing/src/sdram_calc.h @@ -0,0 +1,13 @@ + +extern void sdram_calc_print_info(unsigned f_core); +extern void sdram_calc_timings(unsigned f_core, + unsigned clock_divider, + unsigned read_delay_clocks, + unsigned sample_delay, + unsigned pad_delay, + unsigned& t_read_min, + int& t_left_margin, + unsigned& t_read, + int& t_right_margin, + unsigned& t_read_max, + unsigned& fit); diff --git a/tools/sdram_timing_calculations/src/sdram_timing_calculations.c b/tools/sdram_timing/src/sdram_calc.xc similarity index 66% rename from tools/sdram_timing_calculations/src/sdram_timing_calculations.c rename to tools/sdram_timing/src/sdram_calc.xc index 3d09dc1..5a43e60 100644 --- a/tools/sdram_timing_calculations/src/sdram_timing_calculations.c +++ b/tools/sdram_timing/src/sdram_calc.xc @@ -1,5 +1,5 @@ #include -#include +#include "sdram_calc.h" // Taking data from SDRAM datasheet // -------------------------------- @@ -64,12 +64,10 @@ // all values in picoseconds and MHz +#if defined(__XS3A__) //---------------------------------------------------------------------------------------- -// Values for a xcore-ai/600 MHz onboard SDRAM case +// SDRAM test board for xcore-ai XU316 //---------------------------------------------------------------------------------------- -// processor clock -#define FCORE 600 -#define TCORE (1000000/FCORE) // I/O timing for xcore_ai, A.2, p.19, X1D00..X1D71 #define LAT_PIN_DEP_MIN 400 @@ -81,32 +79,29 @@ #define LAT_LINE_CAP_MAX 9000 // I/O timing for xcore_ai, 4.1, p.13 -#define LAT_RESYNC_MIN (4*TCORE) -#define LAT_RESYNC_MAX (5*TCORE) +#define LAT_RESYNC_MIN 4 // in t_core units +#define LAT_RESYNC_MAX 5 // in t_core units // IS45S16400J Datasheet p.16 #define SDRAM_T_AC2 5400 #define SDRAM_T_OH2 2500 -#if 0 +#elif defined(__XS2A__) //---------------------------------------------------------------------------------------- -// Values for the XS2/500 MHz slicekit +// Values for the XU216 slicekit //---------------------------------------------------------------------------------------- -// processor clock -#define FCORE 500 -#define TCORE (1000000/FCORE) // I/O timing for xCORE200, p.18, all pins -#define LAT_PIN_DEP_MIN 3000 -#define LAT_PIN_DEP_MAX 11300 +#define LAT_PIN_DEP_MIN 3000 +#define LAT_PIN_DEP_MAX 11300 // 1.4 ns of PCB round trip delay (correct for XCORE200 slicekit) #define LAT_LINE_CAP_MIN 1400 #define LAT_LINE_CAP_MAX 1400 // I/O timing for xcore_ai, 4.1, p.13 -#define LAT_RESYNC_MIN (4*TCORE) -#define LAT_RESYNC_MAX (5*TCORE) +#define LAT_RESYNC_MIN 4 // in t_core units +#define LAT_RESYNC_MAX 5 // in t_core units // IS45S16400D Datasheet p.14 #define SDRAM_T_AC2 6000 @@ -116,40 +111,42 @@ //---------------------------------------------------------------------------------------- -int main() +static unsigned rtt_min(unsigned t_core) { - printf("SDRAM input read timing\n"); - printf("-----------------------\n"); - - unsigned rtt_min = LAT_PIN_DEP_MIN + LAT_LINE_CAP_MIN + LAT_RESYNC_MIN; - unsigned rtt_max = LAT_PIN_DEP_MAX + LAT_LINE_CAP_MAX + LAT_RESYNC_MAX; - printf("\nRound trip time min: %d ps, max: %d ps\n", rtt_min, rtt_max); - - for (unsigned clock_divider = 4; clock_divider < 13; clock_divider++) - { - printf("\nF_core: %d MHz, clock divider: %d, F_clk: %d.%02d MHz\n", - FCORE, clock_divider, FCORE / (2 * clock_divider), (FCORE * 50 / clock_divider) % 100); - - for (unsigned read_delay_clocks = 0; read_delay_clocks < 3; read_delay_clocks++) - { - for (unsigned sample_delay = 0; sample_delay < 2; sample_delay++) - { - // t_read = Tclk/2 + (read_delay_clocks + sample_delay / 2) * Tclk - // Tclk = Tcore * clock_divider * 2 - unsigned t_read = TCORE * clock_divider * (read_delay_clocks * 2 + 1 + sample_delay); - for (unsigned i = 0; i < 6; i++) - { - unsigned pad_delay = 5 - i; - unsigned t_read_min = (clock_divider + pad_delay) * TCORE + SDRAM_T_AC2 + rtt_max; - unsigned t_read_max = (3 * clock_divider + pad_delay) * TCORE + SDRAM_T_OH2 + rtt_min; - unsigned success = (t_read_min < t_read && t_read < t_read_max); - printf("div: %2d read: %d sample: %d pad: %d result: %d [%5d ..(%6d).. %5d ..(%6d).. %5d] ps\n", - clock_divider, read_delay_clocks, sample_delay, pad_delay, success, - t_read_min, t_read - t_read_min, t_read, t_read_max - t_read, t_read_max); - } - } - } - } - - return 0; + return LAT_PIN_DEP_MIN + LAT_LINE_CAP_MIN + LAT_RESYNC_MIN * t_core; +} + +static unsigned rtt_max(unsigned t_core) +{ + return LAT_PIN_DEP_MAX + LAT_LINE_CAP_MAX + LAT_RESYNC_MAX * t_core; +} + +void sdram_calc_print_info(unsigned f_core) +{ + unsigned t_core = 1000000/f_core; + printf("Round trip time min: %d ps, max: %d ps\n", rtt_min(t_core), rtt_max(t_core)); +} + +void sdram_calc_timings( + unsigned f_core, + unsigned clock_divider, + unsigned read_delay_clocks, + unsigned sample_delay, + unsigned pad_delay, + unsigned& t_read_min, + int& t_left_margin, + unsigned& t_read, + int& t_right_margin, + unsigned& t_read_max, + unsigned& fit) +{ + unsigned t_core = 1000000/f_core; + // t_read = Tclk/2 + (read_delay_clocks + sample_delay / 2) * Tclk + // Tclk = Tcore * clock_divider * 2 + t_read = t_core * clock_divider * (read_delay_clocks * 2 + 1 + sample_delay); + t_read_min = (clock_divider + pad_delay) * t_core + SDRAM_T_AC2 + rtt_max(t_core); + t_read_max = (3 * clock_divider + pad_delay) * t_core + SDRAM_T_OH2 + rtt_min(t_core); + t_left_margin = (int)t_read - (int)t_read_min; + t_right_margin = (int)t_read_max - (int)t_read; + fit = (t_read_min < t_read && t_read < t_read_max); } diff --git a/tools/sdram_timing/src/sdram_ports.h b/tools/sdram_timing/src/sdram_ports.h new file mode 100644 index 0000000..15fd709 --- /dev/null +++ b/tools/sdram_timing/src/sdram_ports.h @@ -0,0 +1,30 @@ +#include + +#if defined(__XS3A__) +// SDRAM test board for XU316 +#define SERVER_TILE 1 +#define PORT_SDRAM_DQ_AH XS1_PORT_16A +#define PORT_SDRAM_CAS XS1_PORT_1A +#define PORT_SDRAM_RAS XS1_PORT_1P +#define PORT_SDRAM_WE XS1_PORT_1M +#define PORT_SDRAM_CLK XS1_PORT_1F +#define CLOCK_SDRAM XS1_CLKBLK_1 +#elif defined(__XS2A__) +// Triangle slot tile 0 for XU216 of XP-SKC-X200 slice kit board +#define SERVER_TILE 0 +#define PORT_SDRAM_DQ_AH XS1_PORT_16B +#define PORT_SDRAM_CAS XS1_PORT_1J +#define PORT_SDRAM_RAS XS1_PORT_1I +#define PORT_SDRAM_WE XS1_PORT_1K +#define PORT_SDRAM_CLK XS1_PORT_1L +#define CLOCK_SDRAM XS1_CLKBLK_2 +#else +// Square slot on A16 slicekit +#define SERVER_TILE 1 +#define PORT_SDRAM_DQ_AH XS1_PORT_16A +#define PORT_SDRAM_CAS XS1_PORT_1B +#define PORT_SDRAM_RAS XS1_PORT_1G +#define PORT_SDRAM_WE XS1_PORT_1C +#define PORT_SDRAM_CLK XS1_PORT_1F +#define CLOCK_SDRAM XS1_CLKBLK_2 +#endif diff --git a/tools/sdram_timing/src/sdram_test.h b/tools/sdram_timing/src/sdram_test.h new file mode 100644 index 0000000..d985c5a --- /dev/null +++ b/tools/sdram_timing/src/sdram_test.h @@ -0,0 +1,7 @@ + +extern unsigned sdram_test_get_core_frequency_MHz(); +extern void sdram_test_print_info(); +extern unsigned sdram_test_run(unsigned clock_divider, + unsigned read_delay_whole_clocks, + unsigned sample_delay, + unsigned pad_delay); diff --git a/tools/sdram_timing_test/src/sdram_timing_test.xc b/tools/sdram_timing/src/sdram_test.xc similarity index 56% rename from tools/sdram_timing_test/src/sdram_timing_test.xc rename to tools/sdram_timing/src/sdram_test.xc index b6cbc76..c4e8508 100644 --- a/tools/sdram_timing_test/src/sdram_timing_test.xc +++ b/tools/sdram_timing/src/sdram_test.xc @@ -2,16 +2,14 @@ #include #include #include "sdram.h" +#include "sdram_test.h" +#include "sdram_ports.h" -#define VERBOSE_MSG 1 #define ERROR_MSG 0 -//For XS2 (xCORE200) put an SDRAM slice into the 'triangle' slot of tile 0 of the XP-SKC-X200 slice kit -//If using 256Mb slice, then define USE_256Mb below, otherwise leave commented out - -#define SDRAM_256Mb 1 //Use IS42S16160D 256Mb or similar -#define SDRAM_128Mb 0 //Use IS42S16800D 128Mb - //otherwise IS42S16400D 64Mb which is default on XMOS boards +#define SDRAM_256Mb 1 // Use IS42S16160D 256Mb or similar +#define SDRAM_128Mb 0 // Use IS42S16800D 128Mb + // otherwise IS42S16400D 64Mb which is default on XMOS boards #define CAS_LATENCY 2 #define REFRESH_MS 64 @@ -43,36 +41,14 @@ #define ROW_WORDS 128 #endif -#if defined(__XS3A__) -// SDRAM test board for XU316 -#define SERVER_TILE 1 -on tile[SERVER_TILE] : out buffered port:32 sdram_dq_ah = XS1_PORT_16A; -on tile[SERVER_TILE] : out buffered port:32 sdram_cas = XS1_PORT_1A; -on tile[SERVER_TILE] : out buffered port:32 sdram_ras = XS1_PORT_1P; -on tile[SERVER_TILE] : out buffered port:8 sdram_we = XS1_PORT_1M; -on tile[SERVER_TILE] : out port sdram_clk = XS1_PORT_1F; -on tile[SERVER_TILE] : clock sdram_cb = XS1_CLKBLK_1; -#elif defined(__XS2A__) -//Triangle slot tile 0 for XU216 -#define SERVER_TILE 0 -on tile[SERVER_TILE] : out buffered port:32 sdram_dq_ah = XS1_PORT_16B; -on tile[SERVER_TILE] : out buffered port:32 sdram_cas = XS1_PORT_1J; -on tile[SERVER_TILE] : out buffered port:32 sdram_ras = XS1_PORT_1I; -on tile[SERVER_TILE] : out buffered port:8 sdram_we = XS1_PORT_1K; -on tile[SERVER_TILE] : out port sdram_clk = XS1_PORT_1L; -on tile[SERVER_TILE] : clock sdram_cb = XS1_CLKBLK_2; -#else -//Square slot on A16 slicekit -#define SERVER_TILE 1 -on tile[SERVER_TILE] : out buffered port:32 sdram_dq_ah = XS1_PORT_16A; -on tile[SERVER_TILE] : out buffered port:32 sdram_cas = XS1_PORT_1B; -on tile[SERVER_TILE] : out buffered port:32 sdram_ras = XS1_PORT_1G; -on tile[SERVER_TILE] : out buffered port:8 sdram_we = XS1_PORT_1C; -on tile[SERVER_TILE] : out port sdram_clk = XS1_PORT_1F; -on tile[SERVER_TILE] : clock sdram_cb = XS1_CLKBLK_2; -#endif +on tile[SERVER_TILE] : out buffered port:32 sdram_dq_ah = PORT_SDRAM_DQ_AH; +on tile[SERVER_TILE] : out buffered port:32 sdram_cas = PORT_SDRAM_CAS; +on tile[SERVER_TILE] : out buffered port:32 sdram_ras = PORT_SDRAM_RAS; +on tile[SERVER_TILE] : out buffered port:8 sdram_we = PORT_SDRAM_WE; +on tile[SERVER_TILE] : out port sdram_clk = PORT_SDRAM_CLK; +on tile[SERVER_TILE] : clock sdram_cb = CLOCK_SDRAM; -unsigned get_core_frequency() +unsigned sdram_test_get_core_frequency_MHz() { unsigned pll_ctl_value; @@ -82,8 +58,8 @@ unsigned get_core_frequency() unsigned F = (pll_ctl_value >> 8) & 0x1FFF; unsigned R = (pll_ctl_value >> 0) & 0x3F; unsigned f_osc = 24000000; - unsigned f_core = (f_osc / 2) * (F+1) / ((R+1) * (OD+1)); - return f_core; + unsigned f_core_Hz = (f_osc / 2) * (F+1) / ((R+1) * (OD+1)); + return f_core_Hz / 1000000; } unsigned sdram_tester(streaming chanend c_server) @@ -197,14 +173,24 @@ unsigned sdram_tester(streaming chanend c_server) return 1; } -void sdram_test(unsigned clock_divider, - unsigned read_delay_whole_clocks, - unsigned sample_delay, - unsigned pad_delay) +void sdram_test_print_info() +{ +#if SDRAM_256Mb + printf("Using 256Mb SDRAM\n"); +#elif SDRAM_128Mb + printf("Using 128Mb SDRAM\n"); +#else + printf("Using 64Mb SDRAM\n"); +#endif +} + +unsigned sdram_test_run(unsigned clock_divider, + unsigned read_delay_whole_clocks, + unsigned sample_delay, + unsigned pad_delay) { streaming chan c_sdram[1]; unsigned success; - par { { @@ -222,60 +208,5 @@ void sdram_test(unsigned clock_divider, sdram_shutdown(c_sdram[0]); } } - printf("div: %2d read: %d sample: %d pad: %d result: %d\n", - clock_divider, read_delay_whole_clocks, sample_delay, pad_delay, success); -} - -void sdram_test_suite() -{ - if (VERBOSE_MSG) - { -#if SDRAM_256Mb - printf("Using 256Mb SDRAM\n"); -#elif SDRAM_128Mb - printf("Using 128Mb SDRAM\n"); -#else - printf("Using 64Mb SDRAM\n"); -#endif - printf("starting SDRAM tests\n"); - } - - unsigned f_core = get_core_frequency(); - - for (unsigned clock_divider = 4; clock_divider < 13; clock_divider++) - { - if (VERBOSE_MSG) - { - unsigned f_core_MHz = f_core / 1000000; - printf("\nF_core: %d MHz, clock divider: %d, F_clk: %d.%02d MHz\n", - f_core_MHz, clock_divider, - f_core_MHz / (2 * clock_divider), - (f_core_MHz * 50 / clock_divider) % 100); - } - for (unsigned read_delay_clocks = 0; read_delay_clocks < 3; read_delay_clocks++) - { - for (unsigned sample_delay = 0; sample_delay < 2; sample_delay++) - { - for (unsigned i = 0; i < 6; i++) - { - unsigned pad_delay = 5 - i; - sdram_test(clock_divider, read_delay_clocks, sample_delay, pad_delay); - } - } - } - } - if (VERBOSE_MSG) - { - printf("SDRAM tests finished\n\n"); - } -} - -int main() -{ - par - { - on tile[SERVER_TILE]: sdram_test_suite(); - on tile[SERVER_TILE]: par(int i=0;i<6;i++) while(1); - } - return 0; + return success; } diff --git a/tools/sdram_timing/src/sdram_timing.xc b/tools/sdram_timing/src/sdram_timing.xc new file mode 100644 index 0000000..6f32925 --- /dev/null +++ b/tools/sdram_timing/src/sdram_timing.xc @@ -0,0 +1,104 @@ +#include +#include +#include +#include "sdram_calc.h" +#include "sdram_test.h" +#include "sdram_ports.h" + +#define CALC 1 // set to 0 if parameters to calculate are not available +#define TEST 1 // set to 0 if hardware for testing is not available + +#define DEFAULT_FCORE 500 // Core clock rate used when TEST is 0 + +#if !TEST && !CALC +#error "at least one of CALC and TEST should be set to 1" +#endif + +#define VERBOSE_MSG 1 + +void sdram_test_suite() +{ +#if TEST + unsigned f_core = sdram_test_get_core_frequency_MHz(); +#else + unsigned f_core = DEFAULT_FCORE; +#endif + + if (VERBOSE_MSG) + { +#if TEST + sdram_test_print_info(); +#endif +#if CALC + sdram_calc_print_info(f_core); +#endif + printf("starting SDRAM timing\n"); + } + + for (unsigned clock_divider = 4; clock_divider < 13; clock_divider++) + { + if (VERBOSE_MSG) + { + printf("\nF_core: %d MHz, clock divider: %d, F_clk: %d.%02d MHz\n", + f_core, clock_divider, + f_core / (2 * clock_divider), + (f_core * 50 / clock_divider) % 100); + } + for (unsigned read_delay_clocks = 0; read_delay_clocks < 3; read_delay_clocks++) + { + for (unsigned sample_delay = 0; sample_delay < 2; sample_delay++) + { + for (unsigned i = 0; i < 6; i++) + { + unsigned pad_delay = 5 - i; +#if CALC + unsigned t_read_min; + int t_left_margin; + unsigned t_read; + int t_right_margin; + unsigned t_read_max; + unsigned fit; + sdram_calc_timings(f_core, clock_divider, + read_delay_clocks, sample_delay, pad_delay, + t_read_min, t_left_margin, t_read, + t_right_margin, t_read_max, fit); +#endif +#if TEST + unsigned success = sdram_test_run(clock_divider, + read_delay_clocks, sample_delay, pad_delay); +#endif + printf("div: %2d read: %d sample: %d pad: %d", + clock_divider, read_delay_clocks, sample_delay, pad_delay); +#if CALC + // timing window shown in nanoseconds + printf(" [%6.3f (%7.3f) %7.3f (%7.3f) %6.3f] calc: %d", + (float)t_read_min/1000.0, + (float)t_left_margin/1000.0, + (float)t_read/1000.0, + (float)t_right_margin/1000.0, + (float)t_read_max/1000.0, + fit); +#endif +#if TEST + printf(" test: %d", success); +#endif + printf("\n"); + } + } + } + } + if (VERBOSE_MSG) + { + printf("SDRAM timing finished\n\n"); + } +} + +int main() +{ + par + { + on tile[SERVER_TILE]: sdram_test_suite(); + on tile[SERVER_TILE]: par(int i=0;i<6;i++) while(1); + } + return 0; +} diff --git a/tools/sdram_timing_test/xcore_ai_sdram_test_board.xn b/tools/sdram_timing/xcore_ai_sdram_test_board.xn similarity index 100% rename from tools/sdram_timing_test/xcore_ai_sdram_test_board.xn rename to tools/sdram_timing/xcore_ai_sdram_test_board.xn diff --git a/tools/sdram_timing_calculations/CMakeLists.txt b/tools/sdram_timing_calculations/CMakeLists.txt deleted file mode 100644 index 2b074e2..0000000 --- a/tools/sdram_timing_calculations/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -cmake_minimum_required(VERSION 3.21) -include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake) -project(sdram_timing_calculations) - -set(XMOS_SANDBOX_DIR ${CMAKE_CURRENT_LIST_DIR}/../../..) -set(APP_HW_TARGET XU316-1024-FB265-C24) -set(APP_COMPILER_FLAGS -O3 -Wall) -set(APP_PCA_ENABLE ON) -set(APP_DEPENDENT_MODULES) -set(APP_INCLUDES src) - -XMOS_REGISTER_APP() diff --git a/tools/sdram_timing_calculations/README.rst b/tools/sdram_timing_calculations/README.rst deleted file mode 100644 index 118fe1e..0000000 --- a/tools/sdram_timing_calculations/README.rst +++ /dev/null @@ -1,57 +0,0 @@ -SDRAM Data Input Timing Calculations -==================================== - -:scope: Tools -:description: Tool to find input delays matching the round trip window -:keywords: Memory,SDRAM,Round Trip Time -:boards: custom board with xcore-ai and SDRAM - -The tool calculates read delays for the SDRAM data input ports. -Input parameters are to be taken from datasheets to edit the -defines in the code. C was taken as programming language for the -tool just because it should be available to all XMOS developers. - -The input values in the code are selected for a custom board -with xcore-ai and SDRAM, but the method should be valid, with adapted -inputs, for other situations as well, including XS1 and XS2. - -How to use ----------- - -To build and run (with XTC 15.3.x):: - -> cd lib_sdram\tools\sdram_timing_calculations\ -> cmake -G "Unix Makefiles" -B build -> xmake -C build -> xsim .\bin\sdram_timing_calculations.xe - -The results per setting are shown as follows (refer to comments in the program):: - - F_core: 600 MHz, clock divider: 6, F_clk: 50.00 MHz - div: 6 read: 1 sample: 1 pad: 2 result: 0 [40558 ..( -574).. 39984 ..( 4600).. 44584] ps - div: 6 read: 1 sample: 1 pad: 1 result: 1 [38892 ..( 1092).. 39984 ..( 2934).. 42918] ps - div: 6 read: 1 sample: 1 pad: 0 result: 1 [37226 ..( 2758).. 39984 ..( 1268).. 41252] ps - div: 6 read: 2 sample: 0 pad: 5 result: 0 [45556 ..( 4424).. 49980 ..( -398).. 49582] ps - ^ ^ ^ ^ ^ - | | | | | - | | | | --- 1 if the read time fits in the read window - | | | -------------- pad_delay (0..5) - | | --------------------- sample_delay 0 or 1 - | ------------------------------- read_delay_clocks (0..2) - ---------------------------------------- clock_divider (4..12) - -The read window timing is shown in picoseconds from falling clock edge:: - - [40558 ..( -574).. 39984 ..( 4600).. 44584] - ^ ^ ^ ^ ^ - | | | | | - read windows start --- | | | | - start margin -------------- | | | - read time ---------------------- | | - end margin --------------------------------- | - read window end ----------------------------------------- - -A negative margin means that there is none. -So, theoretically, such setting cannot reliably work. -In practice, some of the assumptions about hardware -latencies are relatively weak. From 90c16a263b0f3eb092f9c60b7a5394af60f520f9 Mon Sep 17 00:00:00 2001 From: errsu Date: Sun, 23 Nov 2025 01:38:27 +0100 Subject: [PATCH 10/11] harder sdram_timing thread speed conditions - explicitely limit thread speed of sdram_server to FCore/8, e.g. 63 MIPS at 500 MHz - this is tested to be still fast enough for all scenarios in the test, including 100MHz Tclk at 800MHz Tcore - document the respective code --- tools/sdram_timing/src/sdram_timing.xc | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tools/sdram_timing/src/sdram_timing.xc b/tools/sdram_timing/src/sdram_timing.xc index 6f32925..af1fcb9 100644 --- a/tools/sdram_timing/src/sdram_timing.xc +++ b/tools/sdram_timing/src/sdram_timing.xc @@ -98,7 +98,20 @@ int main() par { on tile[SERVER_TILE]: sdram_test_suite(); - on tile[SERVER_TILE]: par(int i=0;i<6;i++) while(1); + on tile[SERVER_TILE]: { + // - keep other threads busy + // - the resulting sdram_server thread speed is + // Fcore/8, same as the Fclk=FCore/(2*clock_divider) + // of the fastest tested clock_divider of 4 + // 500 MHZ -> 63 MIPS/MHz + // 600 MHz -> 75 MIPS/MHz + // 800 MHz -> 100 MIPS/MHz + // - so the processor speed scales with the raising + // SDRAM clock speed per clock_divider + par(int i=0;i<6;i++) { + { set_core_high_priority_on(); while(1); } + } + } } return 0; } From 35375b1a6d037569f7fdd086111b0415bcf7070c Mon Sep 17 00:00:00 2001 From: errsu Date: Sun, 23 Nov 2025 01:42:56 +0100 Subject: [PATCH 11/11] record XS3 test results for Fcore of 800MHz - The calculation doesn't find a solution for SDRAM clock speeds higher than 57.14 MHz. The hardware actually works in a read time window of 5ns width at 100MHz Fclk. This is definitely too small for the variation of production units, but could possibly work with an adaptive firmware that adjusts SDRAM timing at boot time. - As reference, the successfully tested read time window at 33 Mhz Tclk has a width of 17.5 ns. - Interesting enough, the successfully tested read window shifts towards earlier read times with higher Tclk speeds. --- tools/sdram_timing/results.txt | 351 +++++++++++++++++++++++++++++++++ 1 file changed, 351 insertions(+) diff --git a/tools/sdram_timing/results.txt b/tools/sdram_timing/results.txt index 1d37771..f408900 100644 --- a/tools/sdram_timing/results.txt +++ b/tools/sdram_timing/results.txt @@ -712,3 +712,354 @@ div: 12 read: 2 sample: 1 pad: 2 [50.554 ( 69.398) 119.952 (-45.380) 74.572] cal div: 12 read: 2 sample: 1 pad: 1 [48.888 ( 71.064) 119.952 (-47.046) 72.906] calc: 0 test: 0 div: 12 read: 2 sample: 1 pad: 0 [47.222 ( 72.730) 119.952 (-48.712) 71.240] calc: 0 test: 0 SDRAM timing finished + + +Test results for 800MHz for the same hardware +--------------------------------------------- + +Using 64Mb SDRAM +Round trip time min: 7100 ps, max: 19750 ps +starting SDRAM timing + +F_core: 800 MHz, clock divider: 4, F_clk: 100.00 MHz +div: 4 read: 0 sample: 0 pad: 5 [36.400 (-31.400) 5.000 ( 25.850) 30.850] calc: 0 test: 0 +div: 4 read: 0 sample: 0 pad: 4 [35.150 (-30.150) 5.000 ( 24.600) 29.600] calc: 0 test: 0 +div: 4 read: 0 sample: 0 pad: 3 [33.900 (-28.900) 5.000 ( 23.350) 28.350] calc: 0 test: 0 +div: 4 read: 0 sample: 0 pad: 2 [32.650 (-27.650) 5.000 ( 22.100) 27.100] calc: 0 test: 0 +div: 4 read: 0 sample: 0 pad: 1 [31.400 (-26.400) 5.000 ( 20.850) 25.850] calc: 0 test: 0 +div: 4 read: 0 sample: 0 pad: 0 [30.150 (-25.150) 5.000 ( 19.600) 24.600] calc: 0 test: 0 +div: 4 read: 0 sample: 1 pad: 5 [36.400 (-26.400) 10.000 ( 20.850) 30.850] calc: 0 test: 0 +div: 4 read: 0 sample: 1 pad: 4 [35.150 (-25.150) 10.000 ( 19.600) 29.600] calc: 0 test: 0 +div: 4 read: 0 sample: 1 pad: 3 [33.900 (-23.900) 10.000 ( 18.350) 28.350] calc: 0 test: 0 +div: 4 read: 0 sample: 1 pad: 2 [32.650 (-22.650) 10.000 ( 17.100) 27.100] calc: 0 test: 0 +div: 4 read: 0 sample: 1 pad: 1 [31.400 (-21.400) 10.000 ( 15.850) 25.850] calc: 0 test: 0 +div: 4 read: 0 sample: 1 pad: 0 [30.150 (-20.150) 10.000 ( 14.600) 24.600] calc: 0 test: 0 +div: 4 read: 1 sample: 0 pad: 5 [36.400 (-21.400) 15.000 ( 15.850) 30.850] calc: 0 test: 0 +div: 4 read: 1 sample: 0 pad: 4 [35.150 (-20.150) 15.000 ( 14.600) 29.600] calc: 0 test: 0 +div: 4 read: 1 sample: 0 pad: 3 [33.900 (-18.900) 15.000 ( 13.350) 28.350] calc: 0 test: 0 +div: 4 read: 1 sample: 0 pad: 2 [32.650 (-17.650) 15.000 ( 12.100) 27.100] calc: 0 test: 0 +div: 4 read: 1 sample: 0 pad: 1 [31.400 (-16.400) 15.000 ( 10.850) 25.850] calc: 0 test: 0 +div: 4 read: 1 sample: 0 pad: 0 [30.150 (-15.150) 15.000 ( 9.600) 24.600] calc: 0 test: 0 +div: 4 read: 1 sample: 1 pad: 5 [36.400 (-16.400) 20.000 ( 10.850) 30.850] calc: 0 test: 0 +div: 4 read: 1 sample: 1 pad: 4 [35.150 (-15.150) 20.000 ( 9.600) 29.600] calc: 0 test: 0 +div: 4 read: 1 sample: 1 pad: 3 [33.900 (-13.900) 20.000 ( 8.350) 28.350] calc: 0 test: 0 +div: 4 read: 1 sample: 1 pad: 2 [32.650 (-12.650) 20.000 ( 7.100) 27.100] calc: 0 test: 0 +div: 4 read: 1 sample: 1 pad: 1 [31.400 (-11.400) 20.000 ( 5.850) 25.850] calc: 0 test: 0 +div: 4 read: 1 sample: 1 pad: 0 [30.150 (-10.150) 20.000 ( 4.600) 24.600] calc: 0 test: 0 +div: 4 read: 2 sample: 0 pad: 5 [36.400 (-11.400) 25.000 ( 5.850) 30.850] calc: 0 test: 0 +div: 4 read: 2 sample: 0 pad: 4 [35.150 (-10.150) 25.000 ( 4.600) 29.600] calc: 0 test: 0 +div: 4 read: 2 sample: 0 pad: 3 [33.900 ( -8.900) 25.000 ( 3.350) 28.350] calc: 0 test: 1 +div: 4 read: 2 sample: 0 pad: 2 [32.650 ( -7.650) 25.000 ( 2.100) 27.100] calc: 0 test: 1 +div: 4 read: 2 sample: 0 pad: 1 [31.400 ( -6.400) 25.000 ( 0.850) 25.850] calc: 0 test: 1 +div: 4 read: 2 sample: 0 pad: 0 [30.150 ( -5.150) 25.000 ( -0.400) 24.600] calc: 0 test: 1 +div: 4 read: 2 sample: 1 pad: 5 [36.400 ( -6.400) 30.000 ( 0.850) 30.850] calc: 0 test: 1 +div: 4 read: 2 sample: 1 pad: 4 [35.150 ( -5.150) 30.000 ( -0.400) 29.600] calc: 0 test: 1 +div: 4 read: 2 sample: 1 pad: 3 [33.900 ( -3.900) 30.000 ( -1.650) 28.350] calc: 0 test: 1 +div: 4 read: 2 sample: 1 pad: 2 [32.650 ( -2.650) 30.000 ( -2.900) 27.100] calc: 0 test: 0 +div: 4 read: 2 sample: 1 pad: 1 [31.400 ( -1.400) 30.000 ( -4.150) 25.850] calc: 0 test: 0 +div: 4 read: 2 sample: 1 pad: 0 [30.150 ( -0.150) 30.000 ( -5.400) 24.600] calc: 0 test: 0 + +F_core: 800 MHz, clock divider: 5, F_clk: 80.00 MHz +div: 5 read: 0 sample: 0 pad: 5 [37.650 (-31.400) 6.250 ( 28.350) 34.600] calc: 0 test: 0 +div: 5 read: 0 sample: 0 pad: 4 [36.400 (-30.150) 6.250 ( 27.100) 33.350] calc: 0 test: 0 +div: 5 read: 0 sample: 0 pad: 3 [35.150 (-28.900) 6.250 ( 25.850) 32.100] calc: 0 test: 0 +div: 5 read: 0 sample: 0 pad: 2 [33.900 (-27.650) 6.250 ( 24.600) 30.850] calc: 0 test: 0 +div: 5 read: 0 sample: 0 pad: 1 [32.650 (-26.400) 6.250 ( 23.350) 29.600] calc: 0 test: 0 +div: 5 read: 0 sample: 0 pad: 0 [31.400 (-25.150) 6.250 ( 22.100) 28.350] calc: 0 test: 0 +div: 5 read: 0 sample: 1 pad: 5 [37.650 (-25.150) 12.500 ( 22.100) 34.600] calc: 0 test: 0 +div: 5 read: 0 sample: 1 pad: 4 [36.400 (-23.900) 12.500 ( 20.850) 33.350] calc: 0 test: 0 +div: 5 read: 0 sample: 1 pad: 3 [35.150 (-22.650) 12.500 ( 19.600) 32.100] calc: 0 test: 0 +div: 5 read: 0 sample: 1 pad: 2 [33.900 (-21.400) 12.500 ( 18.350) 30.850] calc: 0 test: 0 +div: 5 read: 0 sample: 1 pad: 1 [32.650 (-20.150) 12.500 ( 17.100) 29.600] calc: 0 test: 0 +div: 5 read: 0 sample: 1 pad: 0 [31.400 (-18.900) 12.500 ( 15.850) 28.350] calc: 0 test: 0 +div: 5 read: 1 sample: 0 pad: 5 [37.650 (-18.900) 18.750 ( 15.850) 34.600] calc: 0 test: 0 +div: 5 read: 1 sample: 0 pad: 4 [36.400 (-17.650) 18.750 ( 14.600) 33.350] calc: 0 test: 0 +div: 5 read: 1 sample: 0 pad: 3 [35.150 (-16.400) 18.750 ( 13.350) 32.100] calc: 0 test: 0 +div: 5 read: 1 sample: 0 pad: 2 [33.900 (-15.150) 18.750 ( 12.100) 30.850] calc: 0 test: 0 +div: 5 read: 1 sample: 0 pad: 1 [32.650 (-13.900) 18.750 ( 10.850) 29.600] calc: 0 test: 0 +div: 5 read: 1 sample: 0 pad: 0 [31.400 (-12.650) 18.750 ( 9.600) 28.350] calc: 0 test: 0 +div: 5 read: 1 sample: 1 pad: 5 [37.650 (-12.650) 25.000 ( 9.600) 34.600] calc: 0 test: 0 +div: 5 read: 1 sample: 1 pad: 4 [36.400 (-11.400) 25.000 ( 8.350) 33.350] calc: 0 test: 0 +div: 5 read: 1 sample: 1 pad: 3 [35.150 (-10.150) 25.000 ( 7.100) 32.100] calc: 0 test: 0 +div: 5 read: 1 sample: 1 pad: 2 [33.900 ( -8.900) 25.000 ( 5.850) 30.850] calc: 0 test: 1 +div: 5 read: 1 sample: 1 pad: 1 [32.650 ( -7.650) 25.000 ( 4.600) 29.600] calc: 0 test: 1 +div: 5 read: 1 sample: 1 pad: 0 [31.400 ( -6.400) 25.000 ( 3.350) 28.350] calc: 0 test: 1 +div: 5 read: 2 sample: 0 pad: 5 [37.650 ( -6.400) 31.250 ( 3.350) 34.600] calc: 0 test: 1 +div: 5 read: 2 sample: 0 pad: 4 [36.400 ( -5.150) 31.250 ( 2.100) 33.350] calc: 0 test: 1 +div: 5 read: 2 sample: 0 pad: 3 [35.150 ( -3.900) 31.250 ( 0.850) 32.100] calc: 0 test: 1 +div: 5 read: 2 sample: 0 pad: 2 [33.900 ( -2.650) 31.250 ( -0.400) 30.850] calc: 0 test: 1 +div: 5 read: 2 sample: 0 pad: 1 [32.650 ( -1.400) 31.250 ( -1.650) 29.600] calc: 0 test: 1 +div: 5 read: 2 sample: 0 pad: 0 [31.400 ( -0.150) 31.250 ( -2.900) 28.350] calc: 0 test: 0 +div: 5 read: 2 sample: 1 pad: 5 [37.650 ( -0.150) 37.500 ( -2.900) 34.600] calc: 0 test: 0 +div: 5 read: 2 sample: 1 pad: 4 [36.400 ( 1.100) 37.500 ( -4.150) 33.350] calc: 0 test: 0 +div: 5 read: 2 sample: 1 pad: 3 [35.150 ( 2.350) 37.500 ( -5.400) 32.100] calc: 0 test: 0 +div: 5 read: 2 sample: 1 pad: 2 [33.900 ( 3.600) 37.500 ( -6.650) 30.850] calc: 0 test: 0 +div: 5 read: 2 sample: 1 pad: 1 [32.650 ( 4.850) 37.500 ( -7.900) 29.600] calc: 0 test: 0 +div: 5 read: 2 sample: 1 pad: 0 [31.400 ( 6.100) 37.500 ( -9.150) 28.350] calc: 0 test: 0 + +F_core: 800 MHz, clock divider: 6, F_clk: 66.66 MHz +div: 6 read: 0 sample: 0 pad: 5 [38.900 (-31.400) 7.500 ( 30.850) 38.350] calc: 0 test: 0 +div: 6 read: 0 sample: 0 pad: 4 [37.650 (-30.150) 7.500 ( 29.600) 37.100] calc: 0 test: 0 +div: 6 read: 0 sample: 0 pad: 3 [36.400 (-28.900) 7.500 ( 28.350) 35.850] calc: 0 test: 0 +div: 6 read: 0 sample: 0 pad: 2 [35.150 (-27.650) 7.500 ( 27.100) 34.600] calc: 0 test: 0 +div: 6 read: 0 sample: 0 pad: 1 [33.900 (-26.400) 7.500 ( 25.850) 33.350] calc: 0 test: 0 +div: 6 read: 0 sample: 0 pad: 0 [32.650 (-25.150) 7.500 ( 24.600) 32.100] calc: 0 test: 0 +div: 6 read: 0 sample: 1 pad: 5 [38.900 (-23.900) 15.000 ( 23.350) 38.350] calc: 0 test: 0 +div: 6 read: 0 sample: 1 pad: 4 [37.650 (-22.650) 15.000 ( 22.100) 37.100] calc: 0 test: 0 +div: 6 read: 0 sample: 1 pad: 3 [36.400 (-21.400) 15.000 ( 20.850) 35.850] calc: 0 test: 0 +div: 6 read: 0 sample: 1 pad: 2 [35.150 (-20.150) 15.000 ( 19.600) 34.600] calc: 0 test: 0 +div: 6 read: 0 sample: 1 pad: 1 [33.900 (-18.900) 15.000 ( 18.350) 33.350] calc: 0 test: 0 +div: 6 read: 0 sample: 1 pad: 0 [32.650 (-17.650) 15.000 ( 17.100) 32.100] calc: 0 test: 0 +div: 6 read: 1 sample: 0 pad: 5 [38.900 (-16.400) 22.500 ( 15.850) 38.350] calc: 0 test: 0 +div: 6 read: 1 sample: 0 pad: 4 [37.650 (-15.150) 22.500 ( 14.600) 37.100] calc: 0 test: 0 +div: 6 read: 1 sample: 0 pad: 3 [36.400 (-13.900) 22.500 ( 13.350) 35.850] calc: 0 test: 0 +div: 6 read: 1 sample: 0 pad: 2 [35.150 (-12.650) 22.500 ( 12.100) 34.600] calc: 0 test: 0 +div: 6 read: 1 sample: 0 pad: 1 [33.900 (-11.400) 22.500 ( 10.850) 33.350] calc: 0 test: 0 +div: 6 read: 1 sample: 0 pad: 0 [32.650 (-10.150) 22.500 ( 9.600) 32.100] calc: 0 test: 0 +div: 6 read: 1 sample: 1 pad: 5 [38.900 ( -8.900) 30.000 ( 8.350) 38.350] calc: 0 test: 1 +div: 6 read: 1 sample: 1 pad: 4 [37.650 ( -7.650) 30.000 ( 7.100) 37.100] calc: 0 test: 1 +div: 6 read: 1 sample: 1 pad: 3 [36.400 ( -6.400) 30.000 ( 5.850) 35.850] calc: 0 test: 1 +div: 6 read: 1 sample: 1 pad: 2 [35.150 ( -5.150) 30.000 ( 4.600) 34.600] calc: 0 test: 1 +div: 6 read: 1 sample: 1 pad: 1 [33.900 ( -3.900) 30.000 ( 3.350) 33.350] calc: 0 test: 1 +div: 6 read: 1 sample: 1 pad: 0 [32.650 ( -2.650) 30.000 ( 2.100) 32.100] calc: 0 test: 1 +div: 6 read: 2 sample: 0 pad: 5 [38.900 ( -1.400) 37.500 ( 0.850) 38.350] calc: 0 test: 1 +div: 6 read: 2 sample: 0 pad: 4 [37.650 ( -0.150) 37.500 ( -0.400) 37.100] calc: 0 test: 1 +div: 6 read: 2 sample: 0 pad: 3 [36.400 ( 1.100) 37.500 ( -1.650) 35.850] calc: 0 test: 1 +div: 6 read: 2 sample: 0 pad: 2 [35.150 ( 2.350) 37.500 ( -2.900) 34.600] calc: 0 test: 0 +div: 6 read: 2 sample: 0 pad: 1 [33.900 ( 3.600) 37.500 ( -4.150) 33.350] calc: 0 test: 0 +div: 6 read: 2 sample: 0 pad: 0 [32.650 ( 4.850) 37.500 ( -5.400) 32.100] calc: 0 test: 0 +div: 6 read: 2 sample: 1 pad: 5 [38.900 ( 6.100) 45.000 ( -6.650) 38.350] calc: 0 test: 0 +div: 6 read: 2 sample: 1 pad: 4 [37.650 ( 7.350) 45.000 ( -7.900) 37.100] calc: 0 test: 0 +div: 6 read: 2 sample: 1 pad: 3 [36.400 ( 8.600) 45.000 ( -9.150) 35.850] calc: 0 test: 0 +div: 6 read: 2 sample: 1 pad: 2 [35.150 ( 9.850) 45.000 (-10.400) 34.600] calc: 0 test: 0 +div: 6 read: 2 sample: 1 pad: 1 [33.900 ( 11.100) 45.000 (-11.650) 33.350] calc: 0 test: 0 +div: 6 read: 2 sample: 1 pad: 0 [32.650 ( 12.350) 45.000 (-12.900) 32.100] calc: 0 test: 0 + +F_core: 800 MHz, clock divider: 7, F_clk: 57.14 MHz +div: 7 read: 0 sample: 0 pad: 5 [40.150 (-31.400) 8.750 ( 33.350) 42.100] calc: 0 test: 0 +div: 7 read: 0 sample: 0 pad: 4 [38.900 (-30.150) 8.750 ( 32.100) 40.850] calc: 0 test: 0 +div: 7 read: 0 sample: 0 pad: 3 [37.650 (-28.900) 8.750 ( 30.850) 39.600] calc: 0 test: 0 +div: 7 read: 0 sample: 0 pad: 2 [36.400 (-27.650) 8.750 ( 29.600) 38.350] calc: 0 test: 0 +div: 7 read: 0 sample: 0 pad: 1 [35.150 (-26.400) 8.750 ( 28.350) 37.100] calc: 0 test: 0 +div: 7 read: 0 sample: 0 pad: 0 [33.900 (-25.150) 8.750 ( 27.100) 35.850] calc: 0 test: 0 +div: 7 read: 0 sample: 1 pad: 5 [40.150 (-22.650) 17.500 ( 24.600) 42.100] calc: 0 test: 0 +div: 7 read: 0 sample: 1 pad: 4 [38.900 (-21.400) 17.500 ( 23.350) 40.850] calc: 0 test: 0 +div: 7 read: 0 sample: 1 pad: 3 [37.650 (-20.150) 17.500 ( 22.100) 39.600] calc: 0 test: 0 +div: 7 read: 0 sample: 1 pad: 2 [36.400 (-18.900) 17.500 ( 20.850) 38.350] calc: 0 test: 0 +div: 7 read: 0 sample: 1 pad: 1 [35.150 (-17.650) 17.500 ( 19.600) 37.100] calc: 0 test: 0 +div: 7 read: 0 sample: 1 pad: 0 [33.900 (-16.400) 17.500 ( 18.350) 35.850] calc: 0 test: 0 +div: 7 read: 1 sample: 0 pad: 5 [40.150 (-13.900) 26.250 ( 15.850) 42.100] calc: 0 test: 0 +div: 7 read: 1 sample: 0 pad: 4 [38.900 (-12.650) 26.250 ( 14.600) 40.850] calc: 0 test: 0 +div: 7 read: 1 sample: 0 pad: 3 [37.650 (-11.400) 26.250 ( 13.350) 39.600] calc: 0 test: 0 +div: 7 read: 1 sample: 0 pad: 2 [36.400 (-10.150) 26.250 ( 12.100) 38.350] calc: 0 test: 0 +div: 7 read: 1 sample: 0 pad: 1 [35.150 ( -8.900) 26.250 ( 10.850) 37.100] calc: 0 test: 1 +div: 7 read: 1 sample: 0 pad: 0 [33.900 ( -7.650) 26.250 ( 9.600) 35.850] calc: 0 test: 1 +div: 7 read: 1 sample: 1 pad: 5 [40.150 ( -5.150) 35.000 ( 7.100) 42.100] calc: 0 test: 1 +div: 7 read: 1 sample: 1 pad: 4 [38.900 ( -3.900) 35.000 ( 5.850) 40.850] calc: 0 test: 1 +div: 7 read: 1 sample: 1 pad: 3 [37.650 ( -2.650) 35.000 ( 4.600) 39.600] calc: 0 test: 1 +div: 7 read: 1 sample: 1 pad: 2 [36.400 ( -1.400) 35.000 ( 3.350) 38.350] calc: 0 test: 1 +div: 7 read: 1 sample: 1 pad: 1 [35.150 ( -0.150) 35.000 ( 2.100) 37.100] calc: 0 test: 1 +div: 7 read: 1 sample: 1 pad: 0 [33.900 ( 1.100) 35.000 ( 0.850) 35.850] calc: 1 test: 1 +div: 7 read: 2 sample: 0 pad: 5 [40.150 ( 3.600) 43.750 ( -1.650) 42.100] calc: 0 test: 1 +div: 7 read: 2 sample: 0 pad: 4 [38.900 ( 4.850) 43.750 ( -2.900) 40.850] calc: 0 test: 0 +div: 7 read: 2 sample: 0 pad: 3 [37.650 ( 6.100) 43.750 ( -4.150) 39.600] calc: 0 test: 0 +div: 7 read: 2 sample: 0 pad: 2 [36.400 ( 7.350) 43.750 ( -5.400) 38.350] calc: 0 test: 0 +div: 7 read: 2 sample: 0 pad: 1 [35.150 ( 8.600) 43.750 ( -6.650) 37.100] calc: 0 test: 0 +div: 7 read: 2 sample: 0 pad: 0 [33.900 ( 9.850) 43.750 ( -7.900) 35.850] calc: 0 test: 0 +div: 7 read: 2 sample: 1 pad: 5 [40.150 ( 12.350) 52.500 (-10.400) 42.100] calc: 0 test: 0 +div: 7 read: 2 sample: 1 pad: 4 [38.900 ( 13.600) 52.500 (-11.650) 40.850] calc: 0 test: 0 +div: 7 read: 2 sample: 1 pad: 3 [37.650 ( 14.850) 52.500 (-12.900) 39.600] calc: 0 test: 0 +div: 7 read: 2 sample: 1 pad: 2 [36.400 ( 16.100) 52.500 (-14.150) 38.350] calc: 0 test: 0 +div: 7 read: 2 sample: 1 pad: 1 [35.150 ( 17.350) 52.500 (-15.400) 37.100] calc: 0 test: 0 +div: 7 read: 2 sample: 1 pad: 0 [33.900 ( 18.600) 52.500 (-16.650) 35.850] calc: 0 test: 0 + +F_core: 800 MHz, clock divider: 8, F_clk: 50.00 MHz +div: 8 read: 0 sample: 0 pad: 5 [41.400 (-31.400) 10.000 ( 35.850) 45.850] calc: 0 test: 0 +div: 8 read: 0 sample: 0 pad: 4 [40.150 (-30.150) 10.000 ( 34.600) 44.600] calc: 0 test: 0 +div: 8 read: 0 sample: 0 pad: 3 [38.900 (-28.900) 10.000 ( 33.350) 43.350] calc: 0 test: 0 +div: 8 read: 0 sample: 0 pad: 2 [37.650 (-27.650) 10.000 ( 32.100) 42.100] calc: 0 test: 0 +div: 8 read: 0 sample: 0 pad: 1 [36.400 (-26.400) 10.000 ( 30.850) 40.850] calc: 0 test: 0 +div: 8 read: 0 sample: 0 pad: 0 [35.150 (-25.150) 10.000 ( 29.600) 39.600] calc: 0 test: 0 +div: 8 read: 0 sample: 1 pad: 5 [41.400 (-21.400) 20.000 ( 25.850) 45.850] calc: 0 test: 0 +div: 8 read: 0 sample: 1 pad: 4 [40.150 (-20.150) 20.000 ( 24.600) 44.600] calc: 0 test: 0 +div: 8 read: 0 sample: 1 pad: 3 [38.900 (-18.900) 20.000 ( 23.350) 43.350] calc: 0 test: 0 +div: 8 read: 0 sample: 1 pad: 2 [37.650 (-17.650) 20.000 ( 22.100) 42.100] calc: 0 test: 0 +div: 8 read: 0 sample: 1 pad: 1 [36.400 (-16.400) 20.000 ( 20.850) 40.850] calc: 0 test: 0 +div: 8 read: 0 sample: 1 pad: 0 [35.150 (-15.150) 20.000 ( 19.600) 39.600] calc: 0 test: 0 +div: 8 read: 1 sample: 0 pad: 5 [41.400 (-11.400) 30.000 ( 15.850) 45.850] calc: 0 test: 0 +div: 8 read: 1 sample: 0 pad: 4 [40.150 (-10.150) 30.000 ( 14.600) 44.600] calc: 0 test: 0 +div: 8 read: 1 sample: 0 pad: 3 [38.900 ( -8.900) 30.000 ( 13.350) 43.350] calc: 0 test: 1 +div: 8 read: 1 sample: 0 pad: 2 [37.650 ( -7.650) 30.000 ( 12.100) 42.100] calc: 0 test: 1 +div: 8 read: 1 sample: 0 pad: 1 [36.400 ( -6.400) 30.000 ( 10.850) 40.850] calc: 0 test: 1 +div: 8 read: 1 sample: 0 pad: 0 [35.150 ( -5.150) 30.000 ( 9.600) 39.600] calc: 0 test: 1 +div: 8 read: 1 sample: 1 pad: 5 [41.400 ( -1.400) 40.000 ( 5.850) 45.850] calc: 0 test: 1 +div: 8 read: 1 sample: 1 pad: 4 [40.150 ( -0.150) 40.000 ( 4.600) 44.600] calc: 0 test: 1 +div: 8 read: 1 sample: 1 pad: 3 [38.900 ( 1.100) 40.000 ( 3.350) 43.350] calc: 1 test: 1 +div: 8 read: 1 sample: 1 pad: 2 [37.650 ( 2.350) 40.000 ( 2.100) 42.100] calc: 1 test: 1 +div: 8 read: 1 sample: 1 pad: 1 [36.400 ( 3.600) 40.000 ( 0.850) 40.850] calc: 1 test: 1 +div: 8 read: 1 sample: 1 pad: 0 [35.150 ( 4.850) 40.000 ( -0.400) 39.600] calc: 0 test: 1 +div: 8 read: 2 sample: 0 pad: 5 [41.400 ( 8.600) 50.000 ( -4.150) 45.850] calc: 0 test: 0 +div: 8 read: 2 sample: 0 pad: 4 [40.150 ( 9.850) 50.000 ( -5.400) 44.600] calc: 0 test: 0 +div: 8 read: 2 sample: 0 pad: 3 [38.900 ( 11.100) 50.000 ( -6.650) 43.350] calc: 0 test: 0 +div: 8 read: 2 sample: 0 pad: 2 [37.650 ( 12.350) 50.000 ( -7.900) 42.100] calc: 0 test: 0 +div: 8 read: 2 sample: 0 pad: 1 [36.400 ( 13.600) 50.000 ( -9.150) 40.850] calc: 0 test: 0 +div: 8 read: 2 sample: 0 pad: 0 [35.150 ( 14.850) 50.000 (-10.400) 39.600] calc: 0 test: 0 +div: 8 read: 2 sample: 1 pad: 5 [41.400 ( 18.600) 60.000 (-14.150) 45.850] calc: 0 test: 0 +div: 8 read: 2 sample: 1 pad: 4 [40.150 ( 19.850) 60.000 (-15.400) 44.600] calc: 0 test: 0 +div: 8 read: 2 sample: 1 pad: 3 [38.900 ( 21.100) 60.000 (-16.650) 43.350] calc: 0 test: 0 +div: 8 read: 2 sample: 1 pad: 2 [37.650 ( 22.350) 60.000 (-17.900) 42.100] calc: 0 test: 0 +div: 8 read: 2 sample: 1 pad: 1 [36.400 ( 23.600) 60.000 (-19.150) 40.850] calc: 0 test: 0 +div: 8 read: 2 sample: 1 pad: 0 [35.150 ( 24.850) 60.000 (-20.400) 39.600] calc: 0 test: 0 + +F_core: 800 MHz, clock divider: 9, F_clk: 44.44 MHz +div: 9 read: 0 sample: 0 pad: 5 [42.650 (-31.400) 11.250 ( 38.350) 49.600] calc: 0 test: 0 +div: 9 read: 0 sample: 0 pad: 4 [41.400 (-30.150) 11.250 ( 37.100) 48.350] calc: 0 test: 0 +div: 9 read: 0 sample: 0 pad: 3 [40.150 (-28.900) 11.250 ( 35.850) 47.100] calc: 0 test: 0 +div: 9 read: 0 sample: 0 pad: 2 [38.900 (-27.650) 11.250 ( 34.600) 45.850] calc: 0 test: 0 +div: 9 read: 0 sample: 0 pad: 1 [37.650 (-26.400) 11.250 ( 33.350) 44.600] calc: 0 test: 0 +div: 9 read: 0 sample: 0 pad: 0 [36.400 (-25.150) 11.250 ( 32.100) 43.350] calc: 0 test: 0 +div: 9 read: 0 sample: 1 pad: 5 [42.650 (-20.150) 22.500 ( 27.100) 49.600] calc: 0 test: 0 +div: 9 read: 0 sample: 1 pad: 4 [41.400 (-18.900) 22.500 ( 25.850) 48.350] calc: 0 test: 0 +div: 9 read: 0 sample: 1 pad: 3 [40.150 (-17.650) 22.500 ( 24.600) 47.100] calc: 0 test: 0 +div: 9 read: 0 sample: 1 pad: 2 [38.900 (-16.400) 22.500 ( 23.350) 45.850] calc: 0 test: 0 +div: 9 read: 0 sample: 1 pad: 1 [37.650 (-15.150) 22.500 ( 22.100) 44.600] calc: 0 test: 0 +div: 9 read: 0 sample: 1 pad: 0 [36.400 (-13.900) 22.500 ( 20.850) 43.350] calc: 0 test: 0 +div: 9 read: 1 sample: 0 pad: 5 [42.650 ( -8.900) 33.750 ( 15.850) 49.600] calc: 0 test: 1 +div: 9 read: 1 sample: 0 pad: 4 [41.400 ( -7.650) 33.750 ( 14.600) 48.350] calc: 0 test: 1 +div: 9 read: 1 sample: 0 pad: 3 [40.150 ( -6.400) 33.750 ( 13.350) 47.100] calc: 0 test: 1 +div: 9 read: 1 sample: 0 pad: 2 [38.900 ( -5.150) 33.750 ( 12.100) 45.850] calc: 0 test: 1 +div: 9 read: 1 sample: 0 pad: 1 [37.650 ( -3.900) 33.750 ( 10.850) 44.600] calc: 0 test: 1 +div: 9 read: 1 sample: 0 pad: 0 [36.400 ( -2.650) 33.750 ( 9.600) 43.350] calc: 0 test: 1 +div: 9 read: 1 sample: 1 pad: 5 [42.650 ( 2.350) 45.000 ( 4.600) 49.600] calc: 1 test: 1 +div: 9 read: 1 sample: 1 pad: 4 [41.400 ( 3.600) 45.000 ( 3.350) 48.350] calc: 1 test: 1 +div: 9 read: 1 sample: 1 pad: 3 [40.150 ( 4.850) 45.000 ( 2.100) 47.100] calc: 1 test: 1 +div: 9 read: 1 sample: 1 pad: 2 [38.900 ( 6.100) 45.000 ( 0.850) 45.850] calc: 1 test: 1 +div: 9 read: 1 sample: 1 pad: 1 [37.650 ( 7.350) 45.000 ( -0.400) 44.600] calc: 0 test: 1 +div: 9 read: 1 sample: 1 pad: 0 [36.400 ( 8.600) 45.000 ( -1.650) 43.350] calc: 0 test: 1 +div: 9 read: 2 sample: 0 pad: 5 [42.650 ( 13.600) 56.250 ( -6.650) 49.600] calc: 0 test: 0 +div: 9 read: 2 sample: 0 pad: 4 [41.400 ( 14.850) 56.250 ( -7.900) 48.350] calc: 0 test: 0 +div: 9 read: 2 sample: 0 pad: 3 [40.150 ( 16.100) 56.250 ( -9.150) 47.100] calc: 0 test: 0 +div: 9 read: 2 sample: 0 pad: 2 [38.900 ( 17.350) 56.250 (-10.400) 45.850] calc: 0 test: 0 +div: 9 read: 2 sample: 0 pad: 1 [37.650 ( 18.600) 56.250 (-11.650) 44.600] calc: 0 test: 0 +div: 9 read: 2 sample: 0 pad: 0 [36.400 ( 19.850) 56.250 (-12.900) 43.350] calc: 0 test: 0 +div: 9 read: 2 sample: 1 pad: 5 [42.650 ( 24.850) 67.500 (-17.900) 49.600] calc: 0 test: 0 +div: 9 read: 2 sample: 1 pad: 4 [41.400 ( 26.100) 67.500 (-19.150) 48.350] calc: 0 test: 0 +div: 9 read: 2 sample: 1 pad: 3 [40.150 ( 27.350) 67.500 (-20.400) 47.100] calc: 0 test: 0 +div: 9 read: 2 sample: 1 pad: 2 [38.900 ( 28.600) 67.500 (-21.650) 45.850] calc: 0 test: 0 +div: 9 read: 2 sample: 1 pad: 1 [37.650 ( 29.850) 67.500 (-22.900) 44.600] calc: 0 test: 0 +div: 9 read: 2 sample: 1 pad: 0 [36.400 ( 31.100) 67.500 (-24.150) 43.350] calc: 0 test: 0 + +F_core: 800 MHz, clock divider: 10, F_clk: 40.00 MHz +div: 10 read: 0 sample: 0 pad: 5 [43.900 (-31.400) 12.500 ( 40.850) 53.350] calc: 0 test: 0 +div: 10 read: 0 sample: 0 pad: 4 [42.650 (-30.150) 12.500 ( 39.600) 52.100] calc: 0 test: 0 +div: 10 read: 0 sample: 0 pad: 3 [41.400 (-28.900) 12.500 ( 38.350) 50.850] calc: 0 test: 0 +div: 10 read: 0 sample: 0 pad: 2 [40.150 (-27.650) 12.500 ( 37.100) 49.600] calc: 0 test: 0 +div: 10 read: 0 sample: 0 pad: 1 [38.900 (-26.400) 12.500 ( 35.850) 48.350] calc: 0 test: 0 +div: 10 read: 0 sample: 0 pad: 0 [37.650 (-25.150) 12.500 ( 34.600) 47.100] calc: 0 test: 0 +div: 10 read: 0 sample: 1 pad: 5 [43.900 (-18.900) 25.000 ( 28.350) 53.350] calc: 0 test: 0 +div: 10 read: 0 sample: 1 pad: 4 [42.650 (-17.650) 25.000 ( 27.100) 52.100] calc: 0 test: 0 +div: 10 read: 0 sample: 1 pad: 3 [41.400 (-16.400) 25.000 ( 25.850) 50.850] calc: 0 test: 0 +div: 10 read: 0 sample: 1 pad: 2 [40.150 (-15.150) 25.000 ( 24.600) 49.600] calc: 0 test: 0 +div: 10 read: 0 sample: 1 pad: 1 [38.900 (-13.900) 25.000 ( 23.350) 48.350] calc: 0 test: 0 +div: 10 read: 0 sample: 1 pad: 0 [37.650 (-12.650) 25.000 ( 22.100) 47.100] calc: 0 test: 0 +div: 10 read: 1 sample: 0 pad: 5 [43.900 ( -6.400) 37.500 ( 15.850) 53.350] calc: 0 test: 1 +div: 10 read: 1 sample: 0 pad: 4 [42.650 ( -5.150) 37.500 ( 14.600) 52.100] calc: 0 test: 1 +div: 10 read: 1 sample: 0 pad: 3 [41.400 ( -3.900) 37.500 ( 13.350) 50.850] calc: 0 test: 1 +div: 10 read: 1 sample: 0 pad: 2 [40.150 ( -2.650) 37.500 ( 12.100) 49.600] calc: 0 test: 1 +div: 10 read: 1 sample: 0 pad: 1 [38.900 ( -1.400) 37.500 ( 10.850) 48.350] calc: 0 test: 1 +div: 10 read: 1 sample: 0 pad: 0 [37.650 ( -0.150) 37.500 ( 9.600) 47.100] calc: 0 test: 1 +div: 10 read: 1 sample: 1 pad: 5 [43.900 ( 6.100) 50.000 ( 3.350) 53.350] calc: 1 test: 1 +div: 10 read: 1 sample: 1 pad: 4 [42.650 ( 7.350) 50.000 ( 2.100) 52.100] calc: 1 test: 1 +div: 10 read: 1 sample: 1 pad: 3 [41.400 ( 8.600) 50.000 ( 0.850) 50.850] calc: 1 test: 1 +div: 10 read: 1 sample: 1 pad: 2 [40.150 ( 9.850) 50.000 ( -0.400) 49.600] calc: 0 test: 1 +div: 10 read: 1 sample: 1 pad: 1 [38.900 ( 11.100) 50.000 ( -1.650) 48.350] calc: 0 test: 1 +div: 10 read: 1 sample: 1 pad: 0 [37.650 ( 12.350) 50.000 ( -2.900) 47.100] calc: 0 test: 0 +div: 10 read: 2 sample: 0 pad: 5 [43.900 ( 18.600) 62.500 ( -9.150) 53.350] calc: 0 test: 0 +div: 10 read: 2 sample: 0 pad: 4 [42.650 ( 19.850) 62.500 (-10.400) 52.100] calc: 0 test: 0 +div: 10 read: 2 sample: 0 pad: 3 [41.400 ( 21.100) 62.500 (-11.650) 50.850] calc: 0 test: 0 +div: 10 read: 2 sample: 0 pad: 2 [40.150 ( 22.350) 62.500 (-12.900) 49.600] calc: 0 test: 0 +div: 10 read: 2 sample: 0 pad: 1 [38.900 ( 23.600) 62.500 (-14.150) 48.350] calc: 0 test: 0 +div: 10 read: 2 sample: 0 pad: 0 [37.650 ( 24.850) 62.500 (-15.400) 47.100] calc: 0 test: 0 +div: 10 read: 2 sample: 1 pad: 5 [43.900 ( 31.100) 75.000 (-21.650) 53.350] calc: 0 test: 0 +div: 10 read: 2 sample: 1 pad: 4 [42.650 ( 32.350) 75.000 (-22.900) 52.100] calc: 0 test: 0 +div: 10 read: 2 sample: 1 pad: 3 [41.400 ( 33.600) 75.000 (-24.150) 50.850] calc: 0 test: 0 +div: 10 read: 2 sample: 1 pad: 2 [40.150 ( 34.850) 75.000 (-25.400) 49.600] calc: 0 test: 0 +div: 10 read: 2 sample: 1 pad: 1 [38.900 ( 36.100) 75.000 (-26.650) 48.350] calc: 0 test: 0 +div: 10 read: 2 sample: 1 pad: 0 [37.650 ( 37.350) 75.000 (-27.900) 47.100] calc: 0 test: 0 + +F_core: 800 MHz, clock divider: 11, F_clk: 36.36 MHz +div: 11 read: 0 sample: 0 pad: 5 [45.150 (-31.400) 13.750 ( 43.350) 57.100] calc: 0 test: 0 +div: 11 read: 0 sample: 0 pad: 4 [43.900 (-30.150) 13.750 ( 42.100) 55.850] calc: 0 test: 0 +div: 11 read: 0 sample: 0 pad: 3 [42.650 (-28.900) 13.750 ( 40.850) 54.600] calc: 0 test: 0 +div: 11 read: 0 sample: 0 pad: 2 [41.400 (-27.650) 13.750 ( 39.600) 53.350] calc: 0 test: 0 +div: 11 read: 0 sample: 0 pad: 1 [40.150 (-26.400) 13.750 ( 38.350) 52.100] calc: 0 test: 0 +div: 11 read: 0 sample: 0 pad: 0 [38.900 (-25.150) 13.750 ( 37.100) 50.850] calc: 0 test: 0 +div: 11 read: 0 sample: 1 pad: 5 [45.150 (-17.650) 27.500 ( 29.600) 57.100] calc: 0 test: 0 +div: 11 read: 0 sample: 1 pad: 4 [43.900 (-16.400) 27.500 ( 28.350) 55.850] calc: 0 test: 0 +div: 11 read: 0 sample: 1 pad: 3 [42.650 (-15.150) 27.500 ( 27.100) 54.600] calc: 0 test: 0 +div: 11 read: 0 sample: 1 pad: 2 [41.400 (-13.900) 27.500 ( 25.850) 53.350] calc: 0 test: 0 +div: 11 read: 0 sample: 1 pad: 1 [40.150 (-12.650) 27.500 ( 24.600) 52.100] calc: 0 test: 0 +div: 11 read: 0 sample: 1 pad: 0 [38.900 (-11.400) 27.500 ( 23.350) 50.850] calc: 0 test: 0 +div: 11 read: 1 sample: 0 pad: 5 [45.150 ( -3.900) 41.250 ( 15.850) 57.100] calc: 0 test: 1 +div: 11 read: 1 sample: 0 pad: 4 [43.900 ( -2.650) 41.250 ( 14.600) 55.850] calc: 0 test: 1 +div: 11 read: 1 sample: 0 pad: 3 [42.650 ( -1.400) 41.250 ( 13.350) 54.600] calc: 0 test: 1 +div: 11 read: 1 sample: 0 pad: 2 [41.400 ( -0.150) 41.250 ( 12.100) 53.350] calc: 0 test: 1 +div: 11 read: 1 sample: 0 pad: 1 [40.150 ( 1.100) 41.250 ( 10.850) 52.100] calc: 1 test: 1 +div: 11 read: 1 sample: 0 pad: 0 [38.900 ( 2.350) 41.250 ( 9.600) 50.850] calc: 1 test: 1 +div: 11 read: 1 sample: 1 pad: 5 [45.150 ( 9.850) 55.000 ( 2.100) 57.100] calc: 1 test: 1 +div: 11 read: 1 sample: 1 pad: 4 [43.900 ( 11.100) 55.000 ( 0.850) 55.850] calc: 1 test: 1 +div: 11 read: 1 sample: 1 pad: 3 [42.650 ( 12.350) 55.000 ( -0.400) 54.600] calc: 0 test: 1 +div: 11 read: 1 sample: 1 pad: 2 [41.400 ( 13.600) 55.000 ( -1.650) 53.350] calc: 0 test: 1 +div: 11 read: 1 sample: 1 pad: 1 [40.150 ( 14.850) 55.000 ( -2.900) 52.100] calc: 0 test: 0 +div: 11 read: 1 sample: 1 pad: 0 [38.900 ( 16.100) 55.000 ( -4.150) 50.850] calc: 0 test: 0 +div: 11 read: 2 sample: 0 pad: 5 [45.150 ( 23.600) 68.750 (-11.650) 57.100] calc: 0 test: 0 +div: 11 read: 2 sample: 0 pad: 4 [43.900 ( 24.850) 68.750 (-12.900) 55.850] calc: 0 test: 0 +div: 11 read: 2 sample: 0 pad: 3 [42.650 ( 26.100) 68.750 (-14.150) 54.600] calc: 0 test: 0 +div: 11 read: 2 sample: 0 pad: 2 [41.400 ( 27.350) 68.750 (-15.400) 53.350] calc: 0 test: 0 +div: 11 read: 2 sample: 0 pad: 1 [40.150 ( 28.600) 68.750 (-16.650) 52.100] calc: 0 test: 0 +div: 11 read: 2 sample: 0 pad: 0 [38.900 ( 29.850) 68.750 (-17.900) 50.850] calc: 0 test: 0 +div: 11 read: 2 sample: 1 pad: 5 [45.150 ( 37.350) 82.500 (-25.400) 57.100] calc: 0 test: 0 +div: 11 read: 2 sample: 1 pad: 4 [43.900 ( 38.600) 82.500 (-26.650) 55.850] calc: 0 test: 0 +div: 11 read: 2 sample: 1 pad: 3 [42.650 ( 39.850) 82.500 (-27.900) 54.600] calc: 0 test: 0 +div: 11 read: 2 sample: 1 pad: 2 [41.400 ( 41.100) 82.500 (-29.150) 53.350] calc: 0 test: 0 +div: 11 read: 2 sample: 1 pad: 1 [40.150 ( 42.350) 82.500 (-30.400) 52.100] calc: 0 test: 0 +div: 11 read: 2 sample: 1 pad: 0 [38.900 ( 43.600) 82.500 (-31.650) 50.850] calc: 0 test: 0 + +F_core: 800 MHz, clock divider: 12, F_clk: 33.33 MHz +div: 12 read: 0 sample: 0 pad: 5 [46.400 (-31.400) 15.000 ( 45.850) 60.850] calc: 0 test: 0 +div: 12 read: 0 sample: 0 pad: 4 [45.150 (-30.150) 15.000 ( 44.600) 59.600] calc: 0 test: 0 +div: 12 read: 0 sample: 0 pad: 3 [43.900 (-28.900) 15.000 ( 43.350) 58.350] calc: 0 test: 0 +div: 12 read: 0 sample: 0 pad: 2 [42.650 (-27.650) 15.000 ( 42.100) 57.100] calc: 0 test: 0 +div: 12 read: 0 sample: 0 pad: 1 [41.400 (-26.400) 15.000 ( 40.850) 55.850] calc: 0 test: 0 +div: 12 read: 0 sample: 0 pad: 0 [40.150 (-25.150) 15.000 ( 39.600) 54.600] calc: 0 test: 0 +div: 12 read: 0 sample: 1 pad: 5 [46.400 (-16.400) 30.000 ( 30.850) 60.850] calc: 0 test: 0 +div: 12 read: 0 sample: 1 pad: 4 [45.150 (-15.150) 30.000 ( 29.600) 59.600] calc: 0 test: 0 +div: 12 read: 0 sample: 1 pad: 3 [43.900 (-13.900) 30.000 ( 28.350) 58.350] calc: 0 test: 0 +div: 12 read: 0 sample: 1 pad: 2 [42.650 (-12.650) 30.000 ( 27.100) 57.100] calc: 0 test: 0 +div: 12 read: 0 sample: 1 pad: 1 [41.400 (-11.400) 30.000 ( 25.850) 55.850] calc: 0 test: 0 +div: 12 read: 0 sample: 1 pad: 0 [40.150 (-10.150) 30.000 ( 24.600) 54.600] calc: 0 test: 0 +div: 12 read: 1 sample: 0 pad: 5 [46.400 ( -1.400) 45.000 ( 15.850) 60.850] calc: 0 test: 1 +div: 12 read: 1 sample: 0 pad: 4 [45.150 ( -0.150) 45.000 ( 14.600) 59.600] calc: 0 test: 1 +div: 12 read: 1 sample: 0 pad: 3 [43.900 ( 1.100) 45.000 ( 13.350) 58.350] calc: 1 test: 1 +div: 12 read: 1 sample: 0 pad: 2 [42.650 ( 2.350) 45.000 ( 12.100) 57.100] calc: 1 test: 1 +div: 12 read: 1 sample: 0 pad: 1 [41.400 ( 3.600) 45.000 ( 10.850) 55.850] calc: 1 test: 1 +div: 12 read: 1 sample: 0 pad: 0 [40.150 ( 4.850) 45.000 ( 9.600) 54.600] calc: 1 test: 1 +div: 12 read: 1 sample: 1 pad: 5 [46.400 ( 13.600) 60.000 ( 0.850) 60.850] calc: 1 test: 1 +div: 12 read: 1 sample: 1 pad: 4 [45.150 ( 14.850) 60.000 ( -0.400) 59.600] calc: 0 test: 1 +div: 12 read: 1 sample: 1 pad: 3 [43.900 ( 16.100) 60.000 ( -1.650) 58.350] calc: 0 test: 1 +div: 12 read: 1 sample: 1 pad: 2 [42.650 ( 17.350) 60.000 ( -2.900) 57.100] calc: 0 test: 0 +div: 12 read: 1 sample: 1 pad: 1 [41.400 ( 18.600) 60.000 ( -4.150) 55.850] calc: 0 test: 0 +div: 12 read: 1 sample: 1 pad: 0 [40.150 ( 19.850) 60.000 ( -5.400) 54.600] calc: 0 test: 0 +div: 12 read: 2 sample: 0 pad: 5 [46.400 ( 28.600) 75.000 (-14.150) 60.850] calc: 0 test: 0 +div: 12 read: 2 sample: 0 pad: 4 [45.150 ( 29.850) 75.000 (-15.400) 59.600] calc: 0 test: 0 +div: 12 read: 2 sample: 0 pad: 3 [43.900 ( 31.100) 75.000 (-16.650) 58.350] calc: 0 test: 0 +div: 12 read: 2 sample: 0 pad: 2 [42.650 ( 32.350) 75.000 (-17.900) 57.100] calc: 0 test: 0 +div: 12 read: 2 sample: 0 pad: 1 [41.400 ( 33.600) 75.000 (-19.150) 55.850] calc: 0 test: 0 +div: 12 read: 2 sample: 0 pad: 0 [40.150 ( 34.850) 75.000 (-20.400) 54.600] calc: 0 test: 0 +div: 12 read: 2 sample: 1 pad: 5 [46.400 ( 43.600) 90.000 (-29.150) 60.850] calc: 0 test: 0 +div: 12 read: 2 sample: 1 pad: 4 [45.150 ( 44.850) 90.000 (-30.400) 59.600] calc: 0 test: 0 +div: 12 read: 2 sample: 1 pad: 3 [43.900 ( 46.100) 90.000 (-31.650) 58.350] calc: 0 test: 0 +div: 12 read: 2 sample: 1 pad: 2 [42.650 ( 47.350) 90.000 (-32.900) 57.100] calc: 0 test: 0 +div: 12 read: 2 sample: 1 pad: 1 [41.400 ( 48.600) 90.000 (-34.150) 55.850] calc: 0 test: 0 +div: 12 read: 2 sample: 1 pad: 0 [40.150 ( 49.850) 90.000 (-35.400) 54.600] calc: 0 test: 0 +SDRAM timing finished