From 1e9606f3fb9d502a9331654c336c17061d8e7cfe Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Fri, 12 Mar 2021 12:37:35 +0100 Subject: [PATCH] software/liblitedram: Improve find_cmd_delay to favor higher number of valid modules and centered scan. Also add an optional debug #define to look at cmd/clk centering scans: __ _ __ _ __ / / (_) /____ | |/_/ / /__/ / __/ -_)> < /____/_/\__/\__/_/|_| Build your hardware, easily! (c) Copyright 2012-2020 Enjoy-Digital (c) Copyright 2007-2015 M-Labs BIOS built on Mar 12 2021 14:06:20 BIOS CRC passed (116682af) Migen git sha1: 7014bdc LiteX git sha1: edcc0f88 --=============== SoC ==================-- CPU: VexRiscv @ 125MHz BUS: WISHBONE 32-bit @ 4GiB CSR: 32-bit data ROM: 64KiB SRAM: 8KiB L2: 8KiB SDRAM: 1048576KiB 64-bit @ 1000MT/s (CL-7 CWL-6) --========== Initialization ============-- Initializing SDRAM @0x40000000... Switching SDRAM to software control. Write leveling: tCK/4 taps: 6 Cmd/Clk scan (0-12) |Cmd/Clk delay: 0 m0: |11000000000000011111111111| delay: 15 m1: |00000000000000111111111111| delay: 14 m2: |11110000000000000111111111| delay: 17 m3: |11110000000000000011111111| delay: 18 m4: |11111111110000000000000111| delay: - m5: |11111111110000000000000111| delay: - m6: |11111111111000000000000001| delay: - m7: |11111111111000000000000011| delay: - Delay mean: 22, ideal: 13 Cmd/Clk delay: 1 m0: |11100000000000001111111111| delay: 16 m1: |10000000000000011111111111| delay: 15 m2: |11111000000000000011111111| delay: 18 m3: |11111000000000000001111111| delay: 19 m4: |11111111111000000000000011| delay: - m5: |11111111111000000000000011| delay: - m6: |11111111111100000000000000| delay: - m7: |11111111111100000000000001| delay: - Delay mean: 23, ideal: 13 Cmd/Clk delay: 2 m0: |11110000000000000111111111| delay: 17 m1: |11000000000000001111111111| delay: 16 m2: |11111100000000000001111111| delay: - m3: |11111100000000000000111111| delay: - m4: |11111111111100000000000001| delay: - m5: |11111111111100000000000001| delay: - m6: |11111111111110000000000000| delay: - m7: |11111111111110000000000000| delay: - Delay mean: 22, ideal: 13 Cmd/Clk delay: 3 m0: |11111000000000000011111111| delay: 18 m1: |11100000000000000111111111| delay: 17 m2: |11111110000000000000111111| delay: - m3: |11111110000000000000011111| delay: - m4: |11111111111110000000000000| delay: - m5: |11111111111110000000000000| delay: - m6: |01111111111111000000000000| delay: 01 m7: |01111111111111000000000000| delay: 01 Delay mean: 15, ideal: 13 Cmd/Clk delay: 4 m0: |11111100000000000001111111| delay: - m1: |11110000000000000011111111| delay: 18 m2: |11111111000000000000011111| delay: - m3: |11111111000000000000001111| delay: - m4: |11111111111111000000000000| delay: - m5: |11111111111111000000000000| delay: - m6: |00111111111111100000000000| delay: 02 m7: |00111111111111100000000000| delay: 02 Delay mean: 13, ideal: 13 Cmd/Clk delay: 5 m0: |11111110000000000000111111| delay: - m1: |11111000000000000001111111| delay: 19 m2: |11111111100000000000001111| delay: - m3: |11111111100000000000000111| delay: - m4: |01111111111111100000000000| delay: 01 m5: |01111111111111100000000000| delay: 01 m6: |00011111111111110000000000| delay: 03 m7: |00011111111111110000000000| delay: 03 Delay mean: 11, ideal: 13 Cmd/Clk delay: 6 m0: |11111111000000000000011111| delay: - m1: |11111100000000000000111111| delay: - m2: |11111111110000000000000111| delay: - m3: |11111111110000000000000011| delay: - m4: |00111111111111110000000000| delay: 02 m5: |00011111111111110000000000| delay: 03 m6: |00001111111111111000000000| delay: 04 m7: |00001111111111111000000000| delay: 04 Delay mean: 9, ideal: 13 Cmd/Clk delay: 7 m0: |11111111100000000000001111| delay: - m1: |11111110000000000000011111| delay: - m2: |11111111111000000000000011| delay: - m3: |11111111111000000000000001| delay: - m4: |00011111111111111000000000| delay: 03 m5: |00001111111111111000000000| delay: 04 m6: |00000111111111111100000000| delay: 05 m7: |00000111111111111100000000| delay: 05 Delay mean: 10, ideal: 13 Cmd/Clk delay: 8 m0: |11111111110000000000000111| delay: - m1: |11111111000000000000001111| delay: - m2: |11111111111100000000000001| delay: - m3: |11111111111100000000000000| delay: - m4: |00001111111111111100000000| delay: 04 m5: |00000111111111111100000000| delay: 05 m6: |00000011111111111110000000| delay: 06 m7: |00000011111111111110000000| delay: 06 Delay mean: 11, ideal: 13 Cmd/Clk delay: 9 m0: |11111111111000000000000011| delay: - m1: |11111111100000000000000111| delay: - m2: |11111111111110000000000000| delay: - m3: |11111111111110000000000000| delay: - m4: |00000111111111111110000000| delay: 05 m5: |00000011111111111110000000| delay: 06 m6: |00000001111111111111000000| delay: 07 m7: |00000001111111111111000000| delay: 07 Delay mean: 12, ideal: 13 Cmd/Clk delay: 10 m0: |11111111111100000000000011| delay: - m1: |11111111110000000000000011| delay: - m2: |01111111111111000000000000| delay: 01 m3: |01111111111111000000000000| delay: 01 m4: |00000011111111111111000000| delay: 06 m5: |00000001111111111111000000| delay: 07 m6: |00000000111111111111100000| delay: 08 m7: |00000000111111111111100000| delay: 08 Delay mean: 11, ideal: 13 Cmd/Clk delay: 11 m0: |11111111111110000000000001| delay: - m1: |11111111111000000000000001| delay: - m2: |00111111111111100000000000| delay: 02 m3: |00111111111111100000000000| delay: 02 m4: |00000001111111111111100000| delay: 07 m5: |00000000111111111111100000| delay: 08 m6: |00000000011111111111110000| delay: 09 m7: |00000000011111111111110000| delay: 09 Delay mean: 12, ideal: 13 | best: 11 Setting Cmd/Clk delay to 11 taps. Data scan: m0: |11111111111110000000000001| delay: - m1: |11111111111000000000000001| delay: - m2: |00111111111111100000000000| delay: 02 m3: |00111111111111100000000000| delay: 02 m4: |00000001111111111111100000| delay: 07 m5: |00000000111111111111100000| delay: 08 m6: |00000000011111111111110000| delay: 09 m7: |00000000011111111111110000| delay: 09 Write latency calibration: m0:6 m1:6 m2:6 m3:6 m4:6 m5:6 m6:6 m7:6 Read leveling: m0, b0: |00000000000000000000000000000000| delays: - m0, b1: |00000000000000000000000000000000| delays: - m0, b2: |00000000000000000000000000000000| delays: - m0, b3: |11111111100000000000000000000000| delays: 04+-04 m0, b4: |00000000000001111111110000000000| delays: 17+-04 m0, b5: |00000000000000000000000000111111| delays: 29+-03 m0, b6: |00000000000000000000000000000000| delays: - m0, b7: |00000000000000000000000000000000| delays: - best: m0, b03 delays: 04+-04 m1, b0: |00000000000000000000000000000000| delays: - m1, b1: |00000000000000000000000000000000| delays: - m1, b2: |00000000000000000000000000000000| delays: - m1, b3: |11111111000000000000000000000000| delays: 04+-04 m1, b4: |00000000000011111111100000000000| delays: 16+-04 m1, b5: |00000000000000000000000000111111| delays: 29+-03 m1, b6: |00000000000000000000000000000000| delays: - m1, b7: |00000000000000000000000000000000| delays: - best: m1, b04 delays: 16+-04 m2, b0: |00000000000000000000000000000000| delays: - m2, b1: |00000000000000000000000000000000| delays: - m2, b2: |00000000000000000000000000000000| delays: - m2, b3: |11111110000000000000000000000000| delays: 03+-03 m2, b4: |00000000000111111111000000000000| delays: 15+-04 m2, b5: |00000000000000000000000011111111| delays: 28+-04 m2, b6: |00000000000000000000000000000000| delays: - m2, b7: |00000000000000000000000000000000| delays: - best: m2, b04 delays: 15+-04 m3, b0: |00000000000000000000000000000000| delays: - m3, b1: |00000000000000000000000000000000| delays: - m3, b2: |00000000000000000000000000000000| delays: - m3, b3: |11111110000000000000000000000000| delays: 03+-03 m3, b4: |00000000001111111110000000000000| delays: 14+-04 m3, b5: |00000000000000000000000011111111| delays: 28+-04 m3, b6: |00000000000000000000000000000000| delays: - m3, b7: |00000000000000000000000000000000| delays: - best: m3, b04 delays: 14+-04 m4, b0: |00000000000000000000000000000000| delays: - m4, b1: |00000000000000000000000000000000| delays: - m4, b2: |00000000000000000000000000000000| delays: - m4, b3: |10000000000000000000000000000000| delays: - m4, b4: |00001111111110000000000000000000| delays: 08+-04 m4, b5: |00000000000000000111111111000000| delays: 22+-05 m4, b6: |00000000000000000000000000000001| delays: 31+-00 m4, b7: |00000000000000000000000000000000| delays: - best: m4, b04 delays: 08+-04 m5, b0: |00000000000000000000000000000000| delays: - m5, b1: |00000000000000000000000000000000| delays: - m5, b2: |00000000000000000000000000000000| delays: - m5, b3: |00000000000000000000000000000000| delays: - m5, b4: |00001111111110000000000000000000| delays: 08+-04 m5, b5: |00000000000000000011111111000000| delays: 22+-04 m5, b6: |00000000000000000000000000000001| delays: 31+-00 m5, b7: |00000000000000000000000000000000| delays: - best: m5, b04 delays: 08+-04 m6, b0: |00000000000000000000000000000000| delays: - m6, b1: |00000000000000000000000000000000| delays: - m6, b2: |00000000000000000000000000000000| delays: - m6, b3: |00000000000000000000000000000000| delays: - m6, b4: |00111111110000000000000000000000| delays: 06+-04 m6, b5: |00000000000000111111111000000000| delays: 18+-04 m6, b6: |00000000000000000000000000001111| delays: 30+-02 m6, b7: |00000000000000000000000000000000| delays: - best: m6, b05 delays: 19+-04 m7, b0: |00000000000000000000000000000000| delays: - m7, b1: |00000000000000000000000000000000| delays: - m7, b2: |00000000000000000000000000000000| delays: - m7, b3: |00000000000000000000000000000000| delays: - m7, b4: |01111111111100000000000000000000| delays: 06+-05 m7, b5: |00000000000000011111111110000000| delays: 20+-05 m7, b6: |00000000000000000000000000001111| delays: 30+-02 m7, b7: |00000000000000000000000000000000| delays: - best: m7, b04 delays: 06+-05 Switching SDRAM to hardware control. Memtest at 0x40000000 (2MiB)... Write: 0x40000000-0x40200000 2MiB Read: 0x40000000-0x40200000 2MiB Memtest OK Memspeed at 0x40000000 (2MiB)... Write speed: 40MiB/s Read speed: 33MiB/s --============== Boot ==================-- Booting from serial... Press Q or ESC to abort boot completely. sL5DdSMmkekro Timeout No boot medium found --============= Console ================-- --- litex/soc/software/liblitedram/sdram.c | 51 ++++++++++++++++++-------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/litex/soc/software/liblitedram/sdram.c b/litex/soc/software/liblitedram/sdram.c index 2de737443..76c4ee496 100644 --- a/litex/soc/software/liblitedram/sdram.c +++ b/litex/soc/software/liblitedram/sdram.c @@ -25,6 +25,7 @@ #include "sdram.h" //#define SDRAM_TEST_DISABLE +//#define SDRAM_WRITE_LEVELING_CMD_DELAY_DEBUG #ifdef CSR_SDRAM_BASE @@ -503,12 +504,15 @@ static int sdram_write_leveling_scan(int *delays, int loops, int show) return ok; } -static void sdram_write_leveling_find_cmd_delay(unsigned int *best_error, int *best_cdly, +static void sdram_write_leveling_find_cmd_delay(unsigned int *best_error, unsigned int *best_count, int *best_cdly, int cdly_start, int cdly_stop, int cdly_step) { int cdly; int cdly_actual = 0; int delays[SDRAM_PHY_MODULES]; +#ifndef SDRAM_WRITE_LEVELING_CMD_DELAY_DEBUG + int ok; +#endif /* Scan through the range */ ddrphy_cdly_rst_write(1); @@ -522,28 +526,42 @@ static void sdram_write_leveling_find_cmd_delay(unsigned int *best_error, int *b } /* Write level using this delay */ - if (sdram_write_leveling_scan(delays, 8, 0)) { - /* Use the mean of delays for error calulation */ - int delay_mean = 0; - for (int i=0; i < SDRAM_PHY_MODULES; ++i) { - delay_mean += delays[i]; +#ifdef SDRAM_WRITE_LEVELING_CMD_DELAY_DEBUG + printf("Cmd/Clk delay: %d\n", cdly); + sdram_write_leveling_scan(delays, 8, 1); +#else + ok = sdram_write_leveling_scan(delays, 8, 0); +#endif + /* Use the mean of delays for error calulation */ + int delay_mean = 0; + int delay_count = 0; + for (int i=0; i < SDRAM_PHY_MODULES; ++i) { + if (delays[i] != -1) { + delay_mean += delays[i] + ddrphy_half_sys8x_taps_read(); + delay_count += 1; } - delay_mean /= SDRAM_PHY_MODULES; + } + if (delay_count != 0) + delay_mean /= delay_count; - /* We want it to be at the start */ - int ideal_delay = 0; - int error = ideal_delay - delay_mean; - if (error < 0) - error *= -1; + /* We want the higher number of valid modules and delay to be centered */ + int ideal_delay = (SDRAM_PHY_DELAYS - ddrphy_half_sys8x_taps_read())/2; + int error = ideal_delay - delay_mean; + if (error < 0) + error *= -1; + if (delay_count >= *best_count) { + *best_count = delay_count; if (error < *best_error) { *best_cdly = cdly; *best_error = error; } - printf("1"); - } else { - printf("0"); } +#ifdef SDRAM_WRITE_LEVELING_CMD_DELAY_DEBUG + printf("Delay mean: %d, ideal: %d\n", delay_mean, ideal_delay); +#else + printf("%d", ok); +#endif } } @@ -551,6 +569,7 @@ int sdram_write_leveling(void) { int delays[SDRAM_PHY_MODULES]; unsigned int best_error = ~0u; + unsigned int best_count = 0; int best_cdly = -1; int cdly_range_start; int cdly_range_end; @@ -578,7 +597,7 @@ int sdram_write_leveling(void) cdly_range_step = 1; while (cdly_range_step > 0) { printf(" |"); - sdram_write_leveling_find_cmd_delay(&best_error, &best_cdly, + sdram_write_leveling_find_cmd_delay(&best_error, &best_count, &best_cdly, cdly_range_start, cdly_range_end, cdly_range_step); /* Small optimization - stop if we have zero error */