Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] SPSC queue #687

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions software/bsg_manycore_lib/bsg_manycore_atomic.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef _BSG_MANYCORE_ATOMIC_H
#define _BSG_MANYCORE_ATOMIC_H

inline int bsg_amoswap (int* p, int val)
inline int bsg_amoswap (volatile int* p, int val)
{
int result;
asm volatile ("amoswap.w %[result], %[val], 0(%[p])" \
Expand All @@ -10,7 +10,7 @@ inline int bsg_amoswap (int* p, int val)
return result;
}

inline int bsg_amoswap_aq (int* p, int val)
inline int bsg_amoswap_aq (volatile int* p, int val)
{
int result;
asm volatile ("amoswap.w.aq %[result], %[val], 0(%[p])" \
Expand All @@ -19,7 +19,7 @@ inline int bsg_amoswap_aq (int* p, int val)
return result;
}

inline int bsg_amoswap_rl(int* p, int val)
inline int bsg_amoswap_rl(volatile int* p, int val)
{
int result;
asm volatile ("amoswap.w.rl %[result], %[val], 0(%[p])" \
Expand All @@ -28,7 +28,7 @@ inline int bsg_amoswap_rl(int* p, int val)
return result;
}

inline int bsg_amoswap_aqrl(int* p, int val)
inline int bsg_amoswap_aqrl(volatile int* p, int val)
{
int result;
asm volatile ("amoswap.w.aqrl %[result], %[val], 0(%[p])" \
Expand All @@ -38,7 +38,7 @@ inline int bsg_amoswap_aqrl(int* p, int val)
}


inline int bsg_amoor (int* p, int val)
inline int bsg_amoor (volatile int* p, int val)
{
int result;
asm volatile ("amoor.w %[result], %[val], 0(%[p])" \
Expand All @@ -47,7 +47,7 @@ inline int bsg_amoor (int* p, int val)
return result;
}

inline int bsg_amoor_aq (int* p, int val)
inline int bsg_amoor_aq (volatile int* p, int val)
{
int result;
asm volatile ("amoor.w.aq %[result], %[val], 0(%[p])" \
Expand All @@ -56,7 +56,7 @@ inline int bsg_amoor_aq (int* p, int val)
return result;
}

inline int bsg_amoor_rl (int* p, int val)
inline int bsg_amoor_rl (volatile int* p, int val)
{
int result;
asm volatile ("amoor.w.rl %[result], %[val], 0(%[p])" \
Expand All @@ -65,7 +65,7 @@ inline int bsg_amoor_rl (int* p, int val)
return result;
}

inline int bsg_amoor_aqrl (int* p, int val)
inline int bsg_amoor_aqrl (volatile int* p, int val)
{
int result;
asm volatile ("amoor.w.aqrl %[result], %[val], 0(%[p])" \
Expand All @@ -74,7 +74,7 @@ inline int bsg_amoor_aqrl (int* p, int val)
return result;
}

inline int bsg_amoadd (int* p, int val)
inline int bsg_amoadd (volatile int* p, int val)
{
int result;
asm volatile ("amoadd.w %[result], %[val], 0(%[p])" \
Expand All @@ -83,7 +83,7 @@ inline int bsg_amoadd (int* p, int val)
return result;
}

inline int bsg_amoadd_aq (int* p, int val)
inline int bsg_amoadd_aq (volatile int* p, int val)
{
int result;
asm volatile ("amoadd.w.aq %[result], %[val], 0(%[p])" \
Expand All @@ -92,7 +92,7 @@ inline int bsg_amoadd_aq (int* p, int val)
return result;
}

inline int bsg_amoadd_rl (int* p, int val)
inline int bsg_amoadd_rl (volatile int* p, int val)
{
int result;
asm volatile ("amoadd.w.rl %[result], %[val], 0(%[p])" \
Expand All @@ -101,7 +101,7 @@ inline int bsg_amoadd_rl (int* p, int val)
return result;
}

inline int bsg_amoadd_aqrl (int* p, int val)
inline int bsg_amoadd_aqrl (volatile int* p, int val)
{
int result;
asm volatile ("amoadd.w.aqrl %[result], %[val], 0(%[p])" \
Expand Down
100 changes: 100 additions & 0 deletions software/bsg_manycore_lib/bsg_manycore_spsc_queue.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@

#ifndef _BSG_MANYCORE_SPSC_QUEUE_HPP
#define _BSG_MANYCORE_SPSC_QUEUE_HPP

#include <bsg_manycore_atomic.h>

template <typename T, int S>
class bsg_manycore_spsc_queue_recv {
private:
volatile T *buffer;
volatile int *count;
int rptr;

public:
bsg_manycore_spsc_queue_recv(T *buffer, int *count)
: buffer(buffer), count(count), rptr(0) { };

bool is_empty(void)
{
return *count == 0;
}

bool try_recv(T *data)
{
if (is_empty())
{
return false;
}

*data = buffer[rptr];
// Probably faster than modulo, but should see if compiler
// optimizes...
if (++rptr == S)
{
rptr = 0;
}
bsg_fence();
bsg_amoadd(count, -1);

return true;
}

// TODO: Add timeout?
T recv(void)
{
T data;
while (1)
{
if (try_recv(&data)) break;
}

return data;
}
};

template <typename T, int S>
class bsg_manycore_spsc_queue_send {
private:
volatile T *buffer;
volatile int *count;
int wptr;

public:
bsg_manycore_spsc_queue_send(T *buffer, int *count)
: buffer(buffer), count(count), wptr(0) { };

bool is_full(void)
{
return (*count == S);
}

bool try_send(T data)
{
if (is_full()) return false;

buffer[wptr] = data;
// Probably faster than modulo, but should see if compiler
// optimizes...
if (++wptr == S)
{
wptr = 0;
}
bsg_fence();
bsg_amoadd(count, 1);

return true;
}

// TODO: Add timeout?
void send(T data)
{
while (1)
{
if (try_send(data)) break;
}
}
};

#endif

15 changes: 15 additions & 0 deletions software/spmd/spsc_queue/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
bsg_tiles_X = 4
bsg_tiles_Y = 2

all: main.run

OBJECT_FILES := main.o

include ../Makefile.include

main.riscv: $(LINK_SCRIPT) $(OBJECT_FILES) $(SPMD_COMMON_OBJECTS) $(BSG_MANYCORE_LIB)
$(RISCV_LINK) $(filter %.o, $^) -L. "-l:$(BSG_MANYCORE_LIB)" -o $@ $(RISCV_LINK_OPTS)

main.o: Makefile

include $(BSG_MANYCORE_DIR)/software/mk/Makefile.tail_rules
68 changes: 68 additions & 0 deletions software/spmd/spsc_queue/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//This kernel performs a barrier among all tiles in tile group

#include "bsg_manycore.h"
#include "bsg_set_tile_x_y.h"
#include "bsg_manycore_spsc_queue.hpp"
#include "bsg_tile_group_barrier.hpp"

bsg_barrier<bsg_tiles_X, bsg_tiles_Y> barrier;

#define BUFFER_ELS 24
#define CHAIN_LEN 8
#define NUM_PACKETS 1000

int buffer_chain [CHAIN_LEN*BUFFER_ELS] __attribute__ ((section (".dram"))) = {0};
int buffer_count [CHAIN_LEN] __attribute__ ((section (".dram"))) = {0};

int main()
{
bsg_set_tile_x_y();

int *buffer = &buffer_chain[0] + (__bsg_id * BUFFER_ELS);
int *count = &buffer_count[0] + (__bsg_id);

int *next_buffer = &buffer_chain[0] + ((__bsg_id+1) * BUFFER_ELS);
int *next_count = &buffer_count[0] + (__bsg_id+1);

bsg_manycore_spsc_queue_recv<int, BUFFER_ELS> recv_spsc(buffer, count);
bsg_manycore_spsc_queue_send<int, BUFFER_ELS> send_spsc(next_buffer, next_count);

int packets = 0;
int recv_data;
int send_data;
do
{
if (__bsg_id == 0)
{
recv_data = packets;
}
else
{
recv_data = recv_spsc.recv();
}

//bsg_printf("[%d] RECV %d\n", __bsg_id, recv_data);

send_data = recv_data;

if (__bsg_id == CHAIN_LEN-1)
{
if (recv_data != packets)
{
bsg_fail();
}
}
else
{
send_spsc.send(send_data);
}

//bsg_printf("[%d] SEND %d\n", __bsg_id, send_data);
} while (++packets < NUM_PACKETS);

barrier.sync();
bsg_finish();
bsg_wait_while(1);
return 0;
}

17 changes: 17 additions & 0 deletions software/spmd/vcache_atomic_mixed/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
bsg_tiles_X = 1
bsg_tiles_Y = 1


all: main.run

OBJECT_FILES=main.o

include ../Makefile.include

main.riscv: $(LINK_SCRIPT) $(OBJECT_FILES) $(SPMD_COMMON_OBJECTS) $(BSG_MANYCORE_LIB) crt.o
$(RISCV_LINK) $(OBJECT_FILES) $(SPMD_COMMON_OBJECTS) -L. "-l:$(BSG_MANYCORE_LIB)" -o $@ $(RISCV_LINK_OPTS)


main.o: Makefile

include ../../mk/Makefile.tail_rules
28 changes: 28 additions & 0 deletions software/spmd/vcache_atomic_mixed/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "bsg_manycore.h"
#include "bsg_set_tile_x_y.h"
#include "bsg_manycore_atomic.h"

int lock __attribute__ ((section (".dram"))) = {0};

int main()
{

bsg_set_tile_x_y();

if (__bsg_id == 0)
{
// Using a regular int* here cause an illegal ordering resulting in:
// x = 1, y = 0, z = 1
//int* lock_ptr = &lock;
volatile int* lock_ptr = &lock;
int x = *lock_ptr;
int y = bsg_amoadd(lock_ptr, 1);
int z = *lock_ptr;

if (x != 0 || y != 0 || z != 1) bsg_fail();

bsg_finish();
}

bsg_wait_while(1);
}