From a7a520695ec23b4ce4cb298f2d24148904f9cf98 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Wed, 9 Nov 2022 17:47:58 +0800 Subject: [PATCH 1/3] software/liblitedram: seek for consecutive delay range when centering On some boards, the working delay range found may be not so consecutive. Considering this to be some inference, we should only count the biggest consecutive delay range instead of just skip ahead for a fixed offset. Signed-off-by: Icenowy Zheng --- litex/soc/software/liblitedram/sdram.c | 31 ++++++++++++-------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/litex/soc/software/liblitedram/sdram.c b/litex/soc/software/liblitedram/sdram.c index 48bb2bf48..47f20944d 100644 --- a/litex/soc/software/liblitedram/sdram.c +++ b/litex/soc/software/liblitedram/sdram.c @@ -378,7 +378,7 @@ static void sdram_leveling_center_module( int working; unsigned int errors; int delay, delay_mid, delay_range; - int delay_min = -1, delay_max = -1; + int delay_min = -1, delay_max = -1, cur_delay_min = -1; if (show_long) printf("m%d: |", module); @@ -406,20 +406,9 @@ static void sdram_leveling_center_module( inc_delay(module); } - /* Get a bit further into the working zone */ -#if SDRAM_PHY_DELAYS > 32 - #define SDRAM_PHY_DELAY_JUMP 16 -#elif SDRAM_PHY_DELAYS > 8 - #define SDRAM_PHY_DELAY_JUMP 4 -#else - #define SDRAM_PHY_DELAY_JUMP 1 -#endif - for(i=0;i best_delay_length) { + delay_min = cur_delay_min; + delay_max = delay; + } + } else { + cur_delay_min = delay + 1; } delay++; if(delay >= SDRAM_PHY_DELAYS) From 8a74eba4d5ee0184eee0c68b9396f31088e05b24 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Wed, 9 Nov 2022 17:52:38 +0800 Subject: [PATCH 2/3] software/liblitedram: scale up values when finding CMD delay The delay finding code is based on integers, and when divided by the count, rounding error will be quite easy to happen. Scale up all delay value by 256x to reduce rounding error. Signed-off-by: Icenowy Zheng --- litex/soc/software/liblitedram/sdram.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/litex/soc/software/liblitedram/sdram.c b/litex/soc/software/liblitedram/sdram.c index 47f20944d..e824d01a8 100644 --- a/litex/soc/software/liblitedram/sdram.c +++ b/litex/soc/software/liblitedram/sdram.c @@ -773,7 +773,7 @@ static void sdram_write_leveling_find_cmd_delay(unsigned int *best_error, unsign int delay_count = 0; for (int i=0; i < SDRAM_PHY_MODULES; ++i) { if (delays[i] != -1) { - delay_mean += delays[i] + _sdram_tck_taps/4; + delay_mean += delays[i]*256 + _sdram_tck_taps*64; delay_count += 1; } } @@ -781,7 +781,7 @@ static void sdram_write_leveling_find_cmd_delay(unsigned int *best_error, unsign delay_mean /= delay_count; /* We want the higher number of valid modules and delay to be centered */ - int ideal_delay = (SDRAM_PHY_DELAYS - _sdram_tck_taps/4)/2; + int ideal_delay = SDRAM_PHY_DELAYS*128 - _sdram_tck_taps*32; int error = ideal_delay - delay_mean; if (error < 0) error *= -1; @@ -794,7 +794,7 @@ static void sdram_write_leveling_find_cmd_delay(unsigned int *best_error, unsign } } #ifdef SDRAM_WRITE_LEVELING_CMD_DELAY_DEBUG - printf("Delay mean: %d, ideal: %d\n", delay_mean, ideal_delay); + printf("Delay mean: %d/256, ideal: %d/256\n", delay_mean, ideal_delay); #else printf("%d", ok); #endif From 7c7b7f78186b5abd946ccea712524988a78c44cc Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Thu, 10 Nov 2022 11:22:45 +0800 Subject: [PATCH 3/3] software/liblitedram: fix an off-by-1 error when write leveling When finding the longest 1 window when write leveling, if the last tap is 1, it won't be correctly handle because the end condition force to judge it as 0. Add one more iteration and force 0 in that one to handle the last 1. Signed-off-by: Icenowy Zheng --- litex/soc/software/liblitedram/sdram.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/litex/soc/software/liblitedram/sdram.c b/litex/soc/software/liblitedram/sdram.c index e824d01a8..86fea89f8 100644 --- a/litex/soc/software/liblitedram/sdram.c +++ b/litex/soc/software/liblitedram/sdram.c @@ -671,9 +671,9 @@ static int sdram_write_leveling_scan(int *delays, int loops, int show) one_window_best_start = 0; one_window_best_count = -1; delays[i] = -1; - for(j=0;j one_window_best_count) { @@ -682,7 +682,7 @@ static int sdram_write_leveling_scan(int *delays, int loops, int show) } } } else { - if (taps_scan[j]) { + if (j != err_ddrphy_wdly && taps_scan[j]) { one_window_active = 1; one_window_start = j; }