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

feature: Add RISC-V Vector Intrinsic Examples for Nuclei RISC-V Processor #17

Merged
merged 2 commits into from
Dec 1, 2023
Merged
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
2 changes: 1 addition & 1 deletion evalsoc/mmudemo/npk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ codemanage:

## Build Configuration
buildconfig:
- type: gcc
- type: common
common_flags: # flags need to be combined together across all packages
- flags: ${app_commonflags}
ldflags:
Expand Down
64 changes: 64 additions & 0 deletions evalsoc/rvv_examples/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
*.i
*.o*
*.d*
*.elf*
*.diss*
*.dasm*
*.map*
*.bin*
*.log*
*.hex*
*.srec*
*.zip
*.pyc
.vscode

software/*/*.s

*.dump*
*.verilog*

*.swp*
*.swo*

prebuilt_tools/
setup_config.sh
setup_config.bat
setup_config.ps1

tags
ctags
TAGS
TAG
CTAGS
*_examples
*_labs
Makefile.local
Makefile.global

doc/build/
_build
__pycache__
*.pyc
logs*

gen/
tmp*/
Scratch*
scratch*
bitstream*
Backup*

usb_info.json
fpga_runner.yaml
*.back*
*.gcda
*.gcno
*.gcov

# IAR Embedded Workbench generated dirs/files
settings/
Debug/
Release/
*.dep
*.ewt
31 changes: 31 additions & 0 deletions evalsoc/rvv_examples/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
TARGET = rvv_example

NUCLEI_SDK_ROOT ?= ../../..

## Some case may fail due to isa not match
CASE ?= branch

# You can specify
# n900f/n900fd
# nx900f/nx900fd
CORE ?= nx900fd

# _zfh is added if F16 support is required
# When CORE is n900f/n900fd, ARCH_EXT should set to _zve32f_zfh
# When CORE is nx900f, ARCH_EXT should set to _zve64f_zfh
# When CORE is nx900fd, ARCH_EXT should set to v_zfh
ARCH_EXT ?= v_zfh

STDCLIB ?= newlib_small

SRCDIRS =

C_SRCS = rvv_$(CASE).c

INCDIRS = .

COMMON_FLAGS := -O0 -msave-restore

CLEAN_OBJS += *.o *.o.d

include $(NUCLEI_SDK_ROOT)/Build/Makefile.base
48 changes: 48 additions & 0 deletions evalsoc/rvv_examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# RISC-V Vector Examples For Nuclei SDK

These RISC-V Vector Examples are modified based on https://github.com/riscv-non-isa/rvv-intrinsic-doc/tree/main/examples
to make it works for Nuclei SDK evalsoc.

## Run in command line

You need to download Nuclei SDK >= 0.5.0 version.

* **CASE**: default `branch`, which is used to specify which rvv_${CASE}.c you want to run, if set to `sgemm`, it means `rvv_sgemm.c` case.


~~~shell
cd /path/to/nuclei-sdk
cd nuclei-board-labs/evalsoc/rvv_examples
# clone this repo to this folder
# assume you have clone or download it to rvv_examples
cd rvv_examples
# build it
# Assume environment is already setup, see https://doc.nucleisys.com/nuclei_sdk/quickstart.html
# Require Nuclei Studio 2023.10
make all
# run on qemu
make run_qemu
# run on hw
# require NX900FD with vector enabled bitstream
make upload
~~~

## Run in Nuclei Studio

> Nuclei Studio >= 2023.10 is required

You can download this NPK package from Nuclei Package Management or download this source code as zip, and import it.

![Import NPK](asserts/import_npk.png)

During the `New Nuclei RISC-V C/C++ Project` project wizard, select `Nuclei FPGA Evaluation SoC`, and select `sdk-nuclei_sdk @0.5.0`

![Select SDK in Project Wizard](asserts/wizard_select_sdk.png)

and then select `RISC-V Vector Examples` example, and choose one case in the choice `Vector Case`, and then create an example.

![Select RVV Case](asserts/wizard_select_rvv_case.png)

Then you can build it and run it in IDE.


Binary file added evalsoc/rvv_examples/asserts/import_npk.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
106 changes: 106 additions & 0 deletions evalsoc/rvv_examples/common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// common.h
// common utilities for the test code under exmaples/

#include <math.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

void gen_rand_1d(double *a, int n) {
for (int i = 0; i < n; ++i)
a[i] = (double)rand() / (double)RAND_MAX + (double)(rand() % 1000);
}

void gen_string(char *s, int n) {
// char value range: -128 ~ 127
for (int i = 0; i < n - 1; ++i)
s[i] = (char)(rand() % 127) + 1;
s[n - 1] = '\0';
}

void gen_rand_2d(double **ar, int n, int m) {
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
ar[i][j] = (double)rand() / (double)RAND_MAX + (double)(rand() % 1000);
}

void print_string(const char *a, const char *name) {
printf("const char *%s = \"", name);
int i = 0;
while (a[i] != 0)
putchar(a[i++]);
printf("\"\n");
puts("");
}

void print_array_1d(double *a, int n, const char *type, const char *name) {
printf("%s %s[%d] = {\n", type, name, n);
for (int i = 0; i < n; ++i) {
printf("%06.2f%s", a[i], i != n - 1 ? "," : "};\n");
if (i % 10 == 9)
puts("");
}
puts("");
}

void print_array_2d(double **a, int n, int m, const char *type,
const char *name) {
printf("%s %s[%d][%d] = {\n", type, name, n, m);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
printf("%06.2f", a[i][j]);
if (j == m - 1)
puts(i == n - 1 ? "};" : ",");
else
putchar(',');
}
}
puts("");
}

bool double_eq(double golden, double actual, double relErr) {
return (fabs(actual - golden) < relErr);
}

bool compare_1d(double *golden, double *actual, int n) {
for (int i = 0; i < n; ++i)
if (!double_eq(golden[i], actual[i], 1e-6))
return false;
return true;
}

bool compare_string(const char *golden, const char *actual, int n) {
for (int i = 0; i < n; ++i)
if (golden[i] != actual[i])
return false;
return true;
}

bool compare_2d(double **golden, double **actual, int n, int m) {
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
if (!double_eq(golden[i][j], actual[i][j], 1e-6))
return false;
return true;
}

double **alloc_array_2d(int n, int m) {
double **ret;
ret = (double **)malloc(sizeof(double *) * n);
for (int i = 0; i < n; ++i)
ret[i] = (double *)malloc(sizeof(double) * m);
return ret;
}

void init_array_one_1d(double *ar, int n) {
for (int i = 0; i < n; ++i)
ar[i] = 1;
}

void init_array_one_2d(double **ar, int n, int m) {
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
ar[i][j] = 1;
}
32 changes: 32 additions & 0 deletions evalsoc/rvv_examples/configs/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"run_config": {
"target" : "qemu",
"hardware" : {
"baudrate": 115200,
"timeout": 60
},
"qemu": {
"qemu32": "qemu-system-riscv32",
"qemu64": "qemu-system-riscv64",
"timeout": 60
}
},
"build_target": "clean all",
"build_config": {
"SOC": "evalsoc"
},
"checks": {
"PASS": ["pass"],
"FAIL": ["MEPC", "fail"]
},
"appdirs": [
"."
],
"appdirs_ignore": [
"nuclei_sdk",
"nuclei-sdk",
"application"
],
"appconfig": {
}
}
28 changes: 28 additions & 0 deletions evalsoc/rvv_examples/configs/hw.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"run_config": {
"target" : "hardware",
"hardware" : {
"baudrate": 115200,
"timeout": 60
},
"qemu": {
"qemu32": "qemu-system-riscv32",
"qemu64": "qemu-system-riscv64",
"timeout": 60
}
},
"build_configs": {
"branch" : {"CASE": "branch"},
"index" : {"CASE": "index"},
"matmul" : {"CASE": "matmul"},
"reduce" : {"CASE": "reduce"},
"saxpy" : {"CASE": "saxpy"},
"sgemm" : {"CASE": "sgemm"},
"strcmp" : {"CASE": "strcmp"},
"strcpy" : {"CASE": "strcpy"},
"strlen" : {"CASE": "strlen"},
"strncpy" : {"CASE": "strncpy"}
},
"expecteds" : {
}
}
Loading