diff --git a/litex/soc/software/bios/cmds/cmd_mem.c b/litex/soc/software/bios/cmds/cmd_mem.c index cb01a3926..d8e165ab3 100644 --- a/litex/soc/software/bios/cmds/cmd_mem.c +++ b/litex/soc/software/bios/cmds/cmd_mem.c @@ -202,9 +202,10 @@ static void mem_speed_handler(int nb_params, char **params) unsigned int *addr; unsigned long size; bool read_only = false; + bool random_access = false; if (nb_params < 1) { - printf("mem_speed []"); + printf("mem_speed [] []"); return; } @@ -228,6 +229,14 @@ static void mem_speed_handler(int nb_params, char **params) } } - memspeed(addr, size, read_only); + if (nb_params >= 4) { + random_access = (bool) strtoul(params[3], &c, 0); + if (*c != 0) { + printf("Incorrect random_access value"); + return; + } + } + + memspeed(addr, size, read_only, random_access); } define_command(mem_speed, mem_speed_handler, "Test memory speed", MEM_CMDS); diff --git a/litex/soc/software/include/base/memtest.h b/litex/soc/software/include/base/memtest.h index 8ea4c3528..30f0693c4 100644 --- a/litex/soc/software/include/base/memtest.h +++ b/litex/soc/software/include/base/memtest.h @@ -20,7 +20,7 @@ int memtest_bus(unsigned int *addr, unsigned long size); int memtest_addr(unsigned int *addr, unsigned long size, int random); int memtest_data(unsigned int *addr, unsigned long size, int random, struct memtest_config *config); -void memspeed(unsigned int *addr, unsigned long size, bool read_only); +void memspeed(unsigned int *addr, unsigned long size, bool read_only, bool random_access); int memtest(unsigned int *addr, unsigned long maxsize); #endif /* __MEMTEST_H */ diff --git a/litex/soc/software/libbase/memtest.c b/litex/soc/software/libbase/memtest.c index 7d4d3e2b5..34e4d830a 100644 --- a/litex/soc/software/libbase/memtest.c +++ b/litex/soc/software/libbase/memtest.c @@ -252,10 +252,11 @@ int memtest_data(unsigned int *addr, unsigned long size, int random, struct memt return errors; } -void memspeed(unsigned int *addr, unsigned long size, bool read_only) +void memspeed(unsigned int *addr, unsigned long size, bool read_only, bool random_access) { volatile unsigned long *array = (unsigned long *)addr; int i; + unsigned int seed_32; uint32_t start, end; unsigned long write_speed = 0; unsigned long read_speed; @@ -297,9 +298,20 @@ void memspeed(unsigned int *addr, unsigned long size, bool read_only) timer0_en_write(1); timer0_update_value_write(1); start = timer0_value_read(); - for(i = 0; i < size/sz; i++) { - data = array[i]; + + int num = size/sz; + + if (random_access) { + for (i = 0; i < size/sz; i++) { + seed_32 = seed_to_data_32(seed_32, i); + data = array[seed_32 % num]; + } + } else { + for (i = 0; i < size/sz; i++) { + data = array[i]; + } } + timer0_update_value_write(1); end = timer0_value_read(); uint64_t numerator = ((uint64_t)size)*((uint64_t)CONFIG_CLOCK_FREQUENCY); diff --git a/litex/soc/software/liblitespi/spiflash.c b/litex/soc/software/liblitespi/spiflash.c index 548dc33d0..d1c4ca8a7 100644 --- a/litex/soc/software/liblitespi/spiflash.c +++ b/litex/soc/software/liblitespi/spiflash.c @@ -88,10 +88,14 @@ void spiflash_init(void) printf("Initializing %s SPI Flash...\n", SPIFLASH_MODULE_NAME); +#ifndef SPIFLASH_SKIP_FREQ_INIT /* Clk frequency auto-calibration. */ ret = spiflash_freq_init(); if (ret < 0) return; +#else + printf("Warning: SPI Flash frequency auto-calibration skipped, using the default divisor of %d", spiflash_phy_clk_divisor_read()); +#endif /* Dummy bits setup. */ #ifdef SPIFLASH_MODULE_DUMMY_BITS @@ -115,6 +119,11 @@ void spiflash_init(void) #endif + printf("SPI Flash bandwidth benchmarks\n"); + printf("Sequential accesses:"); + memspeed(SPIFLASH_BASE, SPIFLASH_SIZE, 1, 0); + printf("Random accesses:"); + memspeed(SPIFLASH_BASE, SPIFLASH_SIZE, 1, 1); } #endif