diff --git a/litex/soc/software/liblitedram/bist.c b/litex/soc/software/liblitedram/bist.c index 7b9ef5ca4..3206e5eb8 100644 --- a/litex/soc/software/liblitedram/bist.c +++ b/litex/soc/software/liblitedram/bist.c @@ -10,6 +10,7 @@ #include #include +#include #include #define SDRAM_TEST_BASE 0x00000000 @@ -157,4 +158,52 @@ void sdram_bist(uint32_t burst_length, uint32_t random) } } +int sdram_hw_test(uint64_t origin, uint64_t size, uint64_t burst_length) { + uint64_t burst_size = SDRAM_TEST_DATA_BYTES * burst_length; + uint64_t old_burst_size = burst_size; + int errors = 0; + + uint64_t supported_memory = sdram_get_supported_memory(); + + if (origin >= supported_memory) { + printf("Selected origin out of memory bounds! Supported memory: "); + print_size(supported_memory); + printf("\n"); + return 0; + } + + if (origin + size > supported_memory) { + printf("Test would go out of memory bounds. Clipping size to memory end: "); + print_size(supported_memory); + printf("\n"); + size = supported_memory - origin; + } + + for (uint64_t address = origin; address < origin + size; address += burst_size) { + if (address + burst_size > size) { + old_burst_size = burst_size; + burst_size = size - address; + } + + if (burst_size < SDRAM_TEST_DATA_BYTES || old_burst_size < burst_size) + break; + + sdram_bist_write(address, burst_size); + + sdram_bist_read(address, burst_size); + errors += sdram_checker_errors_read(); + + print_progress(" SDRAM HW test:", origin, address - origin + burst_size); + } + + if (burst_size < SDRAM_TEST_DATA_BYTES || old_burst_size < burst_size) { + printf("\nTest would go out of memory bounds. Finished early at the end: "); + print_size(supported_memory); + } + + printf("\n"); + + return errors; +} + #endif diff --git a/litex/soc/software/liblitedram/bist.h b/litex/soc/software/liblitedram/bist.h index d697658c3..ab4c676ec 100644 --- a/litex/soc/software/liblitedram/bist.h +++ b/litex/soc/software/liblitedram/bist.h @@ -5,6 +5,8 @@ #define __SDRAM_BIST_H #include + void sdram_bist(uint32_t burst_length, uint32_t random); +int sdram_hw_test(uint64_t origin, uint64_t size, uint64_t burst_length); #endif /* __SDRAM_BIST_H */