aboutsummaryrefslogtreecommitdiffstats
path: root/firmware
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2015-06-26 22:02:22 +0200
committerClifford Wolf <clifford@clifford.at>2015-06-26 23:15:30 +0200
commitd4331491a87aa27fb77e5971c887e345886de2be (patch)
tree3e64f1b034055da5a47d963623d866172b544b56 /firmware
parentf0b824ad9a0d9c4a010baf62114009c847f6a94d (diff)
downloadpicorv32-d4331491a87aa27fb77e5971c887e345886de2be.tar.gz
picorv32-d4331491a87aa27fb77e5971c887e345886de2be.zip
Test firmware refactoring
Diffstat (limited to 'firmware')
-rw-r--r--firmware/firmware.h22
-rw-r--r--firmware/irq.c111
-rw-r--r--firmware/print.c36
-rw-r--r--firmware/sieve.c158
-rw-r--r--firmware/stats.c22
5 files changed, 195 insertions, 154 deletions
diff --git a/firmware/firmware.h b/firmware/firmware.h
new file mode 100644
index 0000000..7744463
--- /dev/null
+++ b/firmware/firmware.h
@@ -0,0 +1,22 @@
+#ifndef FIRMWARE_H
+#define FIRMWARE_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+// irq.c
+uint32_t *irq(uint32_t *regs, uint32_t irqs);
+
+// print.c
+void print_chr(char ch);
+void print_str(const char *p);
+void print_dec(int val);
+void print_hex(unsigned int val);
+
+// sieve.c
+void sieve();
+
+// stats.c
+void stats();
+
+#endif
diff --git a/firmware/irq.c b/firmware/irq.c
new file mode 100644
index 0000000..e49ef47
--- /dev/null
+++ b/firmware/irq.c
@@ -0,0 +1,111 @@
+
+#include "firmware.h"
+
+uint32_t *irq(uint32_t *regs, uint32_t irqs)
+{
+ static int ext_irq_4_count = 0;
+ static int ext_irq_5_count = 0;
+ static int timer_irq_count = 0;
+
+ if ((irqs & (1<<4)) != 0) {
+ ext_irq_4_count++;
+ // print_str("[EXT-IRQ-4]");
+ }
+
+ if ((irqs & (1<<5)) != 0) {
+ ext_irq_5_count++;
+ // print_str("[EXT-IRQ-5]");
+ }
+
+ if ((irqs & 1) != 0) {
+ timer_irq_count++;
+ // print_str("[TIMER-IRQ]");
+ }
+
+ if ((irqs & 6) != 0)
+ {
+ int i, k;
+ uint32_t pc = regs[0] - 4;
+ uint32_t instr = *(uint32_t*)pc;
+
+ print_str("\n");
+ print_str("------------------------------------------------------------\n");
+
+ if ((irqs & 2) != 0) {
+ if (instr == 0x00100073) {
+ print_str("SBREAK instruction at 0x");
+ print_hex(pc);
+ print_str("\n");
+ } else {
+ print_str("Illegal Instruction at 0x");
+ print_hex(pc);
+ print_str(": 0x");
+ print_hex(instr);
+ print_str("\n");
+ }
+ }
+
+ if ((irqs & 4) != 0) {
+ print_str("Bus error in Instruction at 0x");
+ print_hex(pc);
+ print_str(": 0x");
+ print_hex(instr);
+ print_str("\n");
+ }
+
+ for (i = 0; i < 8; i++)
+ for (k = 0; k < 4; k++)
+ {
+ int r = i + k*8;
+
+ if (r == 0) {
+ print_str("pc ");
+ } else
+ if (r < 10) {
+ print_chr('x');
+ print_chr('0' + r);
+ print_chr(' ');
+ print_chr(' ');
+ } else
+ if (r < 20) {
+ print_chr('x');
+ print_chr('1');
+ print_chr('0' + r - 10);
+ print_chr(' ');
+ } else
+ if (r < 30) {
+ print_chr('x');
+ print_chr('2');
+ print_chr('0' + r - 20);
+ print_chr(' ');
+ } else {
+ print_chr('x');
+ print_chr('3');
+ print_chr('0' + r - 30);
+ print_chr(' ');
+ }
+
+ print_hex(regs[r]);
+ print_str(k == 3 ? "\n" : " ");
+ }
+
+ print_str("------------------------------------------------------------\n");
+
+ print_str("Number of fast external IRQs counted: ");
+ print_dec(ext_irq_4_count);
+ print_str("\n");
+
+ print_str("Number of slow external IRQs counted: ");
+ print_dec(ext_irq_5_count);
+ print_str("\n");
+
+ print_str("Number of timer IRQs counted: ");
+ print_dec(timer_irq_count);
+ print_str("\n");
+
+ __asm__("sbreak");
+ }
+
+ return regs;
+}
+
diff --git a/firmware/print.c b/firmware/print.c
new file mode 100644
index 0000000..03e9b09
--- /dev/null
+++ b/firmware/print.c
@@ -0,0 +1,36 @@
+
+#include "firmware.h"
+
+#define OUTPORT 0x10000000
+
+void print_chr(char ch)
+{
+ *((volatile uint32_t*)OUTPORT) = ch;
+}
+
+void print_str(const char *p)
+{
+ while (*p != 0)
+ *((volatile uint32_t*)OUTPORT) = *(p++);
+}
+
+void print_dec(int val)
+{
+ char buffer[10];
+ char *p = buffer;
+ while (val || p == buffer) {
+ *(p++) = val % 10;
+ val = val / 10;
+ }
+ while (p != buffer) {
+ *((volatile uint32_t*)OUTPORT) = '0' + *(--p);
+ }
+}
+
+void print_hex(unsigned int val)
+{
+ int i;
+ for (i = 32-4; i >= 0; i -= 4)
+ *((volatile uint32_t*)OUTPORT) = "0123456789ABCDEF"[(val >> i) % 16];
+}
+
diff --git a/firmware/sieve.c b/firmware/sieve.c
index 6fb5b17..10fd1e0 100644
--- a/firmware/sieve.c
+++ b/firmware/sieve.c
@@ -1,12 +1,17 @@
// A simple Sieve of Eratosthenes
-#include <stdint.h>
-#include <stdbool.h>
+#include "firmware.h"
#define BITMAP_SIZE 64
-#define OUTPORT 0x10000000
static uint32_t bitmap[BITMAP_SIZE/32];
+static uint32_t hash;
+
+static uint32_t mkhash(uint32_t a, uint32_t b)
+{
+ // The XOR version of DJB2
+ return ((a << 5) + a) ^ b;
+}
static void bitmap_set(int idx)
{
@@ -18,37 +23,6 @@ static bool bitmap_get(int idx)
return (bitmap[idx/32] & (1 << (idx % 32))) != 0;
}
-static void print_chr(char ch)
-{
- *((volatile uint32_t*)OUTPORT) = ch;
-}
-
-static void print_str(const char *p)
-{
- while (*p != 0)
- *((volatile uint32_t*)OUTPORT) = *(p++);
-}
-
-static void print_dec(int val)
-{
- char buffer[10];
- char *p = buffer;
- while (val || p == buffer) {
- *(p++) = val % 10;
- val = val / 10;
- }
- while (p != buffer) {
- *((volatile uint32_t*)OUTPORT) = '0' + *(--p);
- }
-}
-
-static void print_hex(unsigned int val)
-{
- int i;
- for (i = 32-4; i >= 0; i -= 4)
- *((volatile uint32_t*)OUTPORT) = "0123456789ABCDEF"[(val >> i) % 16];
-}
-
static void print_prime(int idx, int val)
{
if (idx < 10)
@@ -66,12 +40,16 @@ static void print_prime(int idx, int val)
print_str(" prime is ");
print_dec(val);
print_str(".\n");
+
+ hash = mkhash(hash, idx);
+ hash = mkhash(hash, val);
}
void sieve()
{
int i, j, k;
int idx = 1;
+ hash = 5381;
print_prime(idx++, 2);
for (i = 0; i < BITMAP_SIZE; i++) {
if (bitmap_get(i))
@@ -86,113 +64,15 @@ void sieve()
bitmap_set(k);
}
}
-}
-uint32_t *irq(uint32_t *regs, uint32_t irqs)
-{
- static int ext_irq_4_count = 0;
- static int ext_irq_5_count = 0;
- static int timer_irq_count = 0;
+ print_str("checksum: ");
+ print_hex(hash);
- if ((irqs & (1<<4)) != 0) {
- ext_irq_4_count++;
- // print_str("[EXT-IRQ-4]");
+ if (hash == 0x1772A48F) {
+ print_str(" OK\n");
+ } else {
+ print_str(" ERROR\n");
+ asm volatile ("sbreak");
}
-
- if ((irqs & (1<<5)) != 0) {
- ext_irq_5_count++;
- // print_str("[EXT-IRQ-5]");
- }
-
- if ((irqs & 1) != 0) {
- timer_irq_count++;
- // print_str("[TIMER-IRQ]");
- }
-
- if ((irqs & 6) != 0)
- {
- int i, k;
- uint32_t pc = regs[0] - 4;
- uint32_t instr = *(uint32_t*)pc;
-
- print_str("\n");
- print_str("------------------------------------------------------------\n");
-
- if ((irqs & 2) != 0) {
- if (instr == 0x00100073) {
- print_str("SBREAK instruction at 0x");
- print_hex(pc);
- print_str("\n");
- } else {
- print_str("Illegal Instruction at 0x");
- print_hex(pc);
- print_str(": 0x");
- print_hex(instr);
- print_str("\n");
- }
- }
-
- if ((irqs & 4) != 0) {
- print_str("Bus error in Instruction at 0x");
- print_hex(pc);
- print_str(": 0x");
- print_hex(instr);
- print_str("\n");
- }
-
- for (i = 0; i < 8; i++)
- for (k = 0; k < 4; k++)
- {
- int r = i + k*8;
-
- if (r == 0) {
- print_str("pc ");
- } else
- if (r < 10) {
- print_chr('x');
- print_chr('0' + r);
- print_chr(' ');
- print_chr(' ');
- } else
- if (r < 20) {
- print_chr('x');
- print_chr('1');
- print_chr('0' + r - 10);
- print_chr(' ');
- } else
- if (r < 30) {
- print_chr('x');
- print_chr('2');
- print_chr('0' + r - 20);
- print_chr(' ');
- } else {
- print_chr('x');
- print_chr('3');
- print_chr('0' + r - 30);
- print_chr(' ');
- }
-
- print_hex(regs[r]);
- print_str(k == 3 ? "\n" : " ");
- }
-
- print_str("------------------------------------------------------------\n");
-
- print_str("Number of fast external IRQs counted: ");
- print_dec(ext_irq_4_count);
- print_str("\n");
-
- print_str("Number of slow external IRQs counted: ");
- print_dec(ext_irq_5_count);
- print_str("\n");
-
- print_str("Number of timer IRQs counted: ");
- print_dec(timer_irq_count);
- print_str("\n");
-
- __asm__("sbreak");
- }
-
- return regs;
}
diff --git a/firmware/stats.c b/firmware/stats.c
index c7b1b8e..21f97d5 100644
--- a/firmware/stats.c
+++ b/firmware/stats.c
@@ -1,14 +1,6 @@
-#include <stdint.h>
-#include <stdbool.h>
-#define OUTPORT 0x10000000
+#include "firmware.h"
-static void print_str(const char *p)
-{
- while (*p != 0)
- *((volatile uint32_t*)OUTPORT) = *(p++);
-}
-
-static void print_dec(int val, int digits, bool zero_pad)
+static void stats_print_dec(int val, int digits, bool zero_pad)
{
char buffer[32];
char *p = buffer;
@@ -22,7 +14,7 @@ static void print_dec(int val, int digits, bool zero_pad)
}
while (p != buffer) {
if (p[-1] == ' ' && p[-2] == ' ') p[-1] = '.';
- *((volatile uint32_t*)OUTPORT) = *(--p);
+ print_chr(*(--p));
}
}
@@ -31,13 +23,13 @@ void stats()
int num_cycles, num_instr;
asm("rdcycle %0; rdinstret %1;" : "=r"(num_cycles), "=r"(num_instr));
print_str("Cycle counter ........");
- print_dec(num_cycles, 8, false);
+ stats_print_dec(num_cycles, 8, false);
print_str("\nInstruction counter ..");
- print_dec(num_instr, 8, false);
+ stats_print_dec(num_instr, 8, false);
print_str("\nCPI: ");
- print_dec((num_cycles / num_instr), 0, false);
+ stats_print_dec((num_cycles / num_instr), 0, false);
print_str(".");
- print_dec(((100 * num_cycles) / num_instr) % 100, 2, true);
+ stats_print_dec(((100 * num_cycles) / num_instr) % 100, 2, true);
print_str("\n");
}