From b1d67364b4b4832b8efed112f7b0ead1a0b3cd3b Mon Sep 17 00:00:00 2001 From: Kimplul Date: Sun, 22 Sep 2024 22:45:18 +0300 Subject: start experimenting with processor grids --- src/components/grid/node.c | 106 +++++++++++++++++++++++++++++++++++++++ src/components/grid/router.c | 114 ++++++++++++++++++++++++++++++++++++++++++ src/components/grid/source.mk | 1 + 3 files changed, 221 insertions(+) create mode 100644 src/components/grid/node.c create mode 100644 src/components/grid/router.c create mode 100644 src/components/grid/source.mk (limited to 'src/components/grid') diff --git a/src/components/grid/node.c b/src/components/grid/node.c new file mode 100644 index 0000000..0aed768 --- /dev/null +++ b/src/components/grid/node.c @@ -0,0 +1,106 @@ +/* very simple grid node with 32bit private region, does not currently signal + * being busy or anything. I think I might have to refine the message passing + * interface I have, but this is good enough. + * + * Each node should have a router beneath it, just to simplify my life. A router + * is basically a bus with a fallback ascension path. + */ +#include + +struct grid_node { + struct component component; + uint8_t u, v, x, y; + struct component *left, *right, *up, *down, *ascend, *lower; +}; + +typedef read_callback callback; + +static stat grid_route(struct grid_node *grid, struct packet *pkt, callback op) +{ + uint64_t addr = packet_addr(pkt); + uint8_t u = (addr >> 56) & 0xff; + uint8_t v = (addr >> 48) & 0xff; + uint8_t x = (addr >> 40) & 0xff; + uint8_t y = (addr >> 32) & 0xff; + + if (grid->u == u && grid->v == v && grid->x == x && grid->y == y) + return op(grid->lower, pkt); + + if (grid->u != u || grid->v != v) { + if (!grid->ascend) + return EBUS; + + return op(grid->ascend, pkt); + } + + if (y < grid->y) { + if (!grid->down) + return EBUS; + + return op(grid->down, pkt); + } + + if (y > grid->y) { + if (!grid->up) + return EBUS; + + return op(grid->up, pkt); + } + + if (x < grid->x) { + if (!grid->left) + return EBUS; + + return op(grid->left, pkt); + } + + if (x > grid->x) { + if (!grid->right) + return EBUS; + + return op(grid->right, pkt); + } + + return EBUS; +} + +static stat grid_write(struct grid_node *node, struct packet *pkt) +{ + return grid_route(node, pkt, write); +} + +static stat grid_read(struct grid_node *node, struct packet *pkt) +{ + return grid_route(node, pkt, read); +} + +struct component *create_grid_node(uint8_t u, uint8_t v, uint8_t x, uint8_t y) +{ + struct grid_node *node = calloc(1, sizeof(struct grid_node)); + if (!node) + return NULL; + + node->u = u; + node->v = v; + node->x = x; + node->y = y; + node->component.write = (write_callback)grid_write; + node->component.read = (read_callback)grid_read; + + return (struct component *)node; +} + +stat grid_node_connect(struct component *node, + struct component *left, struct component *right, + struct component *up, struct component *down, + struct component *lower, struct component *ascend) +{ + struct grid_node *n = (struct grid_node *)node; + n->left = left; + n->right = right; + n->up = up; + n->down = down; + n->lower = lower; + n->ascend = ascend; + return OK; +} diff --git a/src/components/grid/router.c b/src/components/grid/router.c new file mode 100644 index 0000000..bdb05c8 --- /dev/null +++ b/src/components/grid/router.c @@ -0,0 +1,114 @@ +#include +#include + +struct router_region { + uint32_t addr; + uint32_t size; + struct component *component; +}; + +struct node_router { + struct component component; + struct component *ascend; + struct vec regions; + uint8_t u, v, x, y; +}; + +static struct router_region *find_region(struct node_router *router, uint32_t addr) +{ + for (size_t i = 0; i < vec_len(&router->regions); ++i) { + struct router_region *region = vec_at(&router->regions, i); + + if (addr >= region->addr && addr < region->addr + region->size) + return region; + } + + return NULL; +} + +static stat router_write(struct node_router *router, struct packet *pkt) +{ + uint64_t addr = packet_addr(pkt); + uint8_t u = (addr >> 56) & 0xff; + uint8_t v = (addr >> 48) & 0xff; + uint8_t x = (addr >> 40) & 0xff; + uint8_t y = (addr >> 32) & 0xff; + + if (router->u != u || router->v != v || router->x != x || router->y != y) + return write(router->ascend, pkt); + + struct router_region *region = find_region(router, addr); + if (!region) + return write(router->ascend, pkt); + + return write(region->component, pkt); +} + +static stat router_read(struct node_router *router, struct packet *pkt) +{ + uint64_t addr = packet_addr(pkt); + uint8_t u = (addr >> 56) & 0xff; + uint8_t v = (addr >> 48) & 0xff; + uint8_t x = (addr >> 40) & 0xff; + uint8_t y = (addr >> 32) & 0xff; + + if (router->u != u || router->v != v || router->x != x || router->y != y) + return read(router->ascend, pkt); + + struct router_region *region = find_region(router, addr); + if (!region) + return read(router->ascend, pkt); + + return read(region->component, pkt); +} + +struct component *create_node_router(uint8_t u, uint8_t v, uint8_t x, uint8_t y) +{ + struct node_router *router = calloc(1, sizeof(struct node_router)); + if (!router) + return NULL; + + router->u = u; + router->v = v; + router->x = x; + router->y = y; + + router->component.write = (write_callback)router_write; + router->component.read = (read_callback)router_read; + router->regions = vec_create(sizeof(struct router_region)); + + return (struct component *)router; +} + +stat node_router_add(struct component *router, struct component *component, uint32_t addr, uint32_t size) +{ + struct node_router *nr = (struct node_router *)router; + struct router_region *found = find_region(nr, addr); + if (!found) found = find_region(nr, addr + size); + + if (found) { + error("%s overlaps with %s at %x", + found->component->name, + component->name, + found->addr + ); + + return EEXISTS; + } + + struct router_region r = (struct router_region){ + .addr = addr, + .size = size, + .component = component + }; + vect_append(struct node_region, nr->regions, &r); + + return OK; +} + +stat node_router_ascend(struct component *router, struct component *node) +{ + struct node_router *nr = (struct node_router *)router; + nr->ascend = node; + return OK; +} diff --git a/src/components/grid/source.mk b/src/components/grid/source.mk new file mode 100644 index 0000000..4fb44ec --- /dev/null +++ b/src/components/grid/source.mk @@ -0,0 +1 @@ +SOURCES += src/components/grid/node.c src/components/grid/router.c -- cgit v1.3