diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2025-08-09 16:06:43 +0300 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2025-08-09 16:06:43 +0300 |
| commit | 3083284c797fc8fc267144b05c8a58395e4583e3 (patch) | |
| tree | d0413af85d65cf895aa85fdaaf3a9f090f41dac1 /tests | |
| parent | aba90a3a6f6c1caee28aaf3dadebb4daba5b5761 (diff) | |
| download | gran-3083284c797fc8fc267144b05c8a58395e4583e3.tar.gz gran-3083284c797fc8fc267144b05c8a58395e4583e3.zip | |
add 1d mesh node and refactor 2d mesh node
+ Seems to decrease performance a little bit, presumably due to
extra register copy, but simplifies code a lot and opens up more
genericism so I'll consider it an upgrade for now. Copying packets
around is rather slow though, might in the future move to some
kind of pointer based packet handling
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/simple_mesh/source.mk | 18 | ||||
| -rw-r--r-- | tests/simple_mesh1d/sim.c | 88 | ||||
| -rw-r--r-- | tests/simple_mesh1d/source.mk | 19 | ||||
| -rw-r--r-- | tests/simple_mesh1d/test.c | 66 | ||||
| -rw-r--r-- | tests/simple_mesh2d/sim.c (renamed from tests/simple_mesh/sim.c) | 23 | ||||
| -rw-r--r-- | tests/simple_mesh2d/source.mk | 18 | ||||
| -rw-r--r-- | tests/simple_mesh2d/test.c (renamed from tests/simple_mesh/test.c) | 2 | ||||
| -rw-r--r-- | tests/starved_mesh/sim.c | 24 |
8 files changed, 221 insertions, 37 deletions
diff --git a/tests/simple_mesh/source.mk b/tests/simple_mesh/source.mk deleted file mode 100644 index 748e252..0000000 --- a/tests/simple_mesh/source.mk +++ /dev/null @@ -1,18 +0,0 @@ -MESH_TEST_OBJ != ./scripts/gen-deps --sources "tests/simple_mesh/sim.c" -TEST_PROGS += build/tests/simple_mesh/sim - -build/tests/simple_mesh/test.inc: tests/simple_mesh/test.c - riscv64-unknown-elf-gcc -O2 -Wall -Wextra -ffreestanding -nostdlib \ - -march=rv64i -mabi=lp64 \ - -o build/tests/simple_mesh/test \ - tests/simple_mesh/test.c - riscv64-unknown-elf-objcopy -Obinary \ - build/tests/simple_mesh/test \ - build/tests/simple_mesh/test.bin - xxd -i build/tests/simple_mesh/test.bin \ - > build/tests/simple_mesh/test.inc - -build/tests/simple_mesh/sim.o: build/tests/simple_mesh/test.inc - -build/tests/simple_mesh/sim: $(MESH_TEST_OBJ) $(OBJS) - $(COMPILE) $(MESH_TEST_OBJ) $(OBJS) -o $@ diff --git a/tests/simple_mesh1d/sim.c b/tests/simple_mesh1d/sim.c new file mode 100644 index 0000000..c5f7290 --- /dev/null +++ b/tests/simple_mesh1d/sim.c @@ -0,0 +1,88 @@ +#include <assert.h> + +#include <gran/root.h> +#include <gran/mem/simple_mem.h> +#include <gran/bus/simple_bus.h> +#include <gran/uart/simple_uart.h> +#include <gran/mesh/node1d.h> +#include <gran/cpu/riscv/simple_riscv64.h> + +#include "../build/tests/simple_mesh1d/test.inc" + +static stat build_node1d(struct clock_domain *clk, uint16_t x, uint16_t y) +{ + struct component **mesh = calloc(x + 1, sizeof(struct component *)); + assert(mesh); + + for (int i = 1; i < x + 1; ++i) { + /* 4 CPUs + 1 mem = 5 elems in total */ + struct component *node = create_mesh_node1d(i, y + 1); + clock_domain_add(clk, node); + mesh[i] = node; + + for (int j = 0; j < y; ++j) { + struct component *imem = create_simple_mem(4096); + init_simple_mem(imem, 0, + build_tests_simple_mesh1d_test_bin_len, + build_tests_simple_mesh1d_test_bin); + + uint64_t rcv = mesh1d_addr(i, j, 0); + struct component *rv64 = create_simple_riscv64(rcv, 0, imem, node); + simple_riscv64_set_reg(rv64, 10, i); /* a0 */ + simple_riscv64_set_reg(rv64, 11, j); /* a1 */ + simple_riscv64_set_reg(rv64, 12, x); /* a2 */ + simple_riscv64_set_reg(rv64, 13, y); /* a3 */ + + clock_domain_add(clk, rv64); + clock_domain_add(clk, imem); + + mesh_node1d_connect(node, rv64, j); + } + + struct component *dmem = create_simple_mem(4096); + clock_domain_add(clk, dmem); + mesh_node1d_connect(node, dmem, 4); + } + + /* extra I/O node (kind of?) */ + struct component *node = create_mesh_node1d(0, 2); + clock_domain_add(clk, node); + mesh[0] = node; + + struct component *uart = create_simple_uart(); + clock_domain_add(clk, uart); + mesh_node1d_connect(node, uart, 0); + + struct component *dmem = create_simple_mem(4096); + clock_domain_add(clk, dmem); + mesh_node1d_connect(node, dmem, 1); + + for (int i = 0; i < x + 1; ++i) { + if (i - 1 >= 0) + mesh_node1d_connect_right(mesh[i], mesh[i - 1]); + + if (i + 1 < x + 1) + mesh_node1d_connect_left(mesh[i], mesh[i + 1]); + } + + free(mesh); + return OK; +} + +int main() +{ + struct clock_domain *clk = create_clock_domain(NS(1)); + + /* one cluster with four cores + mem for each core (should + * instructions be fetched from cluster local mem?) */ + stat r = build_node1d(clk, 8, 8); + assert(r == OK); + + struct gran_root *root = create_root(); + root_add_clock(root, clk); + + r = root_run(root); + assert(r == OK); + + destroy_root(root); +} diff --git a/tests/simple_mesh1d/source.mk b/tests/simple_mesh1d/source.mk new file mode 100644 index 0000000..5013c6e --- /dev/null +++ b/tests/simple_mesh1d/source.mk @@ -0,0 +1,19 @@ +MESH1D_TEST_OBJ != ./scripts/gen-deps --sources "tests/simple_mesh1d/sim.c" +TEST_PROGS += build/tests/simple_mesh1d/sim + +build/tests/simple_mesh1d/test.inc: tests/simple_mesh1d/test.c + riscv64-unknown-elf-gcc -O2 -Wall -Wextra -ffreestanding -nostdlib \ + -march=rv64i -mabi=lp64 \ + -fno-delete-null-pointer-checks \ + -o build/tests/simple_mesh1d/test \ + tests/simple_mesh1d/test.c + riscv64-unknown-elf-objcopy -Obinary \ + build/tests/simple_mesh1d/test \ + build/tests/simple_mesh1d/test.bin + xxd -i build/tests/simple_mesh1d/test.bin \ + > build/tests/simple_mesh1d/test.inc + +build/tests/simple_mesh1d/sim.o: build/tests/simple_mesh1d/test.inc + +build/tests/simple_mesh1d/sim: $(MESH1D_TEST_OBJ) $(OBJS) + $(COMPILE) $(MESH1D_TEST_OBJ) $(OBJS) -o $@ diff --git a/tests/simple_mesh1d/test.c b/tests/simple_mesh1d/test.c new file mode 100644 index 0000000..b3de347 --- /dev/null +++ b/tests/simple_mesh1d/test.c @@ -0,0 +1,66 @@ +#include <stdint.h> + +__attribute__((always_inline)) +static inline uint64_t extreme_numa_addr(uint16_t cluster, uint16_t elem, uint32_t off) +{ + return ((uint64_t)cluster << 48) | ((uint64_t)elem << 32) | off; +} + +__attribute__((always_inline)) +static inline void print_int8(volatile char *uart, unsigned x) +{ + char lo_nibble = (x >> 0) & 0xf; + char hi_nibble = (x >> 4) & 0xf; + + *uart = hi_nibble < 10 ? hi_nibble + '0' : (hi_nibble - 10) + 'a'; + *uart = lo_nibble < 10 ? lo_nibble + '0' : (lo_nibble - 10) + 'a'; +} + +__attribute__((always_inline)) +static inline void print_addr(volatile char *uart, unsigned x, unsigned y) +{ + *uart = '('; + print_int8(uart, x); + *uart = ','; + *uart = ' '; + print_int8(uart, y); + *uart = ')'; + *uart = '\n'; +} + +__attribute__((always_inline)) +static inline uint64_t wrap(unsigned x, unsigned X) +{ + return x + 1 >= X ? 0 : x + 1; +} + +__attribute__((always_inline)) +static inline uint64_t next_idx(unsigned x, unsigned y, unsigned X, unsigned Y) +{ + unsigned yi = wrap(y, Y); + unsigned xi = yi < y ? wrap(x, X) : x; + + return extreme_numa_addr(xi, yi, 0); +} + +void _start(unsigned x, unsigned y, unsigned X, unsigned Y) +{ + volatile char *uart = (char *)extreme_numa_addr(0, 0, 0); + volatile uint64_t *control = (uint64_t *)extreme_numa_addr(0, 1, 0); + + if (x == 1 && y == 0) { + goto do_work; + } else { + while (*control != extreme_numa_addr(x, y, 0)) {} + } + +do_work: + print_addr(uart, x, y); + *control = next_idx(x, y, X, Y); + + if (x == X - 1 && y == Y - 1) + asm("ebreak"); + + /* otherwise just loop */ + while (1) {} +} diff --git a/tests/simple_mesh/sim.c b/tests/simple_mesh2d/sim.c index c3cdc33..1a9ba32 100644 --- a/tests/simple_mesh/sim.c +++ b/tests/simple_mesh2d/sim.c @@ -4,10 +4,10 @@ #include <gran/mem/simple_mem.h> #include <gran/bus/simple_bus.h> #include <gran/uart/simple_uart.h> -#include <gran/mesh/node.h> +#include <gran/mesh/node2d.h> #include <gran/cpu/riscv/simple_riscv64.h> -#include "../build/tests/simple_mesh/test.inc" +#include "../build/tests/simple_mesh2d/test.inc" static size_t idx_1d(int x, int y, uint8_t xw, uint8_t yw) { @@ -40,12 +40,11 @@ static void connect_mesh(struct component **mesh, struct component *c, uint16_t x, uint16_t y, uint16_t xw, uint16_t yw) { - mesh_node_connect(mesh_at(mesh, x, y, xw, yw), - mesh_at(mesh, x , y+1, xw, yw), - mesh_at(mesh, x , y-1, xw, yw), - mesh_at(mesh, x+1, y , xw, yw), - mesh_at(mesh, x-1, y , xw, yw), - c); + mesh_node2d_connect_north(mesh_at(mesh, x, y, xw, yw), mesh_at(mesh, x , y+1, xw, yw)); + mesh_node2d_connect_south(mesh_at(mesh, x, y, xw, yw), mesh_at(mesh, x , y-1, xw, yw)); + mesh_node2d_connect_east(mesh_at(mesh, x, y, xw, yw), mesh_at(mesh, x+1, y , xw, yw)); + mesh_node2d_connect_west(mesh_at(mesh, x, y, xw, yw), mesh_at(mesh, x-1, y , xw, yw)); + mesh_node2d_connect(mesh_at(mesh, x, y, xw, yw), c, 0); } static stat build_mesh(struct clock_domain *clk, uint16_t x, uint16_t y) @@ -58,7 +57,7 @@ static stat build_mesh(struct clock_domain *clk, uint16_t x, uint16_t y) for (size_t i = 0; i < x; ++i) for (size_t j = 0; j < y; ++j) { - struct component *node = create_mesh_node(i, j); + struct component *node = create_mesh_node2d(i, j, 1); clock_domain_add(clk, node); mesh[idx_1d(i, j, x, y)] = node; @@ -70,10 +69,10 @@ static stat build_mesh(struct clock_domain *clk, uint16_t x, uint16_t y) struct component *imem = create_simple_mem(4096); init_simple_mem(imem, 0, - build_tests_simple_mesh_test_bin_len, - build_tests_simple_mesh_test_bin); + build_tests_simple_mesh2d_test_bin_len, + build_tests_simple_mesh2d_test_bin); - uint64_t rcv = mesh_addr(i, j, 0); + uint64_t rcv = mesh2d_addr(i, j, 0, 0); struct component *rv64 = create_simple_riscv64(rcv, 0, imem, node); simple_riscv64_set_reg(rv64, 10, i); /* a0 */ simple_riscv64_set_reg(rv64, 11, j); /* a1 */ diff --git a/tests/simple_mesh2d/source.mk b/tests/simple_mesh2d/source.mk new file mode 100644 index 0000000..525efa3 --- /dev/null +++ b/tests/simple_mesh2d/source.mk @@ -0,0 +1,18 @@ +MESH2D_TEST_OBJ != ./scripts/gen-deps --sources "tests/simple_mesh2d/sim.c" +TEST_PROGS += build/tests/simple_mesh2d/sim + +build/tests/simple_mesh2d/test.inc: tests/simple_mesh2d/test.c + riscv64-unknown-elf-gcc -O2 -Wall -Wextra -ffreestanding -nostdlib \ + -march=rv64i -mabi=lp64 \ + -o build/tests/simple_mesh2d/test \ + tests/simple_mesh2d/test.c + riscv64-unknown-elf-objcopy -Obinary \ + build/tests/simple_mesh2d/test \ + build/tests/simple_mesh2d/test.bin + xxd -i build/tests/simple_mesh2d/test.bin \ + > build/tests/simple_mesh2d/test.inc + +build/tests/simple_mesh2d/sim.o: build/tests/simple_mesh2d/test.inc + +build/tests/simple_mesh2d/sim: $(MESH2D_TEST_OBJ) $(OBJS) + $(COMPILE) $(MESH2D_TEST_OBJ) $(OBJS) -o $@ diff --git a/tests/simple_mesh/test.c b/tests/simple_mesh2d/test.c index b1bbe84..d607a59 100644 --- a/tests/simple_mesh/test.c +++ b/tests/simple_mesh2d/test.c @@ -35,7 +35,7 @@ static inline unsigned next_idx(unsigned x, unsigned y, unsigned X, unsigned Y) void _start(unsigned x, unsigned y, unsigned X, unsigned Y) { volatile char *uart = (char *)4096; - volatile unsigned *control = (unsigned *)(1ULL << 48); + volatile unsigned *control = (unsigned *)(1ULL << 56); if (x == 0 && y == 2) { goto do_work; diff --git a/tests/starved_mesh/sim.c b/tests/starved_mesh/sim.c index 1967e0b..990acc5 100644 --- a/tests/starved_mesh/sim.c +++ b/tests/starved_mesh/sim.c @@ -7,7 +7,7 @@ #include <gran/mem/simple_mem.h> #include <gran/bus/simple_bus.h> #include <gran/uart/simple_uart.h> -#include <gran/mesh/node.h> +#include <gran/mesh/node2d.h> #include <gran/cpu/riscv/simple_riscv64.h> unsigned char _tmp_test_bin[] = { @@ -63,7 +63,7 @@ static stat build_mesh(struct clock_domain *clk, uint8_t x, uint8_t y) for (size_t i = 0; i < x; ++i) for (size_t j = 0; j < y; ++j) { - struct component *node = create_mesh_node(i, j); + struct component *node = create_mesh_node2d(i, j, 1); clock_domain_add(clk, node); mesh[i * x + j] = node; @@ -76,7 +76,7 @@ static stat build_mesh(struct clock_domain *clk, uint8_t x, uint8_t y) struct component *imem = create_simple_mem(4096); init_simple_mem(imem, 0, _tmp_test_bin_len, _tmp_test_bin); - uint64_t rcv = mesh_addr(i, j, 0); + uint64_t rcv = mesh2d_addr(i, j, 0, 0); struct component *rv64 = create_simple_riscv64(rcv, 0, imem, node); simple_riscv64_set_reg(rv64, 10, i); /* a0 */ simple_riscv64_set_reg(rv64, 11, j); /* a1 */ @@ -89,11 +89,19 @@ static stat build_mesh(struct clock_domain *clk, uint8_t x, uint8_t y) struct component *uart = create_simple_uart(); clock_domain_add(clk, uart); - mesh_node_connect(mesh[0], NULL, mesh[x], mesh[1], NULL, uart); + mesh_node2d_connect_north(mesh[0], NULL); + mesh_node2d_connect_south(mesh[0], mesh[x]); + mesh_node2d_connect_east(mesh[0], mesh[1]); + mesh_node2d_connect_west(mesh[0], NULL); + mesh_node2d_connect(mesh[0], uart, 0); struct component *dmem = create_simple_mem(4096); clock_domain_add(clk, dmem); - mesh_node_connect(mesh[1], NULL, mesh[x + 1], mesh[2], mesh[0], dmem); + mesh_node2d_connect_north(mesh[0], NULL); + mesh_node2d_connect_south(mesh[0], mesh[x + 1]); + mesh_node2d_connect_east(mesh[0], mesh[2]); + mesh_node2d_connect_west(mesh[0], mesh[0]); + mesh_node2d_connect(mesh[0], dmem, 0); for (int i = 0; i < x; ++i) for (int j = 0; j < y; ++j) { @@ -109,7 +117,11 @@ static stat build_mesh(struct clock_domain *clk, uint8_t x, uint8_t y) struct component *right = get_mesh(mesh, i + 1, j , x, y); struct component *up = get_mesh(mesh, i , j + 1, x, y); struct component *down = get_mesh(mesh, i , j - 1, x, y); - mesh_node_connect(node, left, right, up, down, lower); + mesh_node2d_connect_north(node, up); + mesh_node2d_connect_south(node, down); + mesh_node2d_connect_east(node, left); + mesh_node2d_connect_west(node, right); + mesh_node2d_connect(node, lower, 0); } free(pes); |
