OPAE HW full redesign - basic test passing

This commit is contained in:
Blaise Tine
2020-04-02 05:10:51 -04:00
parent 7b4b44e5ab
commit 7e4399e3ac
16 changed files with 844 additions and 903 deletions

View File

@@ -17,6 +17,9 @@ $(BUILD_DIR)/Makefile:
run-ase:
cd $(BUILD_DIR) && MENT_VSIM_OPT="-dpicpppath /usr/bin/gcc" make sim
wave:
vsim -view $(BUILD_DIR)/work/vsim.wlf -do wave.do
run-fpga:
# TODO

View File

@@ -108,7 +108,7 @@ module ccip_std_afu
#(
.NUM_LOCAL_MEM_BANKS(NUM_LOCAL_MEM_BANKS)
)
hello_mem_afu_inst
vortex_afu_inst
(
.clk (clk),
.SoftReset (reset_T1),

View File

@@ -1,5 +1,7 @@
vortex_afu.json
+define+GLOBAL_BLOCK_SIZE_BYTES=64
+incdir+.
+incdir+../../rtl
+incdir+../../rtl/shared_memory
@@ -13,6 +15,7 @@ vortex_afu.json
../../rtl/VX_define.v
../../rtl/VX_cache/VX_cache_config.v
../../rtl/Vortex_SOC.v
../../rtl/Vortex_Cluster.v
../../rtl/Vortex.v
../../rtl/VX_front_end.v
../../rtl/VX_back_end.v

View File

@@ -3,7 +3,19 @@
"afu-image": {
"power": 0,
"clock-frequency-high": "auto",
"clock-frequency-low": "auto",
"clock-frequency-low": "auto",
"mmio-csr-cmd": 10,
"mmio-csr-status": 12,
"mmio-csr-io-addr": 14,
"mmio-csr-mem-addr": 16,
"mmio-csr-data-size": 18,
"cmd-type-read": 1,
"cmd-type-write": 2,
"cmd-type-run": 3,
"cmd-type-snoop": 4,
"afu-top-interface":
{
"class": "ccip_std_afu_avalon_mm",

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
CXXFLAGS += -std=c++11 -O0 -g -Wall -Wextra -pedantic -Wfatal-errors
CXXFLAGS += -I../include -I/tools/opae/1.4.0/include
CXXFLAGS += -I../include -I/tools/opae/1.4.0/include -I../../../runtime
LDFLAGS += -L/tools/opae/1.4.0/lib
@@ -17,6 +17,8 @@ CXXFLAGS +=-fstack-protector
# Position independent code
CXXFLAGS += -fPIC
CXXFLAGS += -DGLOBAL_BLOCK_SIZE_BYTES=64
LDFLAGS += -luuid
LDFLAGS += -shared
@@ -50,7 +52,7 @@ $(PROJECT_ASE): $(SRCS) $(ASE_DIR)
$(CXX) $(CXXFLAGS) -DUSE_ASE $(SRCS) $(LDFLAGS) $(ASE_LIBS) -o $@
vortex.o: vortex.cpp $(AFU_JSON_INFO)
$(CC) $(CXXFLAGS) -c vortex.cpp -o $@
$(CXX) $(CXXFLAGS) -c vortex.cpp -o $@
$(ASE_DIR):
mkdir -p ase

View File

@@ -4,35 +4,35 @@
#include <unistd.h>
#include <assert.h>
#include <uuid/uuid.h>
#include <opae/fpga.h>
#include <vortex.h>
#include "vortex_afu.h"
// MMIO Address Mappings
#define MMIO_COPY_IO_ADDRESS 0X120
#define MMIO_COPY_AVM_ADDRESS 0x100
#define MMIO_COPY_DATA_SIZE 0X118
#define MMIO_CMD_TYPE 0X110
#define MMIO_READY_FOR_CMD 0X198
#define MMIO_CMD_TYPE_READ 0
#define MMIO_CMD_TYPE_WRITE 1
#define MMIO_CMD_TYPE_START 2
#define MMIO_CMD_TYPE_SNOOP 3
#define CHECK_RES(_expr) \
do { \
fpga_result res = _expr; \
if (res == FPGA_OK) \
break; \
printf("OPAE Error: '%s' returned %d!\n", #_expr, (int)res); \
printf("OPAE Error: '%s' returned %d, %s!\n", \
#_expr, (int)res, fpgaErrStr(res)); \
return -1; \
} while (false)
///////////////////////////////////////////////////////////////////////////////
#define CMD_TYPE_READ AFU_IMAGE_CMD_TYPE_READ
#define CMD_TYPE_WRITE AFU_IMAGE_CMD_TYPE_WRITE
#define CMD_TYPE_RUN AFU_IMAGE_CMD_TYPE_RUN
#define CMD_TYPE_SNOOP AFU_IMAGE_CMD_TYPE_SNOOP
#define MMIO_CSR_CMD (AFU_IMAGE_MMIO_CSR_CMD * 4)
#define MMIO_CSR_STATUS (AFU_IMAGE_MMIO_CSR_STATUS * 4)
#define MMIO_CSR_IO_ADDR (AFU_IMAGE_MMIO_CSR_IO_ADDR * 4)
#define MMIO_CSR_MEM_ADDR (AFU_IMAGE_MMIO_CSR_MEM_ADDR * 4)
#define MMIO_CSR_DATA_SIZE (AFU_IMAGE_MMIO_CSR_DATA_SIZE * 4)
///////////////////////////////////////////////////////////////////////////////
typedef struct vx_device_ {
fpga_handle fpga;
size_t mem_allocation;
@@ -42,7 +42,7 @@ typedef struct vx_buffer_ {
uint64_t wsid;
volatile void* host_ptr;
uint64_t io_addr;
fpga_handle fpga;
vx_device_h hdevice;
size_t size;
} vx_buffer_t;
@@ -53,10 +53,8 @@ static size_t align_size(size_t size) {
///////////////////////////////////////////////////////////////////////////////
// Search for an accelerator matching the requested UUID and connect to it
// Convert this to void if required as storing the fpga_handle to params variable
extern int vx_dev_open(vx_device_h* hdevice) {
fpga_properties filter = NULL;
fpga_properties filter = nullptr;
fpga_result res;
fpga_guid guid;
fpga_token accel_token;
@@ -64,11 +62,14 @@ extern int vx_dev_open(vx_device_h* hdevice) {
fpga_handle accel_handle;
vx_device_t* device;
if (NULL == hdevice)
if (nullptr == hdevice)
return -1;
// ensure that the block size 64
assert(64 == vx_dev_caps(VX_CAPS_CACHE_LINESIZE));
// Set up a filter that will search for an accelerator
fpgaGetProperties(NULL, &filter);
fpgaGetProperties(nullptr, &filter);
fpgaPropertiesSetObjectType(filter, FPGA_ACCELERATOR);
// Add the desired UUID to the filter
@@ -84,13 +85,13 @@ extern int vx_dev_open(vx_device_h* hdevice) {
if (num_matches < 1) {
fprintf(stderr, "Accelerator %s not found!\n", AFU_ACCEL_UUID);
return NULL;
return -1;
}
// Open accelerator
res = fpgaOpen(accel_token, &accel_handle, 0);
if (FPGA_OK != res) {
return NULL;
return -1;
}
// Done with token
@@ -98,9 +99,9 @@ extern int vx_dev_open(vx_device_h* hdevice) {
// allocate device object
device = (vx_device_t*)malloc(sizeof(vx_device_t));
if (NULL == device) {
if (nullptr == device) {
fpgaClose(accel_handle);
return NULL;
return -1;
}
device->fpga = accel_handle;
@@ -111,9 +112,8 @@ extern int vx_dev_open(vx_device_h* hdevice) {
return 0;
}
// Close the fpga when all the operations are done
extern int vx_dev_close(vx_device_h hdevice) {
if (NULL == hdevice)
if (nullptr == hdevice)
return -1;
vx_device_t *device = ((vx_device_t*)hdevice);
@@ -126,15 +126,15 @@ extern int vx_dev_close(vx_device_h hdevice) {
}
extern int vx_alloc_dev_mem(vx_device_h hdevice, size_t size, size_t* dev_maddr) {
if (NULL == hdevice
|| NULL == dev_maddr
if (nullptr == hdevice
|| nullptr == dev_maddr
|| 0 >= size)
return -1;
vx_device_t *device = ((vx_device_t*)hdevice);
size_t asize = align_size(size);
auto dev_mem_size = vx_dev_caps(VX_CAPS_LOCAL_MEM_SIZE);
size_t dev_mem_size = vx_dev_caps(VX_CAPS_LOCAL_MEM_SIZE);
if (device->mem_allocation + asize > dev_mem_size)
return -1;
@@ -151,9 +151,9 @@ extern int vx_alloc_shared_mem(vx_device_h hdevice, size_t size, vx_buffer_h* hb
uint64_t io_addr;
vx_buffer_t* buffer;
if (NULL == hdevice
if (nullptr == hdevice
|| 0 >= size
|| NULL == hbuffer)
|| nullptr == hbuffer)
return -1;
vx_device_t *device = ((vx_device_t*)hdevice);
@@ -174,7 +174,7 @@ extern int vx_alloc_shared_mem(vx_device_h hdevice, size_t size, vx_buffer_h* hb
// allocate buffer object
buffer = (vx_buffer_t*)malloc(sizeof(vx_buffer_t));
if (NULL == buffer) {
if (nullptr == buffer) {
fpgaReleaseBuffer(device->fpga, wsid);
return -1;
}
@@ -182,7 +182,7 @@ extern int vx_alloc_shared_mem(vx_device_h hdevice, size_t size, vx_buffer_h* hb
buffer->wsid = wsid;
buffer->host_ptr = host_ptr;
buffer->io_addr = io_addr;
buffer->fpga = device->fpga;
buffer->hdevice = hdevice;
buffer->size = size;
*hbuffer = buffer;
@@ -191,136 +191,30 @@ extern int vx_alloc_shared_mem(vx_device_h hdevice, size_t size, vx_buffer_h* hb
}
extern volatile void* vx_host_ptr(vx_buffer_h hbuffer) {
if (nullptr == hbuffer)
return nullptr;
vx_buffer_t* buffer = ((vx_buffer_t*)hbuffer);
if (NULL == buffer)
return NULL;
return buffer->host_ptr;
}
extern int vx_buf_release(vx_buffer_h hbuffer) {
vx_buffer_t* buffer = ((vx_buffer_t*)hbuffer);
if (NULL == buffer)
if (nullptr == hbuffer)
return -1;
fpgaReleaseBuffer(buffer->fpga, buffer->wsid);
vx_buffer_t* buffer = ((vx_buffer_t*)hbuffer);
vx_device_t *device = ((vx_device_t*)buffer->hdevice);
fpgaReleaseBuffer(device->fpga, buffer->wsid);
free(buffer);
return 0;
}
// Check if HW is ready for SW
static int ready_for_sw(fpga_handle hdevice) {
uint64_t data = 0;
struct timespec sleep_time;
#ifdef USE_ASE
sleep_time.tv_sec = 1;
sleep_time.tv_nsec = 0;
#else
sleep_time.tv_sec = 0;
sleep_time.tv_nsec = 1000000;
#endif
do {
CHECK_RES(fpgaReadMMIO64(hdevice, 0, MMIO_READY_FOR_CMD, &data));
nanosleep(&sleep_time, NULL);
} while (data != 0x1);
return 0;
}
extern int vx_copy_to_dev(vx_buffer_h hbuffer, size_t dev_maddr, size_t size, size_t src_offset) {
if (NULL == hbuffer
|| 0 >= size)
return -1;
vx_buffer_t* buffer = ((vx_buffer_t*)hbuffer);
// bound checking
if (size + src_offset > buffer->size)
return -1;
// Ensure ready for new command
if (ready_for_sw(buffer->fpga) != 0)
return -1;
CHECK_RES(fpgaWriteMMIO64(buffer->fpga, 0, MMIO_COPY_AVM_ADDRESS, dev_maddr));
CHECK_RES(fpgaWriteMMIO64(buffer->fpga, 0, MMIO_COPY_IO_ADDRESS, buffer->io_addr + src_offset);
CHECK_RES(fpgaWriteMMIO64(buffer->fpga, 0, MMIO_COPY_DATA_SIZE, size));
CHECK_RES(fpgaWriteMMIO64(buffer->fpga, 0, MMIO_CMD_TYPE, MMIO_CMD_TYPE_WRITE));
// Wait for the write operation to finish
return ready_for_sw(buffer->fpga);
}
extern int vx_copy_from_dev(vx_buffer_h hbuffer, size_t dev_maddr, size_t size, size_t dest_offset) {
if (NULL == hbuffer
|| 0 >= size)
return -1;
vx_buffer_t* buffer = ((vx_buffer_t*)hbuffer);
// bound checking
if (size + dest_offset > buffer->size)
return -1;
// Ensure ready for new command
if (ready_for_sw(buffer->fpga) != 0)
return -1;
CHECK_RES(fpgaWriteMMIO64(buffer->fpga, 0, MMIO_COPY_AVM_ADDRESS, dev_maddr));
CHECK_RES(fpgaWriteMMIO64(buffer->fpga, 0, MMIO_COPY_IO_ADDRESS, buffer->io_addr + dest_offset);
CHECK_RES(fpgaWriteMMIO64(buffer->fpga, 0, MMIO_COPY_DATA_SIZE, size));
CHECK_RES(fpgaWriteMMIO64(buffer->fpga, 0, MMIO_CMD_TYPE, MMIO_CMD_TYPE_READ));
// Wait for the write operation to finish
return ready_for_sw(buffer->fpga);
}
extern int vx_flush_caches(vx_device_h hdevice, size_t dev_maddr, size_t size) {
if (NULL == hbuffer
|| 0 >= size)
return -1;
vx_buffer_t* buffer = ((vx_buffer_t*)hbuffer);
// bound checking
if (size + src_offset > buffer->size)
return -1;
// Ensure ready for new command
if (ready_for_sw(buffer->fpga) != 0)
return -1;
CHECK_RES(fpgaWriteMMIO64(buffer->fpga, 0, MMIO_COPY_AVM_ADDRESS, dev_maddr));
CHECK_RES(fpgaWriteMMIO64(buffer->fpga, 0, MMIO_COPY_IO_ADDRESS, (buffer->io_addr + src_offset)/VX_CACHE_LINESIZE));
CHECK_RES(fpgaWriteMMIO64(buffer->fpga, 0, MMIO_COPY_DATA_SIZE, size));
CHECK_RES(fpgaWriteMMIO64(buffer->fpga, 0, MMIO_CMD_TYPE, MMIO_CMD_TYPE_SNOOP));
// Wait for the write operation to finish
return ready_for_sw(buffer->fpga);
return 0;
}
extern int vx_start(vx_device_h hdevice) {
if (NULL == hdevice)
return -1;
vx_device_t *device = ((vx_device_t*)hdevice);
// Ensure ready for new command
if (ready_for_sw(device->fpga) != 0)
return -1;
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CMD_TYPE, MMIO_CMD_TYPE_START));
return 0;
}
extern int vx_ready_wait(vx_device_h hdevice, long long timeout) {
if (NULL == hdevice)
if (nullptr == hdevice)
return -1;
vx_device_t *device = ((vx_device_t*)hdevice);
@@ -328,7 +222,7 @@ extern int vx_ready_wait(vx_device_h hdevice, long long timeout) {
uint64_t data = 0;
struct timespec sleep_time;
#ifdef USE_ASE
#if defined(USE_ASE)
sleep_time.tv_sec = 1;
sleep_time.tv_nsec = 0;
#else
@@ -339,13 +233,106 @@ extern int vx_ready_wait(vx_device_h hdevice, long long timeout) {
// to milliseconds
long long sleep_time_ms = (sleep_time.tv_sec * 1000) + (sleep_time.tv_nsec / 1000000);
do {
CHECK_RES(fpgaReadMMIO64(device->fpga, 0, MMIO_READY_FOR_CMD, &data));
nanosleep(&sleep_time, NULL);
sleep_time_ms -= sleep_time_ms;
if (timeout <= sleep_time_ms)
for (;;) {
CHECK_RES(fpgaReadMMIO64(device->fpga, 0, MMIO_CSR_STATUS, &data));
if (0 == data || 0 == timeout)
break;
} while (data != 0x1);
nanosleep(&sleep_time, nullptr);
timeout -= sleep_time_ms;
};
return 0;
}
extern int vx_copy_to_dev(vx_buffer_h hbuffer, size_t dev_maddr, size_t size, size_t src_offset) {
if (nullptr == hbuffer
|| 0 >= size)
return -1;
vx_buffer_t* buffer = ((vx_buffer_t*)hbuffer);
vx_device_t *device = ((vx_device_t*)buffer->hdevice);
// bound checking
if (size + src_offset > buffer->size)
return -1;
// Ensure ready for new command
if (vx_ready_wait(buffer->hdevice, -1) != 0)
return -1;
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_IO_ADDR, buffer->io_addr + src_offset));
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_MEM_ADDR, dev_maddr));
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_DATA_SIZE, size));
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_CMD, CMD_TYPE_WRITE));
// Wait for the write operation to finish
if (vx_ready_wait(buffer->hdevice, -1) != 0)
return -1;
return 0;
}
extern int vx_copy_from_dev(vx_buffer_h hbuffer, size_t dev_maddr, size_t size, size_t dest_offset) {
if (nullptr == hbuffer
|| 0 >= size)
return -1;
vx_buffer_t* buffer = ((vx_buffer_t*)hbuffer);
vx_device_t *device = ((vx_device_t*)buffer->hdevice);
// bound checking
if (size + dest_offset > buffer->size)
return -1;
// Ensure ready for new command
if (vx_ready_wait(buffer->hdevice, -1) != 0)
return -1;
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_IO_ADDR, buffer->io_addr + dest_offset));
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_MEM_ADDR, dev_maddr));
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_DATA_SIZE, size));
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_CMD, CMD_TYPE_READ));
// Wait for the write operation to finish
if (vx_ready_wait(buffer->hdevice, -1) != 0)
return -1;
return 0;
}
extern int vx_flush_caches(vx_device_h hdevice, size_t dev_maddr, size_t size) {
if (nullptr == hdevice
|| 0 >= size)
return -1;
vx_device_t* device = ((vx_device_t*)hdevice);
// Ensure ready for new command
if (vx_ready_wait(hdevice, -1) != 0)
return -1;
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_MEM_ADDR, dev_maddr));
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_DATA_SIZE, size));
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_CMD, CMD_TYPE_SNOOP));
// Wait for the write operation to finish
if (vx_ready_wait(hdevice, -1) != 0)
return -1;
return 0;
}
extern int vx_start(vx_device_h hdevice) {
if (nullptr == hdevice)
return -1;
vx_device_t *device = ((vx_device_t*)hdevice);
// Ensure ready for new command
if (vx_ready_wait(hdevice, -1) != 0)
return -1;
CHECK_RES(fpgaWriteMMIO64(device->fpga, 0, MMIO_CSR_CMD, CMD_TYPE_RUN));
return 0;
}

View File

@@ -11,17 +11,6 @@
#include <ram.h>
#include <simulator.h>
#define PAGE_SIZE 4096
#define CHECK_RES(_expr) \
do { \
fpga_result res = _expr; \
if (res == FPGA_OK) \
break; \
printf("OPAE Error: '%s' returned %d!\n", #_expr, (int)res); \
return -1; \
} while (false)
///////////////////////////////////////////////////////////////////////////////
static size_t align_size(size_t size) {
@@ -197,7 +186,7 @@ private:
///////////////////////////////////////////////////////////////////////////////
extern int vx_dev_open(vx_device_h* hdevice) {
if (NULL == hdevice)
if (nullptr == hdevice)
return -1;
*hdevice = new vx_device();
@@ -217,8 +206,8 @@ extern int vx_dev_close(vx_device_h hdevice) {
}
extern int vx_alloc_dev_mem(vx_device_h hdevice, size_t size, size_t* dev_maddr) {
if (NULL == hdevice
|| NULL == dev_maddr
if (nullptr == hdevice
|| nullptr == dev_maddr
|| 0 >= size)
return -1;
@@ -227,7 +216,7 @@ extern int vx_alloc_dev_mem(vx_device_h hdevice, size_t size, size_t* dev_maddr)
}
extern int vx_flush_caches(vx_device_h hdevice, size_t dev_maddr, size_t size) {
if (NULL == hdevice
if (nullptr == hdevice
|| 0 >= size)
return -1;
@@ -240,7 +229,7 @@ extern int vx_flush_caches(vx_device_h hdevice, size_t dev_maddr, size_t size) {
extern int vx_alloc_shared_mem(vx_device_h hdevice, size_t size, vx_buffer_h* hbuffer) {
if (nullptr == hdevice
|| 0 >= size
|| NULL == hbuffer)
|| nullptr == hbuffer)
return -1;
vx_device *device = ((vx_device*)hdevice);

View File

@@ -1,7 +1,7 @@
CFLAGS += -std=c++11 -O3 -Wall -Wextra -pedantic -Wfatal-errors
#CFLAGS += -std=c++11 -g -O0 -Wall -Wextra -pedantic -Wfatal-errors
CFLAGS += -I../../include -I../../../../simX/include -I../../../../runtime
CFLAGS += -I../../include -I../../../../simX/include -I../../../../runtime
CFLAGS += -fPIC

View File

@@ -13,15 +13,6 @@
#define PAGE_SIZE 4096
#define CHECK_RES(_expr) \
do { \
fpga_result res = _expr; \
if (res == FPGA_OK) \
break; \
printf("OPAE Error: '%s' returned %d!\n", #_expr, (int)res); \
return -1; \
} while (false)
///////////////////////////////////////////////////////////////////////////////
static size_t align_size(size_t size) {
@@ -206,7 +197,7 @@ private:
///////////////////////////////////////////////////////////////////////////////
extern int vx_dev_open(vx_device_h* hdevice) {
if (NULL == hdevice)
if (nullptr == hdevice)
return -1;
*hdevice = new vx_device();
@@ -226,8 +217,8 @@ extern int vx_dev_close(vx_device_h hdevice) {
}
extern int vx_alloc_dev_mem(vx_device_h hdevice, size_t size, size_t* dev_maddr) {
if (NULL == hdevice
|| NULL == dev_maddr
if (nullptr == hdevice
|| nullptr == dev_maddr
|| 0 >= size)
return -1;
@@ -236,7 +227,7 @@ extern int vx_alloc_dev_mem(vx_device_h hdevice, size_t size, size_t* dev_maddr)
}
extern int vx_flush_caches(vx_device_h hdevice, size_t /*dev_maddr*/, size_t size) {
if (NULL == hdevice
if (nullptr == hdevice
|| 0 >= size)
return -1;
// this functionality is not need by simX
@@ -246,7 +237,7 @@ extern int vx_flush_caches(vx_device_h hdevice, size_t /*dev_maddr*/, size_t siz
extern int vx_alloc_shared_mem(vx_device_h hdevice, size_t size, vx_buffer_h* hbuffer) {
if (nullptr == hdevice
|| 0 >= size
|| NULL == hbuffer)
|| nullptr == hbuffer)
return -1;
vx_device *device = ((vx_device*)hdevice);

View File

@@ -18,7 +18,7 @@ run-fpga: $(PROJECT)
LD_LIBRARY_PATH=../../sw/opae:$(LD_LIBRARY_PATH) ./$(PROJECT)
run-ase: $(PROJECT)
LD_LIBRARY_PATH=../../sw/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT)
LIBOPAE_LOG=1 LD_LIBRARY_PATH=../../sw/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT)
run-rtlsim: $(PROJECT)
LD_LIBRARY_PATH=../../sw/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT)

Binary file not shown.

View File

@@ -1,6 +1,4 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <iostream>
#include <unistd.h>
#include <vortex.h>
@@ -9,8 +7,8 @@ static void parse_args(int argc, char **argv) {
while ((c = getopt(argc, argv, "?")) != -1) {
switch (c) {
case '?': {
printf("Test.\n");
printf("Usage: [-h: help]\n");
std::cout << "Test." << std::endl;
std::cout << "Usage: [-h: help]" << std::endl;
exit(0);
} break;
default:
@@ -20,12 +18,17 @@ static void parse_args(int argc, char **argv) {
}
uint64_t shuffle(int i, uint64_t value) {
return (value << i) | (value & ((1 << i)-1));;
//return (value << i) | (value & ((1 << i)-1));;
return 0x0badf00ddeadbeef;
}
int run_test(vx_buffer_h sbuf, vx_buffer_h dbuf, uint32_t address, uint64_t value, int num_blocks) {
int err;
int num_failures = 0;
int run_test(vx_buffer_h sbuf,
vx_buffer_h dbuf,
uint32_t address,
uint64_t value,
int num_blocks) {
int ret;
int errors = 0;
// write sbuf data
for (int i = 0; i < 8 * num_blocks; ++i) {
@@ -33,75 +36,114 @@ int run_test(vx_buffer_h sbuf, vx_buffer_h dbuf, uint32_t address, uint64_t valu
}
// write buffer to local memory
err = vx_copy_to_dev(sbuf, address, 64 * num_blocks, 0);
if (err != 0)
return -1;
std::cout << "write buffer to local memory" << std::endl;
ret = vx_copy_to_dev(sbuf, address, 64 * num_blocks, 0);
if (ret != 0)
return ret;
// read buffer from local memory
err = vx_copy_from_dev(dbuf, address, 64 * num_blocks, 0);
if (err != 0)
return -1;
std::cout << "read buffer from local memory" << std::endl;
ret = vx_copy_from_dev(dbuf, address, 64 * num_blocks, 0);
if (ret != 0)
return ret;
// verify result
std::cout << "verify result" << std::endl;
for (int i = 0; i < 8 * num_blocks; ++i) {
auto curr = ((uint64_t*)vx_host_ptr(dbuf))[i];
auto ref = shuffle(i, value);
if (curr != ref) {
printf("error @ %x: actual %ld, expected %ld\n", address + 64 * i, curr, ref);
++num_failures;
std::cout << "error @ " << std::hex << (address + 64 * i)
<< ": actual " << curr << ", expected " << ref << std::endl;
++errors;
}
}
return num_failures;
if (errors != 0) {
std::cout << "Found " << errors << " errors!" << std::endl;
std::cout << "FAILED!" << std::endl;
return 1;
}
return 0;
}
vx_device_h device = nullptr;
vx_buffer_h sbuf = nullptr;
vx_buffer_h dbuf = nullptr;
void cleanup() {
if (sbuf) {
vx_buf_release(sbuf);
}
if (dbuf) {
vx_buf_release(dbuf);
}
if (device) {
vx_dev_close(device);
}
}
int main(int argc, char *argv[]) {
int err;
int num_failures = 0;
int ret;
// parse command arguments
parse_args(argc, argv);
// open device connection
std::cout << "open device connection" << std::endl;
vx_device_h device;
err = vx_dev_open(&device);
if (err != 0)
return -1;
ret = vx_dev_open(&device);
if (ret != 0)
return ret;
// create source buffer
vx_buffer_h sbuf;
err = vx_alloc_shared_mem(device, 4096, &sbuf);
if (err != 0) {
vx_dev_close(device);
return -1;
std::cout << "create source buffer" << std::endl;
ret = vx_alloc_shared_mem(device, 4096, &sbuf);
if (ret != 0) {
cleanup();
return ret;
}
// create destination buffer
vx_buffer_h dbuf;
err = vx_alloc_shared_mem(device, 4096, &dbuf);
if (err != 0) {
vx_buf_release(sbuf);
vx_dev_close(device);
return -1;
std::cout << "create destination buffer" << std::endl;
ret = vx_alloc_shared_mem(device, 4096, &dbuf);
if (ret != 0) {
cleanup();
return ret;
}
// run tests
num_failures += run_test(sbuf, dbuf, 0x10000000, 0x0badf00d00ff00ff, 1);
num_failures += run_test(sbuf, dbuf, 0x10000000, 0x0badf00d00ff00ff, 2);
num_failures += run_test(sbuf, dbuf, 0x20000000, 0xff00ff00ff00ff00, 4);
num_failures += run_test(sbuf, dbuf, 0x20000000, 0x0badf00d40ff40ff, 8);
// releae buffers
vx_buf_release(sbuf);
vx_buf_release(dbuf);
// close device
vx_dev_close(device);
if (0 == num_failures) {
printf("Test PASSED\n");
} else {
printf("Test FAILED\n");
std::cout << "run tests" << std::endl;
ret = run_test(sbuf, dbuf, 0x10000000, 0x0badf00d00ff00ff, 1);
if (ret != 0) {
cleanup();
return ret;
}
return num_failures;
ret = run_test(sbuf, dbuf, 0x10000000, 0x0badf00d00ff00ff, 2);
if (ret != 0) {
cleanup();
return ret;
}
ret = run_test(sbuf, dbuf, 0x20000000, 0xff00ff00ff00ff00, 4);
if (ret != 0) {
cleanup();
return ret;
}
ret = run_test(sbuf, dbuf, 0x20000000, 0x0badf00d40ff40ff, 8);
if (ret != 0) {
cleanup();
return ret;
}
// cleanup
std::cout << "cleanup" << std::endl;
cleanup();
std::cout << "Test PASSED" << std::endl;
return 0;
}

View File

@@ -46,7 +46,7 @@ run-fpga: $(PROJECT)
LD_LIBRARY_PATH=../../sw/opae:$(LD_LIBRARY_PATH) ./$(PROJECT) -f kernel.bin -n 16
run-ase: $(PROJECT)
LD_LIBRARY_PATH=../../sw/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT) -f kernel.bin -n 16
LIBOPAE_LOG=1 LD_LIBRARY_PATH=../../sw/opae/ase:$(LD_LIBRARY_PATH) ./$(PROJECT) -f kernel.bin -n 16
run-rtlsim: $(PROJECT)
LD_LIBRARY_PATH=../../sw/rtlsim:$(LD_LIBRARY_PATH) ./$(PROJECT) -f kernel.bin -n 16

Binary file not shown.

View File

@@ -1,6 +1,5 @@
#include <iostream>
#include <unistd.h>
#include <unistd.h>
#include <string.h>
#include <vortex.h>
#include "common.h"
@@ -40,21 +39,77 @@ static void parse_args(int argc, char **argv) {
}
}
vx_device_h device;
vx_buffer_h buffer;
int run_test(vx_device_h device,
vx_buffer_h buffer,
const kernel_arg_t& kernel_arg,
uint32_t buf_size,
uint32_t num_points) {
int ret;
// start device
std::cout << "start device" << std::endl;
ret = vx_start(device);
if (ret != 0) {
return ret;
}
// wait for completion
std::cout << "wait for completion" << std::endl;
ret = vx_ready_wait(device, -1);
if (ret != 0) {
return ret;
}
// flush the destination buffer caches
std::cout << "flush the destination buffer caches" << std::endl;
ret = vx_flush_caches(device, kernel_arg.dst_ptr, buf_size);
if (ret != 0) {
return ret;
}
// download destination buffer
std::cout << "download destination buffer" << std::endl;
ret = vx_copy_from_dev(buffer, kernel_arg.dst_ptr, buf_size, 0);
if (ret != 0) {
return ret;
}
// verify result
std::cout << "verify result" << std::endl;
{
int errors = 0;
auto buf_ptr = (int*)vx_host_ptr(buffer);
for (uint32_t i = 0; i < num_points; ++i) {
int ref = i * i;
int cur = buf_ptr[i];
if (cur != ref) {
++errors;
}
}
if (errors != 0) {
std::cout << "Found " << errors << " errors!" << std::endl;
std::cout << "FAILED!" << std::endl;
return 1;
}
}
return 0;
}
vx_device_h device = nullptr;
vx_buffer_h buffer = nullptr;
void cleanup() {
if (device) {
vx_dev_close(device);
}
if (buffer) {
vx_buf_release(buffer);
}
if (device) {
vx_dev_close(device);
}
}
int main(int argc, char *argv[]) {
int ret;
int errors = 0;
size_t value;
kernel_arg_t kernel_arg;
@@ -79,14 +134,14 @@ int main(int argc, char *argv[]) {
std::cout << "open device connection" << std::endl;
ret = vx_dev_open(&device);
if (ret != 0)
return -1;
return ret;
// upload program
std::cout << "upload program" << std::endl;
ret = vx_upload_kernel_file(device, program_file);
if (ret != 0) {
cleanup();
return -1;
return ret;
}
// allocate device memory
@@ -95,21 +150,21 @@ int main(int argc, char *argv[]) {
ret = vx_alloc_dev_mem(device, buf_size, &value);
if (ret != 0) {
cleanup();
return -1;
return ret;
}
kernel_arg.src0_ptr = value;
ret = vx_alloc_dev_mem(device, buf_size, &value);
if (ret != 0) {
cleanup();
return -1;
return ret;
}
kernel_arg.src1_ptr = value;
ret = vx_alloc_dev_mem(device, buf_size, &value);
if (ret != 0) {
cleanup();
return -1;
return ret;
}
kernel_arg.dst_ptr = value;
@@ -119,7 +174,7 @@ int main(int argc, char *argv[]) {
ret = vx_alloc_shared_mem(device, alloc_size, &buffer);
if (ret != 0) {
cleanup();
return -1;
return ret;
}
// populate source buffer values
@@ -137,13 +192,13 @@ int main(int argc, char *argv[]) {
ret = vx_copy_to_dev(buffer, kernel_arg.src0_ptr, buf_size, 0);
if (ret != 0) {
cleanup();
return -1;
return ret;
}
ret = vx_copy_to_dev(buffer, kernel_arg.src1_ptr, buf_size, 0);
if (ret != 0) {
cleanup();
return -1;
return ret;
}
// upload kernel argument
@@ -158,117 +213,29 @@ int main(int argc, char *argv[]) {
ret = vx_copy_to_dev(buffer, KERNEL_ARG_DEV_MEM_ADDR, sizeof(kernel_arg_t), 0);
if (ret != 0) {
cleanup();
return -1;
return ret;
}
}
// start device
std::cout << "start device" << std::endl;
ret = vx_start(device);
// run tests
std::cout << "run tests" << std::endl;
ret = run_test(device, buffer, kernel_arg, buf_size, num_points);
if (ret != 0) {
cleanup();
return -1;
return ret;
}
// wait for completion
std::cout << "wait for completion" << std::endl;
ret = vx_ready_wait(device, -1);
ret = run_test(device, buffer, kernel_arg, buf_size, num_points);
if (ret != 0) {
cleanup();
return -1;
}
// flush the destination buffer caches
std::cout << "flush the destination buffer caches" << std::endl;
ret = vx_flush_caches(device, kernel_arg.dst_ptr, buf_size);
if (ret != 0) {
cleanup();
return -1;
}
// download destination buffer
std::cout << "download destination buffer" << std::endl;
ret = vx_copy_from_dev(buffer, kernel_arg.dst_ptr, buf_size, 0);
if (ret != 0) {
cleanup();
return -1;
}
// verify result
std::cout << "verify result" << std::endl;
{
auto buf_ptr = (int*)vx_host_ptr(buffer);
for (uint32_t i = 0; i < num_points; ++i) {
int ref = i * i;
int cur = buf_ptr[i];
if (cur != ref) {
++errors;
}
}
}
if (errors != 0) {
printf("Found %d errors!\n", errors);
printf("FAILED!\n");
cleanup();
return -1;
}
// start device
std::cout << "start device" << std::endl;
ret = vx_start(device);
if (ret != 0) {
cleanup();
return -1;
}
// wait for completion
std::cout << "wait for completion" << std::endl;
ret = vx_ready_wait(device, -1);
if (ret != 0) {
cleanup();
return -1;
}
// flush the destination buffer caches
std::cout << "flush the destination buffer caches" << std::endl;
ret = vx_flush_caches(device, kernel_arg.dst_ptr, buf_size);
if (ret != 0) {
cleanup();
return -1;
}
// download destination buffer
std::cout << "download destination buffer" << std::endl;
ret = vx_copy_from_dev(buffer, kernel_arg.dst_ptr, buf_size, 0);
if (ret != 0) {
cleanup();
return -1;
}
// verify result
std::cout << "verify result" << std::endl;
{
auto buf_ptr = (int*)vx_host_ptr(buffer);
for (uint32_t i = 0; i < num_points; ++i) {
int ref = i * i;
int cur = buf_ptr[i];
if (cur != ref) {
++errors;
}
}
return ret;
}
// cleanup
std::cout << "cleanup" << std::endl;
cleanup();
if (0 == errors) {
printf("PASSED!\n");
} else {
printf("Found %d errors!\n", errors);
printf("FAILED!\n");
}
std::cout << "PASSED!" << std::endl;
return errors;
return 0;
}