aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteffen Vogel <post@steffenvogel.de>2019-02-11 23:14:56 +0100
committerSteffen Vogel <post@steffenvogel.de>2019-02-11 23:14:56 +0100
commitf3b1246c862c37108f2a472816e2ed2e5b37e269 (patch)
treefd2838aab5dc45eda753772194ae410b9d1e2c38
parentd21937bafc77e9f7d81c2f50d2ad825a39fb644c (diff)
downloadpicorv32-f3b1246c862c37108f2a472816e2ed2e5b37e269.tar.gz
picorv32-f3b1246c862c37108f2a472816e2ed2e5b37e269.zip
picosoc: added memtest
-rw-r--r--picosoc/firmware.c154
1 files changed, 126 insertions, 28 deletions
diff --git a/picosoc/firmware.c b/picosoc/firmware.c
index e3eed76..4a86615 100644
--- a/picosoc/firmware.c
+++ b/picosoc/firmware.c
@@ -20,7 +20,11 @@
#include <stdint.h>
#include <stdbool.h>
-#if !defined(ICEBREAKER) && !defined(HX8KDEMO)
+#ifdef ICEBREAKER
+ #define MEM_TOTAL 0x20000
+#elif HX8KDEMO
+ #define MEM_TOTAL 0x200
+#else
# error "Set -DICEBREAKER or -DHX8KDEMO when compiling firmware.c"
#endif
@@ -176,11 +180,21 @@ void print_hex(uint32_t v, int digits)
void print_dec(uint32_t v)
{
- if (v >= 100) {
- print(">=100");
+ if (v >= 1000) {
+ print(">=1000");
return;
}
+ if (v >= 900) { putchar('9'); v -= 900; }
+ else if (v >= 800) { putchar('8'); v -= 800; }
+ else if (v >= 700) { putchar('7'); v -= 700; }
+ else if (v >= 600) { putchar('6'); v -= 600; }
+ else if (v >= 500) { putchar('5'); v -= 500; }
+ else if (v >= 400) { putchar('4'); v -= 400; }
+ else if (v >= 300) { putchar('3'); v -= 300; }
+ else if (v >= 200) { putchar('2'); v -= 200; }
+ else if (v >= 100) { putchar('1'); v -= 100; }
+
if (v >= 90) { putchar('9'); v -= 90; }
else if (v >= 80) { putchar('8'); v -= 80; }
else if (v >= 70) { putchar('7'); v -= 70; }
@@ -236,6 +250,95 @@ char getchar()
return getchar_prompt(0);
}
+void cmd_print_spi_state()
+{
+ print("SPI State:\n");
+
+ print(" LATENCY ");
+ print_dec((reg_spictrl >> 16) & 15);
+ print("\n");
+
+ print(" DDR ");
+ if ((reg_spictrl & (1 << 22)) != 0)
+ print("ON\n");
+ else
+ print("OFF\n");
+
+ print(" QSPI ");
+ if ((reg_spictrl & (1 << 21)) != 0)
+ print("ON\n");
+ else
+ print("OFF\n");
+
+ print(" CRM ");
+ if ((reg_spictrl & (1 << 20)) != 0)
+ print("ON\n");
+ else
+ print("OFF\n");
+}
+
+uint32_t xorshift32(uint32_t *state)
+{
+ /* Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs" */
+ uint32_t x = *state;
+ x ^= x << 13;
+ x ^= x >> 17;
+ x ^= x << 5;
+ *state = x;
+
+ return x;
+}
+
+void cmd_memtest()
+{
+ int cyc_count = 5;
+ int stride = 256;
+ uint32_t state;
+
+ volatile uint32_t *base_word = (uint32_t *) 0;
+ volatile uint8_t *base_byte = (uint8_t *) 0;
+
+ print("Running memtest ");
+
+ // Walk in stride increments, word access
+ for (int i = 1; i <= cyc_count; i++) {
+ state = i;
+
+ for (int word = 0; word < MEM_TOTAL / sizeof(int); word += stride) {
+ *(base_word + word) = xorshift32(&state);
+ }
+
+ state = i;
+
+ for (int word = 0; word < MEM_TOTAL / sizeof(int); word += stride) {
+ if (*(base_word + word) != xorshift32(&state)) {
+ print(" ***FAILED WORD*** at ");
+ print_hex(4*word, 4);
+ print("\n");
+ return;
+ }
+ }
+
+ print(".");
+ }
+
+ // Byte access
+ for (int byte = 0; byte < 128; byte++) {
+ *(base_byte + byte) = (uint8_t) byte;
+ }
+
+ for (int byte = 0; byte < 128; byte++) {
+ if (*(base_byte + byte) != (uint8_t) byte) {
+ print(" ***FAILED BYTE*** at ");
+ print_hex(byte, 4);
+ print("\n");
+ return;
+ }
+ }
+
+ print(" passed\n");
+}
+
// --------------------------------------------------------
void cmd_read_flash_id()
@@ -570,36 +673,23 @@ void main()
print(" | |_) | |/ __/ _ \\___ \\ / _ \\| |\n");
print(" | __/| | (_| (_) |__) | (_) | |___\n");
print(" |_| |_|\\___\\___/____/ \\___/ \\____|\n");
+ print("\n");
- while (1)
- {
- print("\n");
- print("\n");
- print("SPI State:\n");
-
- print(" LATENCY ");
- print_dec((reg_spictrl >> 16) & 15);
- print("\n");
-
- print(" DDR ");
- if ((reg_spictrl & (1 << 22)) != 0)
- print("ON\n");
- else
- print("OFF\n");
+ print("Total memory: ");
+ print_dec(MEM_TOTAL / 1024);
+ print(" KiB\n");
+ print("\n");
- print(" QSPI ");
- if ((reg_spictrl & (1 << 21)) != 0)
- print("ON\n");
- else
- print("OFF\n");
+ cmd_memtest();
+ print("\n");
- print(" CRM ");
- if ((reg_spictrl & (1 << 20)) != 0)
- print("ON\n");
- else
- print("OFF\n");
+ cmd_print_spi_state();
+ print("\n");
+ while (1)
+ {
print("\n");
+
print("Select an action:\n");
print("\n");
print(" [1] Read SPI Flash ID\n");
@@ -611,6 +701,8 @@ void main()
print(" [7] Toggle continuous read mode\n");
print(" [9] Run simplistic benchmark\n");
print(" [0] Benchmark all configs\n");
+ print(" [M] Run Memtest\n");
+ print(" [S] Print SPI state\n");
print("\n");
for (int rep = 10; rep > 0; rep--)
@@ -650,6 +742,12 @@ void main()
case '0':
cmd_benchmark_all();
break;
+ case 'M':
+ cmd_memtest();
+ break;
+ case 'P':
+ cmd_print_spi_state();
+ break;
default:
continue;
}