Skip to content

Automate prebuilt executable updates via GitHub Actions #474

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

Merged
merged 25 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from 8 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
6 changes: 3 additions & 3 deletions .ci/gdbstub-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ if [ -z ${GDB} ]; then
exit 1
fi

build/rv32emu -g build/puzzle.elf &
build/rv32emu -g build/bin/riscv32/puzzle &
PID=$!

# Before starting GDB, we should ensure rv32emu is still running.
Expand All @@ -31,9 +31,9 @@ fi

OPTS=
tmpfile=/tmp/rv32emu-gdbstub.$PID
breakpoints=(0x10700 0x10800 0x10900)
breakpoints=(0x10500 0x10600 0x10700)
bkpt_count=${#breakpoints[@]}
OPTS+="-ex 'file build/puzzle.elf' "
OPTS+="-ex 'file build/bin/riscv32/puzzle' "
OPTS+="-ex 'target remote :1234' "
for t in ${breakpoints[@]}; do
OPTS+="-ex 'break *$t' "
Expand Down
61 changes: 61 additions & 0 deletions .github/workflows/build-testbenches.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Build testbenches

on:
push:
branches:
- master
workflow_dispatch:

env:
CROSS_CC_PREFIX: riscv-none-elf-
CROSS_CC_URL: https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v14.2.0-1/xpack-riscv-none-elf-gcc-14.2.0-1-linux-x64.tar.gz

jobs:
build-testbenches:
runs-on: ubuntu-20.04
steps:
- name: Install essential packages
run: |
sudo apt-get update -q -y
sudo apt-get upgrade -q -y
sudo apt-get install -q -y gcc-multilib g++-multilib
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: 'true'
- name: Test changed files
id: file-changed
uses: tj-actions/changed-files@v44
with:
fetch_additional_submodule_history: 'true'
files: |
tests/ansibench/*
tests/rv8-bench/*
tests/*.c
- name: Fetch xPack RISC-V GNU toolchain
if: ${{ steps.file-changed.outputs.any_changed == 'true' || github.event_name == 'workflow_dispatch' }}
run: |
mkdir -p /opt/riscv-gnu-toolchain
wget -O - $CROSS_CC_URL | tar -zxf - --strip-components=1 -C /opt/riscv-gnu-toolchain
echo "/opt/riscv-gnu-toolchain/bin" >> $GITHUB_PATH
echo "CROSS_CC=/opt/riscv-gnu-toolchain/bin/$CROSS_CC_PREFIX""gcc" >> $GITHUB_ENV
- name: Build RISC-V executables
if: ${{ steps.file-changed.outputs.any_changed == 'true' || github.event_name == 'workflow_dispatch' }}
run: |
CROSS_CC=$CROSS_CC USE_PREBUILT=0 make build-testbenches
- name: Create tarballs
if: ${{ steps.file-changed.outputs.any_changed == 'true' || github.event_name == 'workflow_dispatch' }}
run: |
tar -zcf rv32emu-prebuilt.tar.gz -C build bin
- name: Create GitHub Release
if: ${{ steps.file-changed.outputs.any_changed == 'true' || github.event_name == 'workflow_dispatch' }}
env:
GH_TOKEN: ${{ secrets.RV32EMU_PREBUILT_TOKEN }}
run: |
RELEASE_TAG=$(date +'%Y.%m.%d')
gh release create $RELEASE_TAG \
--repo sysprog21/rv32emu-prebuilt \
--title "$RELEASE_TAG""-nightly"
gh release upload $RELEASE_TAG \
rv32emu-prebuilt.tar.gz \
--repo sysprog21/rv32emu-prebuilt
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ build/softfloat
build/cache/
build/map/
build/path/
build/bin/
*.o
*.o.d
tests/**/*.elf
Expand Down
8 changes: 8 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,11 @@
url = https://github.com/sysprog21/berkeley-softfloat-3
branch = rv32emu
shallow = true
[submodule "tests/ansibench"]
path = tests/ansibench
url = https://github.com/sysprog21/ansibench
shallow = true
[submodule "tests/rv8-bench"]
path = tests/rv8-bench
url = https://github.com/sysprog21/rv8-bench
shallow = true
25 changes: 12 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ $(OUT)/emulate.o: CFLAGS += -foptimize-sibling-calls -fomit-frame-pointer -fno-s
.DEFAULT_GOAL := all

include mk/external.mk

include mk/benchmark.mk
include mk/wasm.mk

all: config $(BIN)
Expand Down Expand Up @@ -229,36 +229,35 @@ tool: $(TOOLS_BIN)
include mk/riscv-arch-test.mk
include mk/tests.mk

CHECK_ELF_FILES := \
hello \
puzzle \
fcalc
# the prebuilt executables are built for "rv32im"
CHECK_ELF_FILES :=

ifeq ($(call has, EXT_M), 1)
CHECK_ELF_FILES += \
puzzle \
fcalc \
pi
endif

EXPECTED_hello = Hello World!
EXPECTED_puzzle = success in 2005 trials
EXPECTED_fcalc = Performed 12 tests, 0 failures, 100% success rate.
EXPECTED_pi = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086

check: $(BIN)
check: $(BIN) build-testbenches
$(Q)$(foreach e,$(CHECK_ELF_FILES),\
$(PRINTF) "Running $(e).elf ... "; \
if [ "$(shell $(BIN) $(OUT)/$(e).elf | uniq)" = "$(strip $(EXPECTED_$(e))) inferior exit code 0" ]; then \
$(PRINTF) "Running $(e) ... "; \
if [ "$(shell $(BIN) $(OUT)/bin/riscv32/$(e) | uniq)" = "$(strip $(EXPECTED_$(e))) inferior exit code 0" ]; then \
$(call notice, [OK]); \
else \
$(PRINTF) "Failed.\n"; \
exit 1; \
fi; \
)

EXPECTED_aes_sha1 = 1242a6757c8aef23e50b5264f5941a2f4b4a347e -
misalign: $(BIN)
$(Q)$(PRINTF) "Running aes.elf ... ";
$(Q)if [ "$(shell $(BIN) -m $(OUT)/aes.elf | $(SHA1SUM))" = "$(EXPECTED_aes_sha1)" ]; then \
EXPECTED_aes_sha1 = f9924635666d3d58d5b60c0bde8b986a2a99effb -
misalign: $(BIN) build-testbenches
$(Q)$(PRINTF) "Running aes ... ";
$(Q)if [ "$(shell $(BIN) -m $(OUT)/bin/riscv32/aes | $(SHA1SUM))" = "$(EXPECTED_aes_sha1)" ]; then \
$(call notice, [OK]); \
else \
$(PRINTF) "Failed.\n"; \
Expand Down
50 changes: 20 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -327,46 +327,36 @@ Use of this source code is governed by a MIT license that can be found in the [L

## External sources

In `rv32emu` repository, there are some prebuilt ELF files for testing purpose.
* `aes.elf` : See [tests/aes.c](tests/aes.c)
* `captcha.elf` : See [tests/captcha.c](tests/captcha.c)
There are some prebuilt executables in [rv32emu-prebuilt](https://github.com/sysprog21/rv32emu-prebuilt) for testing and benchmarking purpose.
The prebuilt executables are built from GNU/GCC v9 and [xPack GCC v14.2.0-1](https://github.com/xpack-dev-tools/gcc-xpack) under Ubuntu-20.04.

To fetch the prebuilt executables, run the following command:

```shell
$ make build-testbenches
```

Or, to compile the executables from the source, run:

```shell
$ make build-testbenches USE_PREBUILT=0 CROSS_CC=<riscv-cross-compiler>
```

Notice that the RISC-V cross-compiler is required to build the binary.

In default, `rv32emu` will download the tarball from GitHub and extract the executables into `build/bin/`.

There are still some prebuilt ELF files for testing purpose under `build/`.
* `cc.elf` : See [tests/cc](tests/cc)
* `chacha20.elf` : See [tests/chacha20](tests/chacha20)
* `coremark.elf` : See [eembc/coremark](https://github.com/eembc/coremark) [RV32M]
* `dhrystone.elf` : See [rv8-bench](https://github.com/michaeljclark/rv8-bench)
* `donut.elf` : See [donut.c](tests/donut.c)
* `doom.elf` : See [sysprog21/doom_riscv](https://github.com/sysprog21/doom_riscv) [RV32M]
* `fcalc.elf` : See [fcalc.c](tests/fcalc.c)
* `hamilton.elf` : See [hamilton.c](tests/hamilton.c)
* `ieee754.elf` : See [tests/ieee754.c](tests/ieee754.c) [RV32F]
* `jit-bf.elf` : See [ezaki-k/xkon_beta](https://github.com/ezaki-k/xkon_beta)
* `lena.elf`: See [tests/lena.c](tests/lena.c)
* `line.elf` : See [tests/line.c](tests/line.c) [RV32M]
* `maj2random.elf` : See [tests/maj2random.c](tests/maj2random.c) [RV32F]
* `mandelbrot.elf` : See [tests/mandelbrot.c](tests/mandelbrot.c)
* `nqueens.elf` : See [tests/nqueens.c](tests/nqueens.c)
* `nyancat.elf` : See [tests/nyancat.c](tests/nyancat.c)
* `pi.elf` : See [tests/pi.c](tests/pi.c) [RV32M]
* `qrcode.elf` : See [tests/qrcode.c](tests/qrcode.c)
* `quake.elf` : See [sysprog21/quake-embedded](https://github.com/sysprog21/quake-embedded) [RV32F]
* `readelf.elf` : See [tests/readelf](tests/readelf)
* `richards.elf` : See [tests/richards.c](tests/richards.c)
* `rvsim.elf` : See [tests/rvsim.c](tests/rvsim.c)
* `scimark2.elf` : See [tests/scimark2](tests/scimark2) [RV32MF]
* `smolnes.elf` : See [tests/smolnes](tests/smolnes.c) [RV32M]
* `spirograph.elf` : See [tests/spirograph.c](tests/spirograph.c)
* `stream.elf` : See [tests/stream](tests/stream.c) [RV32MF]
* `qsort.elf` : See [rv8-bench](https://github.com/michaeljclark/rv8-bench)
* `miniz.elf` : See [rv8-bench](https://github.com/michaeljclark/rv8-bench)
* `primes.elf` : See [rv8-bench](https://github.com/michaeljclark/rv8-bench)
* `sha512.elf` : See [rv8-bench](https://github.com/michaeljclark/rv8-bench)
* `numeric_sort.elf` : See [nbench](https://github.com/nfinit/ansibench/tree/master/nbench)
* `FP_emulation.elf` : See [nbench](https://github.com/nfinit/ansibench/tree/master/nbench)
* `bitfield.elf` : See [nbench](https://github.com/nfinit/ansibench/tree/master/nbench)
* `idea.elf` : See [nbench](https://github.com/nfinit/ansibench/tree/master/nbench)
* `assignment.elf` : See [nbench](https://github.com/nfinit/ansibench/tree/master/nbench)
* `string_sort.elf` : See [nbench](https://github.com/nfinit/ansibench/tree/master/nbench)
* `huffman.elf` : See [nbench](https://github.com/nfinit/ansibench/tree/master/nbench)
## Reference

* [Writing a simple RISC-V emulator in plain C](https://fmash16.github.io/content/posts/riscv-emulator-in-c.html)
Expand Down
Binary file removed build/FP_emulation.elf
Binary file not shown.
Binary file removed build/aes.elf
Binary file not shown.
Binary file removed build/assignment.elf
Binary file not shown.
Binary file removed build/bitfield.elf
Binary file not shown.
Binary file removed build/captcha.elf
Binary file not shown.
Binary file removed build/coremark.elf
Binary file not shown.
Binary file removed build/dhrystone.elf
Binary file not shown.
Binary file removed build/donut.elf
Binary file not shown.
Binary file removed build/fcalc.elf
Binary file not shown.
Binary file removed build/hamilton.elf
Binary file not shown.
Binary file removed build/huffman.elf
Binary file not shown.
Binary file removed build/idea.elf
Binary file not shown.
Binary file removed build/lena.elf
Binary file not shown.
Binary file removed build/line.elf
Binary file not shown.
Binary file removed build/maj2random.elf
Binary file not shown.
Binary file removed build/mandelbrot.elf
Binary file not shown.
Binary file removed build/miniz.elf
Binary file not shown.
Binary file removed build/nqueens.elf
Binary file not shown.
Binary file removed build/numeric_sort.elf
Binary file not shown.
Binary file removed build/nyancat.elf
Binary file not shown.
Binary file removed build/pi.elf
Binary file not shown.
Binary file removed build/primes.elf
Binary file not shown.
Binary file removed build/puzzle.elf
Binary file not shown.
Binary file removed build/qrcode.elf
Binary file not shown.
Binary file removed build/qsort.elf
Binary file not shown.
Binary file removed build/richards.elf
Binary file not shown.
Binary file removed build/rvsim.elf
Binary file not shown.
Binary file removed build/sha512.elf
Binary file not shown.
Binary file removed build/spirograph.elf
Binary file not shown.
Binary file removed build/stream.elf
Binary file not shown.
Binary file removed build/string_sort.elf
Binary file not shown.
60 changes: 60 additions & 0 deletions mk/benchmark.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
USE_PREBUILT ?= 1

CC ?= gcc
CROSS_CC ?= riscv-none-elf-gcc

BINDIR := $(abspath $(OUT))/bin

TEST_SUITES += \
ansibench \
rv8-bench

# "ieee754" needs F extension
# "smolnes", "ticks" have inline assembly and only work in riscv
TESTBENCHES += \
captcha \
donut \
fcalc \
hamilton \
$(ieee754) \
jit \
lena \
line \
maj2random \
mandelbrot \
nqueens \
nyancat \
pi \
puzzle \
qrcode \
richards \
rvsim \
$(smolnes) \
spirograph \
$(ticks)

ifeq ($(USE_PREBUILT),1)
LATEST_RELEASE := $(shell wget -qO - https://api.github.com/repos/sysprog21/rv32emu-prebuilt/releases/latest | grep -Po '(?<="tag_name": ").+(?=",)')
endif

.PHONY: build-testbenches benchmark

# TODO: generate results automatically
benchmark: build-testbenches

build-testbenches:
ifeq ($(USE_PREBUILT),1)
@echo "Fetching prebuilt executables in \"rv32emu-prebuilt\"..."
@wget -O - https://github.com/sysprog21/rv32emu-prebuilt/releases/download/$(LATEST_RELEASE)/rv32emu-prebuilt.tar.gz | tar zx -C build
else
@$(foreach tb,$(TEST_SUITES), \
git submodule update --init ./tests/$(tb) &&) true
@$(foreach tb,$(TEST_SUITES), \
CC=$(CC) CROSS_CC=$(CROSS_CC) BINDIR=$(BINDIR) \
$(MAKE) -C ./tests/$(tb) all &&) true
@$(foreach tb,$(TESTBENCHES), \
$(CC) -m32 -O2 -Wno-unused-result -o $(BINDIR)/x86_64/$(tb) tests/$(tb).c -lm &&) true
@$(foreach tb,$(TESTBENCHES), \
$(CROSS_CC) -march=rv32im -mabi=ilp32 -O2 -Wno-unused-result -Wno-implicit-function-declaration \
-o $(BINDIR)/riscv32/$(tb) tests/$(tb).c -lm -lsemihost &&) true
endif
Loading
Loading