URL
https://opencores.org/ocsvn/neorv32/neorv32/trunk
Subversion Repositories neorv32
Compare Revisions
- This comparison shows the changes necessary to convert path
/neorv32/trunk/sw/example
- from Rev 43 to Rev 44
- ↔ Reverse comparison
Rev 43 → Rev 44
/bit_manipulation/README.md
0,0 → 1,15
# NEORV32 Bit Manipulation `B` Extension |
|
:warning: The RISC-V `B` extension is not ratified yet. Hence, it is not supported by the upstream RISC-V GCC port. |
|
:warning: The NEORV32's bit manipulation instruction only supports the `Zbb` base instructions subset yet. |
|
The provided test program `main.c` verifies all instructions of the `B.Zbb` extensions by checking the results against a pure-software emulation model. |
The emulation functions as well as the available **intrinsics** for the `B` extension are located in `neorv32_b_extension_intrinsics.h`. |
|
:information_source: More information regarding the RISC-V bit manipulation extension can be found in the officail GitHub repo: |
[github.com/riscv/riscv-bitmanip](https://github.com/riscv/riscv-bitmanip). The current specification of the bitmanipulation spec supported by the NEORV32 |
can be found in `docs/bitmanip-draft.pdf`. |
|
:information_source: Compiling the test program (`main.c`) and/or the intriniscs library using the `MARCH` `b` flag should be avoided (might add further instructions from the `B` extension |
that are not part of the `Zbb` subset). |
/bit_manipulation/main.c
0,0 → 1,360
// ################################################################################################# |
// # << NEORV32 - Bit manipulation 'B.Zbb' test program >> # |
// # ********************************************************************************************* # |
// # BSD 3-Clause License # |
// # # |
// # Copyright (c) 2021, Stephan Nolting. All rights reserved. # |
// # # |
// # Redistribution and use in source and binary forms, with or without modification, are # |
// # permitted provided that the following conditions are met: # |
// # # |
// # 1. Redistributions of source code must retain the above copyright notice, this list of # |
// # conditions and the following disclaimer. # |
// # # |
// # 2. Redistributions in binary form must reproduce the above copyright notice, this list of # |
// # conditions and the following disclaimer in the documentation and/or other materials # |
// # provided with the distribution. # |
// # # |
// # 3. Neither the name of the copyright holder nor the names of its contributors may be used to # |
// # endorse or promote products derived from this software without specific prior written # |
// # permission. # |
// # # |
// # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS # |
// # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # |
// # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # |
// # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # |
// # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # |
// # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED # |
// # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # |
// # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # |
// # OF THE POSSIBILITY OF SUCH DAMAGE. # |
// # ********************************************************************************************* # |
// # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting # |
// ################################################################################################# |
|
|
/**********************************************************************//** |
* @file bit_manipulation/main.c |
* @author Stephan Nolting |
* @brief Test program for the NEORV32 'B' extension (Zbb subset) using pseudo-random data as input; compares results from hardware against pure-sw reference functions. |
**************************************************************************/ |
|
#include <neorv32.h> |
#include "neorv32_b_extension_intrinsics.h" |
|
/**********************************************************************//** |
* @name User configuration |
**************************************************************************/ |
/**@{*/ |
/** UART BAUD rate */ |
#define BAUD_RATE (19200) |
//** Number of test cases for each instruction */ |
#define NUM_TEST_CASES (10000) |
/**@}*/ |
|
|
// Prototypes |
uint32_t xorshift32(void); |
uint32_t check_result(uint32_t opa, uint32_t opb, uint32_t ref, uint32_t res); |
void print_report(int num_err, int num_tests); |
|
|
/**********************************************************************//** |
* Main function; test all available operations of the NEORV32 'B' extensions using bit manipulation intrinsics and software-only reference functions (emulation). |
* |
* @note This program requires the B CPU extension. |
* |
* @return Irrelevant. |
**************************************************************************/ |
int main() { |
|
uint32_t opa = 0, opb = 0, res_hw = 0, res_sw = 0; |
int i = 0, err_cnt = 0; |
const int num_tests = (int)NUM_TEST_CASES; |
|
// capture all exceptions and give debug info via UART |
neorv32_rte_setup(); |
|
// init UART at default baud rate, no parity bits, no rx interrupt, no tx interrupt |
neorv32_uart_setup(BAUD_RATE, 0b00, 0, 0); |
|
// intro |
neorv32_uart_printf("NEORV32 Bit Manipulation (B.Zbb) Extension Test\n\n"); |
|
// check available hardware extensions and compare with compiler flags |
neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch |
|
|
neorv32_uart_printf("Starting bit manipulation extensions tests (%i test cases per instruction)...\n", num_tests); |
|
// CLZ |
neorv32_uart_printf("\nCLZ:\n"); |
err_cnt = 0; |
for (i=0;i<num_tests; i++) { |
opa = xorshift32(); |
res_sw = riscv_emulate_clz(opa); |
res_hw = riscv_intrinsic_clz(opa); |
err_cnt += check_result(opa, 0, res_sw, res_hw); |
} |
print_report(err_cnt, num_tests); |
|
// CTZ |
neorv32_uart_printf("\nCTZ:\n"); |
err_cnt = 0; |
for (i=0;i<num_tests; i++) { |
opa = xorshift32(); |
res_sw = riscv_emulate_ctz(opa); |
res_hw = riscv_intrinsic_ctz(opa); |
err_cnt += check_result(opa, 0, res_sw, res_hw); |
} |
print_report(err_cnt, num_tests); |
|
// CPOP |
neorv32_uart_printf("\nCPOP:\n"); |
err_cnt = 0; |
for (i=0;i<num_tests; i++) { |
opa = xorshift32(); |
res_sw = riscv_emulate_cpop(opa); |
res_hw = riscv_intrinsic_cpop(opa); |
err_cnt += check_result(opa, 0, res_sw, res_hw); |
} |
print_report(err_cnt, num_tests); |
|
// SEXT.B |
neorv32_uart_printf("\nSEXT.B:\n"); |
err_cnt = 0; |
for (i=0;i<num_tests; i++) { |
opa = xorshift32(); |
res_sw = riscv_emulate_sextb(opa); |
res_hw = riscv_intrinsic_sextb(opa); |
err_cnt += check_result(opa, 0, res_sw, res_hw); |
} |
print_report(err_cnt, num_tests); |
|
// SEXT.H |
neorv32_uart_printf("\nSEXT.H:\n"); |
err_cnt = 0; |
for (i=0;i<num_tests; i++) { |
opa = xorshift32(); |
res_sw = riscv_emulate_sexth(opa); |
res_hw = riscv_intrinsic_sexth(opa); |
err_cnt += check_result(opa, 0, res_sw, res_hw); |
} |
print_report(err_cnt, num_tests); |
|
// MIN |
neorv32_uart_printf("\nMIN:\n"); |
err_cnt = 0; |
for (i=0;i<num_tests; i++) { |
opa = xorshift32(); |
opb = xorshift32(); |
res_sw = riscv_emulate_min(opa, opb); |
res_hw = riscv_intrinsic_min(opa, opb); |
err_cnt += check_result(opa, opb, res_sw, res_hw); |
} |
print_report(err_cnt, num_tests); |
|
// MINU |
neorv32_uart_printf("\nMINU:\n"); |
err_cnt = 0; |
for (i=0;i<num_tests; i++) { |
opa = xorshift32(); |
opb = xorshift32(); |
res_sw = riscv_emulate_minu(opa, opb); |
res_hw = riscv_intrinsic_minu(opa, opb); |
err_cnt += check_result(opa, opb, res_sw, res_hw); |
} |
print_report(err_cnt, num_tests); |
|
// MAX |
neorv32_uart_printf("\nMAX:\n"); |
err_cnt = 0; |
for (i=0;i<num_tests; i++) { |
opa = xorshift32(); |
opb = xorshift32(); |
res_sw = riscv_emulate_max(opa, opb); |
res_hw = riscv_intrinsic_max(opa, opb); |
err_cnt += check_result(opa, opb, res_sw, res_hw); |
} |
print_report(err_cnt, num_tests); |
|
// MAXU |
neorv32_uart_printf("\nMAXU:\n"); |
err_cnt = 0; |
for (i=0;i<num_tests; i++) { |
opa = xorshift32(); |
opb = xorshift32(); |
res_sw = riscv_emulate_maxu(opa, opb); |
res_hw = riscv_intrinsic_maxu(opa, opb); |
err_cnt += check_result(opa, opb, res_sw, res_hw); |
} |
print_report(err_cnt, num_tests); |
|
// PACK |
neorv32_uart_printf("\nPACK:\n"); |
err_cnt = 0; |
for (i=0;i<num_tests; i++) { |
opa = xorshift32(); |
opb = xorshift32(); |
res_sw = riscv_emulate_pack(opa, opb); |
res_hw = riscv_intrinsic_pack(opa, opb); |
err_cnt += check_result(opa, opb, res_sw, res_hw); |
} |
print_report(err_cnt, num_tests); |
|
// ANDN |
neorv32_uart_printf("\nANDN:\n"); |
err_cnt = 0; |
for (i=0;i<num_tests; i++) { |
opa = xorshift32(); |
opb = xorshift32(); |
res_sw = riscv_emulate_andn(opa, opb); |
res_hw = riscv_intrinsic_andn(opa, opb); |
err_cnt += check_result(opa, opb, res_sw, res_hw); |
} |
print_report(err_cnt, num_tests); |
|
// ORN |
neorv32_uart_printf("\nORN:\n"); |
err_cnt = 0; |
for (i=0;i<num_tests; i++) { |
opa = xorshift32(); |
opb = xorshift32(); |
res_sw = riscv_emulate_orn(opa, opb); |
res_hw = riscv_intrinsic_orn(opa, opb); |
err_cnt += check_result(opa, opb, res_sw, res_hw); |
} |
print_report(err_cnt, num_tests); |
|
// XNOR |
neorv32_uart_printf("\nXNOR:\n"); |
err_cnt = 0; |
for (i=0;i<num_tests; i++) { |
opa = xorshift32(); |
opb = xorshift32(); |
res_sw = riscv_emulate_xnor(opa, opb); |
res_hw = riscv_intrinsic_xnor(opa, opb); |
err_cnt += check_result(opa, opb, res_sw, res_hw); |
} |
print_report(err_cnt, num_tests); |
|
// ROL |
neorv32_uart_printf("\nROL:\n"); |
err_cnt = 0; |
for (i=0;i<num_tests; i++) { |
opa = xorshift32(); |
opb = xorshift32(); |
res_sw = riscv_emulate_rol(opa, opb); |
res_hw = riscv_intrinsic_rol(opa, opb); |
err_cnt += check_result(opa, opb, res_sw, res_hw); |
} |
print_report(err_cnt, num_tests); |
|
// ROR |
neorv32_uart_printf("\nROR:\n"); |
err_cnt = 0; |
for (i=0;i<num_tests; i++) { |
opa = xorshift32(); |
opb = xorshift32(); |
res_sw = riscv_emulate_ror(opa, opb); |
res_hw = riscv_intrinsic_ror(opa, opb); |
err_cnt += check_result(opa, opb, res_sw, res_hw); |
} |
print_report(err_cnt, num_tests); |
|
// RORI |
neorv32_uart_printf("\nRORI (imm=20):\n"); // FIXME: static immediate |
err_cnt = 0; |
for (i=0;i<num_tests; i++) { |
opa = xorshift32(); |
res_sw = riscv_emulate_ror(opa, 20); |
res_hw = riscv_intrinsic_rori20(opa); |
err_cnt += check_result(opa, opb, res_sw, res_hw); |
} |
print_report(err_cnt, num_tests); |
|
// ORC.B |
neorv32_uart_printf("\nORC.B:\n"); |
err_cnt = 0; |
for (i=0;i<num_tests; i++) { |
opa = xorshift32(); |
res_sw = riscv_emulate_orcb(opa); |
res_hw = riscv_intrinsic_orcb(opa); |
err_cnt += check_result(opa, 0, res_sw, res_hw); |
} |
print_report(err_cnt, num_tests); |
|
// REV8 |
neorv32_uart_printf("\nREV8:\n"); |
err_cnt = 0; |
for (i=0;i<num_tests; i++) { |
opa = xorshift32(); |
res_sw = riscv_emulate_rev8(opa); |
res_hw = riscv_intrinsic_rev8(opa); |
err_cnt += check_result(opa, 0, res_sw, res_hw); |
} |
print_report(err_cnt, num_tests); |
|
|
neorv32_uart_printf("\nBit manipulation extension tests done.\n"); |
|
return 0; |
} |
|
|
/**********************************************************************//** |
* Pseudo-Random Number Generator (to generate test vectors). |
* |
* @return Random data (32-bit). |
**************************************************************************/ |
uint32_t xorshift32(void) { |
|
static uint32_t x32 = 314159265; |
|
x32 ^= x32 << 13; |
x32 ^= x32 >> 17; |
x32 ^= x32 << 5; |
|
return x32; |
} |
|
|
/**********************************************************************//** |
* Check results (reference (SW) vs actual hardware). |
* |
* @param[in] opa Operand 1 |
* @param[in] opb Operand 2 |
* @param[in] ref Software reference |
* @param[in] res Actual results |
* @return zero if results are equal. |
**************************************************************************/ |
uint32_t check_result(uint32_t opa, uint32_t opb, uint32_t ref, uint32_t res) { |
|
if (ref != res) { |
neorv32_uart_printf("opa = 0x%x, opb = 0x%x : ref = 0x%x vs res = 0x%x ", opa, opb, ref, res); |
neorv32_uart_printf("%c[1m[FAILED]%c[0m\n", 27, 27); |
return 1; |
} |
else { |
return 0; |
} |
} |
|
|
/**********************************************************************//** |
* Print test report. |
* |
* @param[in] num_err Number or errors in this test. |
* @param[in] num_tests Total number of conducted tests. |
**************************************************************************/ |
void print_report(int num_err, int num_tests) { |
|
neorv32_uart_printf("Errors: %i/%i ", num_err, num_tests); |
|
if (num_err == 0) { |
neorv32_uart_printf("%c[1m[ok]%c[0m\n", 27, 27); |
} |
else { |
neorv32_uart_printf("%c[1m[FAILED]%c[0m\n", 27, 27); |
} |
} |
/bit_manipulation/makefile
0,0 → 1,338
################################################################################################# |
# << NEORV32 - Application Makefile >> # |
# ********************************************************************************************* # |
# Make sure to add the riscv GCC compiler's bin folder to your PATH environment variable. # |
# ********************************************************************************************* # |
# BSD 3-Clause License # |
# # |
# Copyright (c) 2020, Stephan Nolting. All rights reserved. # |
# # |
# Redistribution and use in source and binary forms, with or without modification, are # |
# permitted provided that the following conditions are met: # |
# # |
# 1. Redistributions of source code must retain the above copyright notice, this list of # |
# conditions and the following disclaimer. # |
# # |
# 2. Redistributions in binary form must reproduce the above copyright notice, this list of # |
# conditions and the following disclaimer in the documentation and/or other materials # |
# provided with the distribution. # |
# # |
# 3. Neither the name of the copyright holder nor the names of its contributors may be used to # |
# endorse or promote products derived from this software without specific prior written # |
# permission. # |
# # |
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS # |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # |
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # |
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # |
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # |
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED # |
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # |
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # |
# OF THE POSSIBILITY OF SUCH DAMAGE. # |
# ********************************************************************************************* # |
# The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting # |
################################################################################################# |
|
|
# ***************************************************************************** |
# USER CONFIGURATION |
# ***************************************************************************** |
# User's application sources (*.c, *.cpp, *.s, *.S); add additional files here |
APP_SRC ?= $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S) |
|
# User's application include folders (don't forget the '-I' before each entry) |
APP_INC ?= -I . |
# User's application include folders - for assembly files only (don't forget the '-I' before each entry) |
ASM_INC ?= -I . |
|
# Optimization |
EFFORT ?= -Os |
|
# Compiler toolchain |
RISCV_TOOLCHAIN ?= riscv32-unknown-elf |
|
# CPU architecture and ABI |
MARCH ?= -march=rv32i |
MABI ?= -mabi=ilp32 |
|
# User flags for additional configuration (will be added to compiler flags) |
USER_FLAGS ?= |
|
# Serial port for executable upload via bootloer |
COM_PORT ?= /dev/ttyUSB0 |
|
# Relative or absolute path to the NEORV32 home folder |
NEORV32_HOME ?= ../../.. |
# ***************************************************************************** |
|
|
|
# ----------------------------------------------------------------------------- |
# NEORV32 framework |
# ----------------------------------------------------------------------------- |
# Path to NEORV32 linker script and startup file |
NEORV32_COM_PATH = $(NEORV32_HOME)/sw/common |
# Path to main NEORV32 library include files |
NEORV32_INC_PATH = $(NEORV32_HOME)/sw/lib/include |
# Path to main NEORV32 library source files |
NEORV32_SRC_PATH = $(NEORV32_HOME)/sw/lib/source |
# Path to NEORV32 executable generator |
NEORV32_EXG_PATH = $(NEORV32_HOME)/sw/image_gen |
# Path to NEORV32 core rtl folder |
NEORV32_RTL_PATH = $(NEORV32_HOME)/rtl/core |
# Marker file to check for NEORV32 home folder |
NEORV32_HOME_MARKER = $(NEORV32_INC_PATH)/neorv32.h |
|
# Core libraries (peripheral and CPU drivers) |
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c) |
# Application start-up code |
CORE_SRC += $(NEORV32_COM_PATH)/crt0.S |
|
# Linker script |
LD_SCRIPT = $(NEORV32_COM_PATH)/neorv32.ld |
|
# Main output files |
APP_EXE = neorv32_exe.bin |
APP_ASM = main.asm |
APP_IMG = neorv32_application_image.vhd |
BOOT_IMG = neorv32_bootloader_image.vhd |
|
|
# ----------------------------------------------------------------------------- |
# Sources and objects |
# ----------------------------------------------------------------------------- |
# Define all sources |
SRC = $(APP_SRC) |
SRC += $(CORE_SRC) |
|
# Define all object files |
OBJ = $(SRC:%=%.o) |
|
|
# ----------------------------------------------------------------------------- |
# Tools and flags |
# ----------------------------------------------------------------------------- |
# Compiler tools |
CC = $(RISCV_TOOLCHAIN)-gcc |
OBJDUMP = $(RISCV_TOOLCHAIN)-objdump |
OBJCOPY = $(RISCV_TOOLCHAIN)-objcopy |
SIZE = $(RISCV_TOOLCHAIN)-size |
|
# Host native compiler |
CC_X86 = g++ -Wall -O -g |
|
# NEORV32 executable image generator |
IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen |
|
# Compiler & linker flags |
CC_OPTS = $(MARCH) $(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -nostartfiles |
CC_OPTS += -Wl,--gc-sections -lm -lc -lgcc -lc |
# This accelerates instruction fetch after branches when C extension is enabled (irrelevant when C extension is disabled) |
CC_OPTS += -falign-functions=4 -falign-labels=4 -falign-loops=4 -falign-jumps=4 |
CC_OPTS += $(USER_FLAGS) |
|
|
# ----------------------------------------------------------------------------- |
# Application output definitions |
# ----------------------------------------------------------------------------- |
.PHONY: check info help elf_info clean clean_all bootloader |
.DEFAULT_GOAL := help |
|
# 'compile' is still here for compatibility |
exe: $(APP_ASM) $(APP_EXE) |
compile: $(APP_ASM) $(APP_EXE) |
install: $(APP_ASM) $(APP_IMG) |
all: $(APP_ASM) $(APP_EXE) $(APP_IMG) |
|
# Check if making bootloader |
# Use different base address and legth for instruction memory/"rom" (BOOTMEM instead of IMEM) |
# Also define "make_bootloader" for crt0.S |
target bootloader: CC_OPTS += -Wl,--defsym=make_bootloader=1 -Dmake_bootloader |
|
|
# ----------------------------------------------------------------------------- |
# Image generator targets |
# ----------------------------------------------------------------------------- |
# install/compile tools |
$(IMAGE_GEN): $(NEORV32_EXG_PATH)/image_gen.cpp |
@echo Compiling $(IMAGE_GEN) |
@$(CC_X86) $< -o $(IMAGE_GEN) |
|
|
# ----------------------------------------------------------------------------- |
# General targets: Assemble, compile, link, dump |
# ----------------------------------------------------------------------------- |
# Compile app *.s sources (assembly) |
%.s.o: %.s |
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@ |
|
# Compile app *.S sources (assembly + C pre-processor) |
%.S.o: %.S |
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@ |
|
# Compile app *.c sources |
%.c.o: %.c |
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@ |
|
# Compile app *.cpp sources |
%.cpp.o: %.cpp |
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@ |
|
# Link object files and show memory utilization |
main.elf: $(OBJ) |
@$(CC) $(CC_OPTS) -T $(LD_SCRIPT) $(OBJ) -o $@ |
@echo "Memory utilization:" |
@$(SIZE) main.elf |
|
# Assembly listing file (for debugging) |
$(APP_ASM): main.elf |
@$(OBJDUMP) -d -S -z $< > $@ |
|
# Generate final executable from .text + .rodata + .data (in THIS order!) |
main.bin: main.elf $(APP_ASM) |
@$(OBJCOPY) -I elf32-little $< -j .text -O binary text.bin |
@$(OBJCOPY) -I elf32-little $< -j .rodata -O binary rodata.bin |
@$(OBJCOPY) -I elf32-little $< -j .data -O binary data.bin |
@cat text.bin rodata.bin data.bin > $@ |
@rm -f text.bin rodata.bin data.bin |
|
|
# ----------------------------------------------------------------------------- |
# Application targets: Generate binary executable, install (as VHDL file) |
# ----------------------------------------------------------------------------- |
# Generate NEORV32 executable image for upload via bootloader |
$(APP_EXE): main.bin $(IMAGE_GEN) |
@set -e |
@$(IMAGE_GEN) -app_bin $< $@ $(shell basename $(CURDIR)) |
@echo "Executable ($(APP_EXE)) size in bytes:" |
@wc -c < $(APP_EXE) |
|
# Generate NEORV32 executable VHDL boot image |
$(APP_IMG): main.bin $(IMAGE_GEN) |
@set -e |
@$(IMAGE_GEN) -app_img $< $@ $(shell basename $(CURDIR)) |
@echo "Installing application image to $(NEORV32_RTL_PATH)/$(APP_IMG)" |
@cp $(APP_IMG) $(NEORV32_RTL_PATH)/. |
|
|
# ----------------------------------------------------------------------------- |
# Bootloader targets |
# ----------------------------------------------------------------------------- |
# Create and install bootloader VHDL init image |
$(BOOT_IMG): main.bin $(IMAGE_GEN) |
@set -e |
@$(IMAGE_GEN) -bld_img $< $(BOOT_IMG) $(shell basename $(CURDIR)) |
@echo "Installing bootloader image to $(NEORV32_RTL_PATH)/$(BOOT_IMG)" |
@cp $(BOOT_IMG) $(NEORV32_RTL_PATH)/. |
|
# Just an alias that |
bootloader: $(BOOT_IMG) |
|
|
# ----------------------------------------------------------------------------- |
# Check toolchain |
# ----------------------------------------------------------------------------- |
check: $(IMAGE_GEN) |
@echo "---------------- Check: NEORV32_HOME folder ----------------" |
ifneq ($(shell [ -e $(NEORV32_HOME_MARKER) ] && echo 1 || echo 0 ), 1) |
$(error NEORV32_HOME folder not found!) |
endif |
@echo "NEORV32_HOME: $(NEORV32_HOME)" |
@echo "---------------- Check: $(CC) ----------------" |
@$(CC) -v |
@echo "---------------- Check: $(OBJDUMP) ----------------" |
@$(OBJDUMP) -V |
@echo "---------------- Check: $(OBJCOPY) ----------------" |
@$(OBJCOPY) -V |
@echo "---------------- Check: $(SIZE) ----------------" |
@$(SIZE) -V |
@echo "---------------- Check: NEORV32 image_gen ----------------" |
@$(IMAGE_GEN) -help |
@echo "---------------- Check: Native GCC ----------------" |
@$(CC_X86) -v |
@echo |
@echo "Toolchain check OK" |
|
|
# ----------------------------------------------------------------------------- |
# Upload executable via serial port to bootloader |
# ----------------------------------------------------------------------------- |
upload: $(APP_EXE) |
@sh $(NEORV32_EXG_PATH)/uart_upload.sh $(COM_PORT) $(APP_EXE) |
|
|
# ----------------------------------------------------------------------------- |
# Show configuration |
# ----------------------------------------------------------------------------- |
info: |
@echo "---------------- Info: Project ----------------" |
@echo "Project folder: $(shell basename $(CURDIR))" |
@echo "Source files: $(APP_SRC)" |
@echo "Include folder(s): $(APP_INC)" |
@echo "ASM include folder(s): $(ASM_INC)" |
@echo "---------------- Info: NEORV32 ----------------" |
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)" |
@echo "IMAGE_GEN: $(IMAGE_GEN)" |
@echo "Core source files:" |
@echo "$(CORE_SRC)" |
@echo "Core include folder:" |
@echo "$(NEORV32_INC_PATH)" |
@echo "---------------- Info: Objects ----------------" |
@echo "Project object files:" |
@echo "$(OBJ)" |
@echo "---------------- Info: RISC-V CPU ----------------" |
@echo "MARCH: $(MARCH)" |
@echo "MABI: $(MABI)" |
@echo "---------------- Info: Toolchain ----------------" |
@echo "Toolchain: $(RISCV_TOLLCHAIN)" |
@echo "CC: $(CC)" |
@echo "OBJDUMP: $(OBJDUMP)" |
@echo "OBJCOPY: $(OBJCOPY)" |
@echo "SIZE: $(SIZE)" |
@echo "---------------- Info: Compiler Libraries ----------------" |
@echo "LIBGCC:" |
@$(CC) -print-libgcc-file-name |
@echo "SEARCH-DIRS:" |
@$(CC) -print-search-dirs |
@echo "---------------- Info: Flags ----------------" |
@echo "USER_FLAGS: $(USER_FLAGS)" |
@echo "CC_OPTS: $(CC_OPTS)" |
@echo "---------------- Info: Host Native GCC Flags ----------------" |
@echo "CC_X86: $(CC_X86)" |
|
|
# ----------------------------------------------------------------------------- |
# Show final ELF details (just for debugging) |
# ----------------------------------------------------------------------------- |
elf_info: main.elf |
@$(OBJDUMP) -x main.elf |
|
|
# ----------------------------------------------------------------------------- |
# Help |
# ----------------------------------------------------------------------------- |
help: |
@echo "<<< NEORV32 Application Makefile >>>" |
@echo "Make sure to add the bin folder of RISC-V GCC to your PATH variable." |
@echo "Targets:" |
@echo " help - show this text" |
@echo " check - check toolchain" |
@echo " info - show makefile/toolchain configuration" |
@echo " exe - compile and generate <neorv32_exe.bin> executable for upload via bootloader" |
@echo " install - compile, generate and install VHDL IMEM boot image (for application)" |
@echo " all - compile and generate <neorv32_exe.bin> executable for upload via bootloader and generate and install VHDL IMEM boot image (for application)" |
@echo " clean - clean up project" |
@echo " clean_all - clean up project, core libraries and image generator" |
@echo " bootloader - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)" |
@echo " upload - upload <neorv32_exe.bin> executable via serial port <COM_PORT> to bootloader" |
|
|
# ----------------------------------------------------------------------------- |
# Clean up |
# ----------------------------------------------------------------------------- |
clean: |
@rm -f *.elf *.o *.bin *.out *.asm *.vhd |
|
clean_all: clean |
@rm -f $(OBJ) $(IMAGE_GEN) |
/bit_manipulation/neorv32_b_extension_intrinsics.h
0,0 → 1,842
// ################################################################################################# |
// # << NEORV32 - Intrinsics + Emulation Functions for the B.Zbb CPU extensions >> # |
// # ********************************************************************************************* # |
// # BSD 3-Clause License # |
// # # |
// # Copyright (c) 2021, Stephan Nolting. All rights reserved. # |
// # # |
// # Redistribution and use in source and binary forms, with or without modification, are # |
// # permitted provided that the following conditions are met: # |
// # # |
// # 1. Redistributions of source code must retain the above copyright notice, this list of # |
// # conditions and the following disclaimer. # |
// # # |
// # 2. Redistributions in binary form must reproduce the above copyright notice, this list of # |
// # conditions and the following disclaimer in the documentation and/or other materials # |
// # provided with the distribution. # |
// # # |
// # 3. Neither the name of the copyright holder nor the names of its contributors may be used to # |
// # endorse or promote products derived from this software without specific prior written # |
// # permission. # |
// # # |
// # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS # |
// # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # |
// # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # |
// # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # |
// # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # |
// # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED # |
// # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # |
// # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # |
// # OF THE POSSIBILITY OF SUCH DAMAGE. # |
// # ********************************************************************************************* # |
// # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting # |
// ################################################################################################# |
|
|
/**********************************************************************//** |
* @file bit_manipulation/neorv32_b_extension_intrinsics.h |
* @author Stephan Nolting |
* @brief "Intrinsic" library for the NEORV32 bit manipulation (B.Zbb) extension. Also provides emulation functions for all intrinsics (functionality re-built in pure software). |
* |
* @warning This library is just a temporary fall-back until the B/Zbb extensions are supported by the upstream RISC-V GCC port. |
**************************************************************************/ |
|
#ifndef neorv32_b_extension_intrinsics_h |
#define neorv32_b_extension_intrinsics_h |
|
/**********************************************************************//** |
* @name Custom instructions helper macros |
**************************************************************************/ |
/**@{*/ |
|
//** Selection helper macro */ |
#define STR1(x) #x |
//** Selection helper macro 2 */ |
#define STR(x) STR1(x) |
|
//** Register address converter */ |
#define GET_REG_ADDR(x) REG_ADDR_##x |
|
#define REG_ADDR_x0 0 /**< register 0 */ |
#define REG_ADDR_x1 1 /**< register 1 */ |
#define REG_ADDR_x2 2 /**< register 2 */ |
#define REG_ADDR_x3 3 /**< register 3 */ |
#define REG_ADDR_x4 4 /**< register 4 */ |
#define REG_ADDR_x5 5 /**< register 5 */ |
#define REG_ADDR_x6 6 /**< register 6 */ |
#define REG_ADDR_x7 7 /**< register 7 */ |
#define REG_ADDR_x8 8 /**< register 8 */ |
#define REG_ADDR_x9 9 /**< register 9 */ |
#define REG_ADDR_x10 10 /**< register 10 */ |
#define REG_ADDR_x11 11 /**< register 11 */ |
#define REG_ADDR_x12 12 /**< register 12 */ |
#define REG_ADDR_x13 13 /**< register 13 */ |
#define REG_ADDR_x14 14 /**< register 14 */ |
#define REG_ADDR_x15 15 /**< register 15 */ |
#define REG_ADDR_x16 16 /**< register 16 */ |
#define REG_ADDR_x17 17 /**< register 17 */ |
#define REG_ADDR_x18 18 /**< register 18 */ |
#define REG_ADDR_x19 19 /**< register 19 */ |
#define REG_ADDR_x20 20 /**< register 20 */ |
#define REG_ADDR_x21 21 /**< register 21 */ |
#define REG_ADDR_x22 22 /**< register 22 */ |
#define REG_ADDR_x23 23 /**< register 23 */ |
#define REG_ADDR_x24 24 /**< register 24 */ |
#define REG_ADDR_x25 25 /**< register 25 */ |
#define REG_ADDR_x26 26 /**< register 26 */ |
#define REG_ADDR_x27 27 /**< register 27 */ |
#define REG_ADDR_x28 28 /**< register 28 */ |
#define REG_ADDR_x29 29 /**< register 29 */ |
#define REG_ADDR_x30 30 /**< register 30 */ |
#define REG_ADDR_x31 31 /**< register 31 */ |
#define REG_ADDR_zero 0 /**< register 0 - according to calling convention */ |
#define REG_ADDR_ra 1 /**< register 1 - according to calling convention */ |
#define REG_ADDR_sp 2 /**< register 2 - according to calling convention */ |
#define REG_ADDR_gp 3 /**< register 3 - according to calling convention */ |
#define REG_ADDR_tp 4 /**< register 4 - according to calling convention */ |
#define REG_ADDR_t0 5 /**< register 5 - according to calling convention */ |
#define REG_ADDR_t1 6 /**< register 6 - according to calling convention */ |
#define REG_ADDR_t2 7 /**< register 7 - according to calling convention */ |
#define REG_ADDR_s0 8 /**< register 8 - according to calling convention */ |
#define REG_ADDR_s1 9 /**< register 9 - according to calling convention */ |
#define REG_ADDR_a0 10 /**< register 10 - according to calling convention */ |
#define REG_ADDR_a1 11 /**< register 11 - according to calling convention */ |
#define REG_ADDR_a2 12 /**< register 12 - according to calling convention */ |
#define REG_ADDR_a3 13 /**< register 13 - according to calling convention */ |
#define REG_ADDR_a4 14 /**< register 14 - according to calling convention */ |
#define REG_ADDR_a5 15 /**< register 15 - according to calling convention */ |
#define REG_ADDR_a6 16 /**< register 16 - according to calling convention */ |
#define REG_ADDR_a7 17 /**< register 17 - according to calling convention */ |
#define REG_ADDR_s2 18 /**< register 18 - according to calling convention */ |
#define REG_ADDR_s3 19 /**< register 19 - according to calling convention */ |
#define REG_ADDR_s4 20 /**< register 20 - according to calling convention */ |
#define REG_ADDR_s5 21 /**< register 21 - according to calling convention */ |
#define REG_ADDR_s6 22 /**< register 22 - according to calling convention */ |
#define REG_ADDR_s7 23 /**< register 23 - according to calling convention */ |
#define REG_ADDR_s8 24 /**< register 24 - according to calling convention */ |
#define REG_ADDR_s9 25 /**< register 25 - according to calling convention */ |
#define REG_ADDR_s10 26 /**< register 26 - according to calling convention */ |
#define REG_ADDR_s11 27 /**< register 27 - according to calling convention */ |
#define REG_ADDR_t3 28 /**< register 28 - according to calling convention */ |
#define REG_ADDR_t4 29 /**< register 29 - according to calling convention */ |
#define REG_ADDR_t5 30 /**< register 30 - according to calling convention */ |
#define REG_ADDR_t6 31 /**< register 31 - according to calling convention */ |
|
//** Construct instruction word (32-bit) for R-type instruction */ |
#define CMD_WORD_R_TYPE(funct7, rs2, rs1, funct3, rd, opcode) \ |
( (opcode & 0x7f) << 0 ) + \ |
( (rd & 0x1f) << 7 ) + \ |
( (rs1 & 0x1f) << 15 ) + \ |
( (rs2 & 0x1f) << 20 ) + \ |
( (funct7 & 0x7f) << 25 ) + \ |
( (funct3 & 0x1f) << 12 ) |
|
//** Construct instruction word (32-bit) for I-type instruction */ |
#define CMD_WORD_I_TYPE(imm12, rs1_f5, funct3, rd, opcode) \ |
( (opcode & 0x7f) << 0 ) + \ |
( (rd & 0x1f) << 7 ) + \ |
( (rs1_f5 & 0x1f) << 15 ) + \ |
( (imm12 & 0xfff) << 20 ) + \ |
( (funct3 & 0x1f) << 12 ) |
|
//** Construct custom instruction for R-type instruction */ |
#define CUSTOM_INSTR_R_TYPE(funct7, rs2, rs1, funct3, rd, opcode) \ |
asm volatile (".word "STR(CMD_WORD_R_TYPE(funct7, GET_REG_ADDR(rs2), GET_REG_ADDR(rs1), funct3, GET_REG_ADDR(rd), opcode))"\n"); |
|
//** Construct custom instruction for R1-type instruction (register + 5-bit immediate/function_select) */ |
#define CUSTOM_INSTR_R1_TYPE(funct7, funct5, rs1, funct3, rd, opcode) \ |
asm volatile (".word "STR(CMD_WORD_R_TYPE(funct7, funct5, GET_REG_ADDR(rs1), funct3, GET_REG_ADDR(rd), opcode))"\n"); |
|
//** Construct custom instruction for I-type instruction */ |
#define CUSTOM_INSTR_I_TYPE(imm12, rs1, funct3, rd, opcode) \ |
asm volatile (".word "STR(CMD_WORD_I_TYPE(imm12, GET_REG_ADDR(rs1), funct3, GET_REG_ADDR(rd), opcode))"\n"); |
/**@}*/ |
|
|
// ################################################################################################ |
// "Intrinsics" |
// ################################################################################################ |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation CLZ (count leading zeros) [B.Zbb] |
* |
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1. |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @return Number of leading zeros in source operand. |
**************************************************************************/ |
uint32_t __attribute__ ((noinline)) riscv_intrinsic_clz(uint32_t rs1) { |
|
register uint32_t result __asm__ ("a0"); |
|
// clz a0, a0 |
CUSTOM_INSTR_R1_TYPE(0b0110000, 0b00000, a0, 0b001, a0, 0b0010011); |
|
return result; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation CTZ (count trailing zeros) [B.Zbb] |
* |
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1. |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @return Number of trailing zeros in source operand. |
**************************************************************************/ |
uint32_t __attribute__ ((noinline)) riscv_intrinsic_ctz(uint32_t rs1) { |
|
register uint32_t result __asm__ ("a0"); |
|
// ctz a0, a0 |
CUSTOM_INSTR_R1_TYPE(0b0110000, 0b00001, a0, 0b001, a0, 0b0010011); |
|
return result; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation CPOP (count set bits) [B.Zbb] |
* |
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1. |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @return Number of set bits in source operand. |
**************************************************************************/ |
uint32_t __attribute__ ((noinline)) riscv_intrinsic_cpop(uint32_t rs1) { |
|
register uint32_t result __asm__ ("a0"); |
|
// cpop a0, a0 |
CUSTOM_INSTR_R1_TYPE(0b0110000, 0b00010, a0, 0b001, a0, 0b0010011); |
|
return result; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation SEXT.B (sign-extend byte) [B.Zbb] |
* |
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1. |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @return Sign extended byte (operand(7:0)). |
**************************************************************************/ |
uint32_t __attribute__ ((noinline)) riscv_intrinsic_sextb(uint32_t rs1) { |
|
register uint32_t result __asm__ ("a0"); |
|
// sext.b a0, a0 |
CUSTOM_INSTR_R1_TYPE(0b0110000, 0b00100, a0, 0b001, a0, 0b0010011); |
|
return result; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation SEXT.H (sign-extend half-word) [B.Zbb] |
* |
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1. |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @return Sign extended half-word (operand(15:0)). |
**************************************************************************/ |
uint32_t __attribute__ ((noinline)) riscv_intrinsic_sexth(uint32_t rs1) { |
|
register uint32_t result __asm__ ("a0"); |
|
// sext.h a0, a0 |
CUSTOM_INSTR_R1_TYPE(0b0110000, 0b00101, a0, 0b001, a0, 0b0010011); |
|
return result; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation MIN (select signed minimum) [B.Zbb] |
* |
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1. |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @param[in] rs2 Source operand 2 (a0). |
* @return Signed minimum. |
**************************************************************************/ |
uint32_t __attribute__ ((noinline)) riscv_intrinsic_min(uint32_t rs1, uint32_t rs2) { |
|
register uint32_t result __asm__ ("a0"); |
|
// min a0, a0, a1 |
CUSTOM_INSTR_R_TYPE(0b0000101, a1, a0, 0b100, a0, 0b0110011); |
|
return result; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation MINU (select unsigned minimum) [B.Zbb] |
* |
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1. |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @param[in] rs2 Source operand 2 (a0). |
* @return Unsigned minimum. |
**************************************************************************/ |
uint32_t __attribute__ ((noinline)) riscv_intrinsic_minu(uint32_t rs1, uint32_t rs2) { |
|
register uint32_t result __asm__ ("a0"); |
|
// minu a0, a0, a1 |
CUSTOM_INSTR_R_TYPE(0b0000101, a1, a0, 0b101, a0, 0b0110011); |
|
return result; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation MAX (select signed maximum) [B.Zbb] |
* |
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1. |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @param[in] rs2 Source operand 2 (a0). |
* @return Signed maximum. |
**************************************************************************/ |
uint32_t __attribute__ ((noinline)) riscv_intrinsic_max(uint32_t rs1, uint32_t rs2) { |
|
register uint32_t result __asm__ ("a0"); |
|
// max a0, a0, a1 |
CUSTOM_INSTR_R_TYPE(0b0000101, a1, a0, 0b110, a0, 0b0110011); |
|
return result; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation MAXU (select unsigned maximum) [B.Zbb] |
* |
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1. |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @param[in] rs2 Source operand 2 (a0). |
* @return Unsigned maximum. |
**************************************************************************/ |
uint32_t __attribute__ ((noinline)) riscv_intrinsic_maxu(uint32_t rs1, uint32_t rs2) { |
|
register uint32_t result __asm__ ("a0"); |
|
// maxu a0, a0, a1 |
CUSTOM_INSTR_R_TYPE(0b0000101, a1, a0, 0b111, a0, 0b0110011); |
|
return result; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation PACK (pack lower words) [B.Zbb] |
* |
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1. |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @param[in] rs2 Source operand 2 (a0). |
* @return Packed lower words. |
**************************************************************************/ |
uint32_t __attribute__ ((noinline)) riscv_intrinsic_pack(uint32_t rs1, uint32_t rs2) { |
|
register uint32_t result __asm__ ("a0"); |
|
// maxu a0, a0, a1 |
CUSTOM_INSTR_R_TYPE(0b0000100, a1, a0, 0b100, a0, 0b0110011); |
|
return result; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation ANDN (logical and-negate) [B.Zbb] |
* |
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1. |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @param[in] rs2 Source operand 2 (a0). |
* @return Operand 1 AND NOT operand 2. |
**************************************************************************/ |
uint32_t __attribute__ ((noinline)) riscv_intrinsic_andn(uint32_t rs1, uint32_t rs2) { |
|
register uint32_t result __asm__ ("a0"); |
|
// andn a0, a0, a1 |
CUSTOM_INSTR_R_TYPE(0b0100000, a1, a0, 0b111, a0, 0b0110011); |
|
return result; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation ORN (logical or-negate) [B.Zbb] |
* |
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1. |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @param[in] rs2 Source operand 2 (a0). |
* @return Operand 1 OR NOT operand 2. |
**************************************************************************/ |
uint32_t __attribute__ ((noinline)) riscv_intrinsic_orn(uint32_t rs1, uint32_t rs2) { |
|
register uint32_t result __asm__ ("a0"); |
|
// orn a0, a0, a1 |
CUSTOM_INSTR_R_TYPE(0b0100000, a1, a0, 0b110, a0, 0b0110011); |
|
return result; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation XNOR (logical xor-negate) [B.Zbb] |
* |
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1. |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @param[in] rs2 Source operand 2 (a0). |
* @return Operand 1 XOR NOT operand 2. |
**************************************************************************/ |
uint32_t __attribute__ ((noinline)) riscv_intrinsic_xnor(uint32_t rs1, uint32_t rs2) { |
|
register uint32_t result __asm__ ("a0"); |
|
// xnor a0, a0, a1 |
CUSTOM_INSTR_R_TYPE(0b0100000, a1, a0, 0b100, a0, 0b0110011); |
|
return result; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation ROL (rotate-left) [B.Zbb] |
* |
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1. |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @param[in] rs2 Source operand 2 (a0). |
* @return Operand 1 rotated left by operand_2(4:0) positions. |
**************************************************************************/ |
uint32_t __attribute__ ((noinline)) riscv_intrinsic_rol(uint32_t rs1, uint32_t rs2) { |
|
register uint32_t result __asm__ ("a0"); |
|
// rol a0, a0, a1 |
CUSTOM_INSTR_R_TYPE(0b0110000, a1, a0, 0b001, a0, 0b0110011); |
|
return result; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation ROR (rotate-right) [B.Zbb] |
* |
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1. |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @param[in] rs2 Source operand 2 (a0). |
* @return Operand 1 rotated right by operand_2(4:0) positions. |
**************************************************************************/ |
uint32_t __attribute__ ((noinline)) riscv_intrinsic_ror(uint32_t rs1, uint32_t rs2) { |
|
register uint32_t result __asm__ ("a0"); |
|
// ror a0, a0, a1 |
CUSTOM_INSTR_R_TYPE(0b0110000, a1, a0, 0b101, a0, 0b0110011); |
|
return result; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation RORI (rotate-right) by 20 positions. [B.Zbb] |
* |
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1. |
* @warning Fixed shift amount (20) for now. |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @return Operand 1 rotated right by 20 positions. |
**************************************************************************/ |
uint32_t __attribute__ ((noinline)) riscv_intrinsic_rori20(uint32_t rs1) { |
|
register uint32_t result __asm__ ("a0"); |
|
// rori a0, a0, 20 |
CUSTOM_INSTR_R1_TYPE(0b0110000, 0b10100, a0, 0b101, a0, 0b0010011); |
|
return result; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation ORC.B (or-combine byte) [B.Zbb] |
* |
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1. |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @return OR-combined bytes of operand 1. |
**************************************************************************/ |
uint32_t __attribute__ ((noinline)) riscv_intrinsic_orcb(uint32_t rs1) { |
|
register uint32_t result __asm__ ("a0"); |
|
// gorci a0, a0, 7 (pseudo-instruction: orc.b a0, a0) |
CUSTOM_INSTR_R1_TYPE(0b0010100, 0b00111, a0, 0b101, a0, 0b0010011); |
|
return result; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation REV8 (byte-swap) [B.Zbb] |
* |
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1. |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @return Byte swap of operand 1 |
**************************************************************************/ |
uint32_t __attribute__ ((noinline)) riscv_intrinsic_rev8(uint32_t rs1) { |
|
register uint32_t result __asm__ ("a0"); |
|
// grevi a0, a0, -8 (pseudo-instruction: rev8 a0, a0) |
CUSTOM_INSTR_R1_TYPE(0b0110100, 0b11000, a0, 0b101, a0, 0b0010011); |
|
return result; |
} |
|
|
// ################################################################################################ |
// Emulation functions |
// ################################################################################################ |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation CLZ (count leading zeros) [emulation] |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @return Number of leading zeros in source operand. |
**************************************************************************/ |
uint32_t riscv_emulate_clz(uint32_t rs1) { |
|
uint32_t sreg = rs1; |
uint32_t cnt = 0; |
|
while(1) { |
if (sreg & 0x80000000UL) { |
break; |
} |
else { |
sreg <<= 1; |
cnt++; |
} |
} |
|
return cnt; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation CTZ (count trailing zeros) [emulation] |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @return Number of trailing zeros in source operand. |
**************************************************************************/ |
uint32_t riscv_emulate_ctz(uint32_t rs1) { |
|
uint32_t sreg = rs1; |
uint32_t cnt = 0; |
|
while(1) { |
if (sreg & 1) { |
break; |
} |
else { |
sreg >>= 1; |
cnt++; |
} |
} |
|
return cnt; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation CPOP (population count) [emulation] |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @return Number of set bits in source operand. |
**************************************************************************/ |
uint32_t riscv_emulate_cpop(uint32_t rs1) { |
|
uint32_t sreg = rs1; |
uint32_t cnt = 0; |
int i; |
|
for (i=0; i<32; i++) { |
if (sreg & 1) { |
cnt++; |
} |
sreg >>= 1; |
} |
|
return cnt; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation SEXT.B (sign-extend byte) [emulation] |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @return Sign-extended byte (operand(7:0)). |
**************************************************************************/ |
uint32_t riscv_emulate_sextb(uint32_t rs1) { |
|
uint32_t tmp = rs1 & 0xff; |
|
if (tmp & 0x80) { |
tmp |= 0xFFFFFF00UL; |
} |
|
return tmp; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation SEXT.H (sign-extend half-word) [emulation] |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @return Sign-extended half-word (operand(15:0)). |
**************************************************************************/ |
uint32_t riscv_emulate_sexth(uint32_t rs1) { |
|
uint32_t tmp = rs1 & 0xffff; |
|
if (tmp & 0x8000) { |
tmp |= 0xFFFF0000UL; |
} |
|
return tmp; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation MIN (select signed minimum) [emulation] |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @param[in] rs2 Source operand 1 (a0). |
* @return Signed minimum. |
**************************************************************************/ |
uint32_t riscv_emulate_min(uint32_t rs1, uint32_t rs2) { |
|
int32_t s_opa = (int32_t)rs1; |
int32_t s_opb = (int32_t)rs2; |
|
if (s_opa < s_opb) { |
return rs1; |
} |
else { |
return rs2; |
} |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation MINU (select unsigned minimum) [emulation] |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @param[in] rs2 Source operand 1 (a0). |
* @return Unsigned minimum. |
**************************************************************************/ |
uint32_t riscv_emulate_minu(uint32_t rs1, uint32_t rs2) { |
|
if (rs1 < rs2) { |
return rs1; |
} |
else { |
return rs2; |
} |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation MAX (select signed maximum) [emulation] |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @param[in] rs2 Source operand 1 (a0). |
* @return Signed maximum. |
**************************************************************************/ |
uint32_t riscv_emulate_max(uint32_t rs1, uint32_t rs2) { |
|
int32_t s_opa = (int32_t)rs1; |
int32_t s_opb = (int32_t)rs2; |
|
if (s_opa < s_opb) { |
return rs2; |
} |
else { |
return rs1; |
} |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation MAXU (select unsigned maximum) [emulation] |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @param[in] rs2 Source operand 1 (a0). |
* @return Unsigned maximum. |
**************************************************************************/ |
uint32_t riscv_emulate_maxu(uint32_t rs1, uint32_t rs2) { |
|
if (rs1 < rs2) { |
return rs2; |
} |
else { |
return rs1; |
} |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation PACK (pack lower words) [emulation] |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @param[in] rs2 Source operand 1 (a0). |
* @return Unsigned maximum. |
**************************************************************************/ |
uint32_t riscv_emulate_pack(uint32_t rs1, uint32_t rs2) { |
|
uint32_t tmp_a = rs1 & 0xffff; |
uint32_t tmp_b = rs2 & 0xffff; |
|
return (tmp_b << 16) | tmp_a; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation ANDN (logical and-negate) [emulation] |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @param[in] rs2 Source operand 1 (a0). |
* @return Operand 1 AND NOT operand 2. |
**************************************************************************/ |
uint32_t riscv_emulate_andn(uint32_t rs1, uint32_t rs2) { |
|
return rs1 & (~rs2); |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation ORN (logical or-negate) [emulation] |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @param[in] rs2 Source operand 1 (a0). |
* @return Operand 1 OR NOT operand 2. |
**************************************************************************/ |
uint32_t riscv_emulate_orn(uint32_t rs1, uint32_t rs2) { |
|
return rs1 | (~rs2); |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation XNOR (logical xor-negate) [emulation] |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @param[in] rs2 Source operand 1 (a0). |
* @return Operand 1 XOR NOT operand 2. |
**************************************************************************/ |
uint32_t riscv_emulate_xnor(uint32_t rs1, uint32_t rs2) { |
|
return rs1 ^ (~rs2); |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation ROL (rotate-left) [emulation] |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @param[in] rs2 Source operand 1 (a0). |
* @return Operand 1 rotated left by operand_2(4:0) positions. |
**************************************************************************/ |
uint32_t riscv_emulate_rol(uint32_t rs1, uint32_t rs2) { |
|
uint32_t shamt = rs2 & 0x1f; |
|
uint32_t tmp_a = rs1 << shamt; |
uint32_t tmp_b = rs1 >> (32-shamt); |
|
return tmp_a | tmp_b; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation ROR (rotate-right) [emulation] |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @param[in] rs2 Source operand 1 (a0). |
* @return Operand 1 rotated right by operand_2(4:0) positions. |
**************************************************************************/ |
uint32_t riscv_emulate_ror(uint32_t rs1, uint32_t rs2) { |
|
uint32_t shamt = rs2 & 0x1f; |
|
uint32_t tmp_a = rs1 >> shamt; |
uint32_t tmp_b = rs1 << (32-shamt); |
|
return tmp_a | tmp_b; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation REV8 (byte swap) [emulation] |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @return Operand 1 byte swapped. |
**************************************************************************/ |
uint32_t riscv_emulate_rev8(uint32_t rs1) { |
|
uint32_t tmp_a = (rs1 & 0x000000ffUL) << 24; |
uint32_t tmp_b = (rs1 & 0x0000ff00UL) << 8; |
uint32_t tmp_c = (rs1 & 0x00ff0000UL) >> 8; |
uint32_t tmp_d = (rs1 & 0xff000000UL) >> 24; |
|
return tmp_a | tmp_b | tmp_c | tmp_d; |
} |
|
|
/**********************************************************************//** |
* Intrinsic: Bit manipulation ORCB (or-combine bytes) [emulation] |
* |
* @param[in] rs1 Source operand 1 (a0). |
* @return OR-combined bytes of operand 1. |
**************************************************************************/ |
uint32_t riscv_emulate_orcb(uint32_t rs1) { |
|
uint32_t tmp = 0; |
|
if (rs1 & 0x000000ffUL) { |
tmp |= 0x000000ffUL; |
} |
if (rs1 & 0x0000ff00UL) { |
tmp |= 0x0000ff00UL; |
} |
if (rs1 & 0x00ff0000UL) { |
tmp |= 0x00ff0000UL; |
} |
if (rs1 & 0xff000000UL) { |
tmp |= 0xff000000UL; |
} |
|
return tmp; |
} |
|
|
#endif // neorv32_b_extension_intrinsics_h |
|
/blink_led/main.c
3,7 → 3,7
// # ********************************************************************************************* # |
// # BSD 3-Clause License # |
// # # |
// # Copyright (c) 2020, Stephan Nolting. All rights reserved. # |
// # Copyright (c) 2021, Stephan Nolting. All rights reserved. # |
// # # |
// # Redistribution and use in source and binary forms, with or without modification, are # |
// # permitted provided that the following conditions are met: # |
86,6 → 86,9
// this is not required, but keeps us safe |
neorv32_rte_setup(); |
|
// check available hardware extensions and compare with compiler flags |
neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch |
|
// say hello |
neorv32_uart_print("Blinking LED demo program\n"); |
|
/coremark/core_portme.c
164,6 → 164,9
while(1); |
#endif |
|
// check available hardware extensions and compare with compiler flags |
neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch |
|
num_hpm_cnts_global = neorv32_cpu_hpm_get_counters(); |
|
// try to setup as many HPMs as possible |
/cpu_test/main.c
140,20 → 140,22
return 0; |
#endif |
|
neorv32_uart_printf("\n--- PROCESSOR/CPU TEST ---\n"); |
neorv32_uart_printf("\n<< PROCESSOR/CPU TEST >>\n"); |
neorv32_uart_printf("build: "__DATE__" "__TIME__"\n"); |
neorv32_uart_printf("This test suite is intended to verify the default NEORV32 processor setup using the default testbench.\n\n"); |
|
// check if we came from hardware reset |
neorv32_uart_printf("Coming from hardware reset? "); |
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_RESET) { |
neorv32_uart_printf("true\n"); |
neorv32_uart_printf("yes\n"); |
} |
else { |
neorv32_uart_printf("unknown (mcause != TRAP_CODE_RESET)\n"); |
} |
|
// check available hardware extensions and compare with compiler flags |
neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch |
|
|
// reset performance counter |
neorv32_cpu_set_minstret(0); |
neorv32_cpu_set_mcycle(0); |
183,7 → 185,7
|
// configure RTE |
// ----------------------------------------------- |
neorv32_uart_printf("\n\nInitializing NEORV32 run-time environment (RTE)... "); |
neorv32_uart_printf("\n\nInitializing NEORV32 RTE... "); |
|
neorv32_rte_setup(); // this will install a full-detailed debug handler for all traps |
|
208,7 → 210,7
install_err += neorv32_rte_exception_install(RTE_TRAP_FIRQ_3, global_trap_handler); |
|
if (install_err) { |
neorv32_uart_printf("RTE install error (%i)!\n", install_err); |
neorv32_uart_printf("RTE error (%i)!\n", install_err); |
return 0; |
} |
|
237,7 → 239,7
// Test standard RISC-V performance counter [m]cycle[h] |
// ---------------------------------------------------------- |
neorv32_cpu_csr_write(CSR_MCAUSE, 0); |
neorv32_uart_printf("[%i] Testing [m]instret[h] counters: ", cnt_test); |
neorv32_uart_printf("[%i] [m]instret[h] counter test: ", cnt_test); |
|
cnt_test++; |
|
262,7 → 264,7
// Test standard RISC-V performance counter [m]instret[h] |
// ---------------------------------------------------------- |
neorv32_cpu_csr_write(CSR_MCAUSE, 0); |
neorv32_uart_printf("[%i] Testing [m]cycle[h] counters: ", cnt_test); |
neorv32_uart_printf("[%i] [m]cycle[h] counter test: ", cnt_test); |
|
cnt_test++; |
|
287,7 → 289,7
// Test mcountinhibt: inhibit auto-inc of [m]cycle |
// ---------------------------------------------------------- |
neorv32_cpu_csr_write(CSR_MCAUSE, 0); |
neorv32_uart_printf("[%i] Testing mcountINHIBT.cy CSR: ", cnt_test); |
neorv32_uart_printf("[%i] mcountinhibt.cy CSR test: ", cnt_test); |
|
cnt_test++; |
|
323,7 → 325,7
// Test mcounteren: do not allow cycle[h] access from user-mode |
// ---------------------------------------------------------- |
neorv32_cpu_csr_write(CSR_MCAUSE, 0); |
neorv32_uart_printf("[%i] Testing mcounterEN.cy CSR: ", cnt_test); |
neorv32_uart_printf("[%i] mcounteren.cy CSR test: ", cnt_test); |
|
cnt_test++; |
|
1209,7 → 1211,7
// Test RTE debug trap handler |
// ---------------------------------------------------------- |
neorv32_cpu_csr_write(CSR_MCAUSE, 0); |
neorv32_uart_printf("[%i] RTE (runtime environment) debug trap handler test: ", cnt_test); |
neorv32_uart_printf("[%i] RTE (runtime env.) debug trap handler test: ", cnt_test); |
|
cnt_test++; |
|
1489,7 → 1491,7
// HPM reports |
// ---------------------------------------------------------- |
neorv32_cpu_csr_write(CSR_MCOUNTINHIBIT, -1); // stop all counters |
neorv32_uart_printf("\n\nHPM results:\n"); |
neorv32_uart_printf("\n\n-- HPM results --\n"); |
if (num_hpm_cnts_global == 0) {neorv32_uart_printf("no HPMs available\n"); } |
if (num_hpm_cnts_global > 0) {neorv32_uart_printf("# Retired compr. instructions: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER3)); } |
if (num_hpm_cnts_global > 1) {neorv32_uart_printf("# I-fetch wait cycles: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_MHPMCOUNTER4)); } |
1508,8 → 1510,8
// ---------------------------------------------------------- |
// Final test reports |
// ---------------------------------------------------------- |
neorv32_uart_printf("\nExecuted instructions: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_INSTRET)); |
neorv32_uart_printf( "Required clock cycles: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_CYCLE)); |
neorv32_uart_printf("\n# Instructions: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_INSTRET)); |
neorv32_uart_printf( "# Clock cycles: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_CYCLE)); |
|
neorv32_uart_printf("\nTest results:\nOK: %i/%i\nFAILED: %i/%i\n\n", cnt_ok, cnt_test, cnt_fail, cnt_test); |
|
/demo_freeRTOS/main.c
129,6 → 129,9
|
// init UART at default baud rate, no parity bits, no rx interrupt, no tx interrupt |
neorv32_uart_setup(BAUD_RATE, 0b00, 0, 0); |
|
// check available hardware extensions and compare with compiler flags |
neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch |
} |
|
/*-----------------------------------------------------------*/ |
/demo_gpio_irq/main.c
3,7 → 3,7
// # ********************************************************************************************* # |
// # BSD 3-Clause License # |
// # # |
// # Copyright (c) 2020, Stephan Nolting. All rights reserved. # |
// # Copyright (c) 2021, Stephan Nolting. All rights reserved. # |
// # # |
// # Redistribution and use in source and binary forms, with or without modification, are # |
// # permitted provided that the following conditions are met: # |
75,7 → 75,10
// init UART at default baud rate, no parity bits, no rx interrupt, no tx interrupt |
neorv32_uart_setup(BAUD_RATE, 0b00, 0, 0); |
|
// check available hardware extensions and compare with compiler flags |
neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch |
|
|
// check if GPIO unit is implemented at all |
if (neorv32_gpio_available() == 0) { |
neorv32_uart_print("ERROR! GPIO unit not synthesized!\n"); |
/demo_pwm/main.c
3,7 → 3,7
// # ********************************************************************************************* # |
// # BSD 3-Clause License # |
// # # |
// # Copyright (c) 2020, Stephan Nolting. All rights reserved. # |
// # Copyright (c) 2021, Stephan Nolting. All rights reserved. # |
// # # |
// # Redistribution and use in source and binary forms, with or without modification, are # |
// # permitted provided that the following conditions are met: # |
76,6 → 76,9
// init UART at default baud rate, no parity bits, no rx interrupt, no tx interrupt |
neorv32_uart_setup(BAUD_RATE, 0b00, 0, 0); |
|
// check available hardware extensions and compare with compiler flags |
neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch |
|
// say hello |
neorv32_uart_print("PWM demo program\n"); |
|
/demo_trng/main.c
3,7 → 3,7
// # ********************************************************************************************* # |
// # BSD 3-Clause License # |
// # # |
// # Copyright (c) 2020, Stephan Nolting. All rights reserved. # |
// # Copyright (c) 2021, Stephan Nolting. All rights reserved. # |
// # # |
// # Redistribution and use in source and binary forms, with or without modification, are # |
// # permitted provided that the following conditions are met: # |
82,6 → 82,9
// init UART at default baud rate, no parity bits, no rx interrupt, no tx interrupt |
neorv32_uart_setup(BAUD_RATE, 0b00, 0, 0); |
|
// check available hardware extensions and compare with compiler flags |
neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch |
|
// intro |
neorv32_uart_printf("\n--- TRNG Demo ---\n\n"); |
|
/demo_twi/main.c
3,7 → 3,7
// # ********************************************************************************************* # |
// # BSD 3-Clause License # |
// # # |
// # Copyright (c) 2020, Stephan Nolting. All rights reserved. # |
// # Copyright (c) 2021, Stephan Nolting. All rights reserved. # |
// # # |
// # Redistribution and use in source and binary forms, with or without modification, are # |
// # permitted provided that the following conditions are met: # |
86,6 → 86,9
// init UART at default baud rate, no parity bits, no rx interrupt, no tx interrupt |
neorv32_uart_setup(BAUD_RATE, 0b00, 0, 0); |
|
// check available hardware extensions and compare with compiler flags |
neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch |
|
// intro |
neorv32_uart_printf("\n--- TWI Bus Explorer ---\n\n"); |
|
/demo_wdt/main.c
3,7 → 3,7
// # ********************************************************************************************* # |
// # BSD 3-Clause License # |
// # # |
// # Copyright (c) 2020, Stephan Nolting. All rights reserved. # |
// # Copyright (c) 2021, Stephan Nolting. All rights reserved. # |
// # # |
// # Redistribution and use in source and binary forms, with or without modification, are # |
// # permitted provided that the following conditions are met: # |
79,6 → 79,9
// init UART at default baud rate, no parity bits, no rx interrupt, no tx interrupt |
neorv32_uart_setup(BAUD_RATE, 0b00, 0, 0); |
|
// check available hardware extensions and compare with compiler flags |
neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch |
|
// simple text output via UART (strings only) |
neorv32_uart_print("\nWatchdog system reset demo program\n\n"); |
|
/game_of_life/main.c
3,7 → 3,7
// # ********************************************************************************************* # |
// # BSD 3-Clause License # |
// # # |
// # Copyright (c) 2020, Stephan Nolting. All rights reserved. # |
// # Copyright (c) 2021, Stephan Nolting. All rights reserved. # |
// # # |
// # Redistribution and use in source and binary forms, with or without modification, are # |
// # permitted provided that the following conditions are met: # |
100,7 → 100,10
// init UART at default baud rate, no parity bits, no rx interrupt, no tx interrupt |
neorv32_uart_setup(BAUD_RATE, 0b00, 0, 0); |
|
// check available hardware extensions and compare with compiler flags |
neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch |
|
|
while (1) { |
|
int u = 0, cell = 0, n = 0; |
/hello_world/main.c
3,7 → 3,7
// # ********************************************************************************************* # |
// # BSD 3-Clause License # |
// # # |
// # Copyright (c) 2020, Stephan Nolting. All rights reserved. # |
// # Copyright (c) 2021, Stephan Nolting. All rights reserved. # |
// # # |
// # Redistribution and use in source and binary forms, with or without modification, are # |
// # permitted provided that the following conditions are met: # |
68,6 → 68,9
// init UART at default baud rate, no parity bits, no rx interrupt, no tx interrupt |
neorv32_uart_setup(BAUD_RATE, 0b00, 0, 0); |
|
// check available hardware extensions and compare with compiler flags |
neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch |
|
// print project logo via UART |
neorv32_rte_print_logo(); |
|
/hex_viewer/main.c
3,7 → 3,7
// # ********************************************************************************************* # |
// # BSD 3-Clause License # |
// # # |
// # Copyright (c) 2020, Stephan Nolting. All rights reserved. # |
// # Copyright (c) 2021, Stephan Nolting. All rights reserved. # |
// # # |
// # Redistribution and use in source and binary forms, with or without modification, are # |
// # permitted provided that the following conditions are met: # |
85,6 → 85,9
// init UART at default baud rate, no parity bits, no rx interrupt, no tx interrupt |
neorv32_uart_setup(BAUD_RATE, 0b00, 0, 0); |
|
// check available hardware extensions and compare with compiler flags |
neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch |
|
// intro |
neorv32_uart_printf("\n--- Hex Viewer ---\n\n"); |
|