From 07d0cd4201c17e14078a0297091f6a74ce9b6709 Mon Sep 17 00:00:00 2001 From: Hiroo HAYASHI <24754036+hirooih@users.noreply.github.com> Date: Mon, 11 Oct 2021 22:42:31 +0900 Subject: [PATCH 1/2] A Board Configuration for The Freedom E310 Arty FPGA Dev Kit --- .../boards/freedom-e310-arty/README.md | 212 ++++++++++++++++++ .../boards/freedom-e310-arty/board.cfg | 82 +++++++ .../boards/freedom-e310-arty/boardsupport.c | 56 +++++ .../boards/freedom-e310-arty/boardsupport.h | 10 + pylib/run_freedom-e310-arty.py | 111 +++++++++ 5 files changed, 471 insertions(+) create mode 100644 config/riscv32/boards/freedom-e310-arty/README.md create mode 100644 config/riscv32/boards/freedom-e310-arty/board.cfg create mode 100644 config/riscv32/boards/freedom-e310-arty/boardsupport.c create mode 100644 config/riscv32/boards/freedom-e310-arty/boardsupport.h create mode 100644 pylib/run_freedom-e310-arty.py diff --git a/config/riscv32/boards/freedom-e310-arty/README.md b/config/riscv32/boards/freedom-e310-arty/README.md new file mode 100644 index 00000000..ec91fc07 --- /dev/null +++ b/config/riscv32/boards/freedom-e310-arty/README.md @@ -0,0 +1,212 @@ +# A Board Configuration for The Freedom E310 Arty FPGA Dev Kit + +Author: Hiroo HAYASHI + +Copyright (C) 2021 Hiroo HAYASHI + +This document is part of Embench. +It is made freely available under the terms of the GNU Free Documentation +License version 1.2 or later. + +Embench is a trade mark of the Embench Task Group of the Free and Open Source +Silicon Foundation. + +*** + +This configuration demonstrates how to run the Embench on an FPGA board. +No performance tuning is done. Your contributions are welcome. + +## Requirements + +- [Digilent Arty A7 100T Reference board](https://digilent.com/reference/programmable-logic/arty-a7/start) +- [The Freedom E310 Arty FPGA Dev Kit](https://github.com/sifive/freedom#freedom-e300-arty-fpga-dev-kit) + - The data memory size of the default configuration for Arty A7 35T is too small for the Embench. + See [Configuring FPGA](#FPGA) for details. +- [SiFive Freedom E SDK](https://github.com/sifive/freedom-e-sdk) + +## Configuring FPGA + +See the following links. + +- [The Freedom E310 Arty FPGA Dev Kit](https://github.com/sifive/freedom#freedom-e300-arty-fpga-dev-kit) +- [Running a RISC-V Processor on the Arty A7](https://digilent.com/reference/programmable-logic/arty-a7/arty_a7_100_risc_v/start) + +Notes: + +- `vlsi_rom_gen` script fails with python3.5 or higher. + [Here](https://github.com/hex-five/multizone-fpga/issues/9) is a workaround. + See [this](https://github.com/chipsalliance/rocket-chip/issues/1991) for more details. +- The baud rate of UART is 57600 instead of 115200 as documented. + See [this Q&A](https://forums.sifive.com/t/uploading-to-my-arty-board-not-working/323/21). + +Make sure that the generated MCS file works. See the E310 E SDK document how to test it. + +Next apply the following changes to increase the size of data memory, and build the FPGA again. + +`freedom/Makefile.e300artydevkit` + +```diff +@@ -6,7 +6,7 @@ MODEL := E300ArtyDevKitFPGAChip + PROJECT := sifive.freedom.everywhere.e300artydevkit + export CONFIG_PROJECT := sifive.freedom.everywhere.e300artydevkit + export CONFIG := E300ArtyDevKitConfig +-export BOARD := arty ++export BOARD := arty_a7_100 + export BOOTROM_DIR := $(base_dir)/bootrom/xip + + rocketchip_dir := $(base_dir)/rocket-chip +``` + +`freedom/rocket-chip/src/main/scala/subsystem/Configs.scala` + +```diff +@@ -85,7 +85,7 @@ class With1TinyCore extends Config((site, here, up) => { + btb = None, + dcache = Some(DCacheParams( + rowBits = site(SystemBusKey).beatBits, +- nSets = 256, // 16Kb scratchpad ++ nSets = 8192, // 512Kb scratchpad + nWays = 1, + nTLBEntries = 4, + nMSHRs = 0, +``` + +`freedom-e-sdk/bsp/freedom-e310-arty/metal.default.lds` + +```diff +@@ -12,7 +12,7 @@ ENTRY(_enter) + MEMORY + { + itim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x4000 +- ram (arw!xi) : ORIGIN = 0x80000000, LENGTH = 0x4000 ++ ram (arw!xi) : ORIGIN = 0x80000000, LENGTH = 0x80000 + rom (irx!wa) : ORIGIN = 0x20400000, LENGTH = 0x1fc00000 + } + +``` + +It is a kind of magic, isn't it? + +See the following link for more details; + +- [How to Increase the Size of the Data Memory on SiFive FE310 RISC-V](https://dloghin.medium.com/how-to-increase-the-size-of-the-data-memory-on-sifive-fe310-risc-v-f05df0f50a25) + +## Running Embench + +### Preparations + +Set the environment variables `PATH` and etc. following the Freedom E SDK document. +Set the environment variable `FREEDOM_E_SDK_PATH` to the directory of the Freedom E SDK installed. For example; + +```sh +export FREEDOM_E_SDK_PATH=/home/foo/github/freedom-e-sdk +``` + +If you have a Debug Adapter other than Olimex ARM-USB-TINY-H, +modify `bsp/freedom-e310-arty/openocd.cfg` as follows; + +```diff +@@ -19,7 +19,7 @@ set debug_config "${protocol}_${connection}" + switch ${debug_config} { + jtag_probe { + echo "Using JTAG" +- source [find interface/ftdi/olimex-arm-usb-tiny-h.cfg] ++ source [find interface/ftdi/olimex-arm-usb-ocd-h.cfg] + set chain_length 5 + } + cjtag_probe { + +``` + +### Build + +```sh +./build_all.py -v --arch riscv32 --chip generic --board freedom-e310-arty --cpu-mhz=32 +``` + +### Size Test + +```sh +./benchmark_size.py +``` + +### Speed Test + +Invoke an OpenOCD server in a terminal window. + +```sh +/opt/SiFive/riscv-openocd-0.10.0-2020.12.1-x86_64-linux-ubuntu14/bin/openocd -f bsp/freedom-e310-arty/openocd.cfg +``` + +Run the following command in a terminal window. +(The device name `/dev/ttyUSB2` may be different on your system.) + +```sh +stty -F /dev/ttyUSB2 57600 +cat /dev/ttyUSB2 +``` + +Run the speed benchmark. + +```sh +./benchmark_speed.py --target-module run_freedom-e310-arty --timeout=600 +``` + +On Windows Subsystem for Linux (WSL) invoke an OpenOCD server on Windows +and connect to it by using `--gdbserver-target` option. + +```sh +./benchmark_speed.py --target-module run_freedom-e310-arty --timeout=600 --gdbserver-target $(grep -oP "(?<=nameserver ).+" /etc/resolv.conf):3333 +``` + +## Debugging + +### Debugging with GDB + +Example: + +```sh +... ... +$ cat gdbconf +set confirm off +set remotetimeout 240 +set remote hardware-breakpoint-limit 2 +target extended-remote localhost:3333 +monitor reset halt +monitor flash protect 0 64 last off +load +break _exit +$ riscv64-unknown-elf-gdb -q -x gdbconf bd/src/md5sum/md5sum +... +(gdb) run +... +``` + +Use `load` command to reload a recompiled program. + +### Debugging in VS Code + +Example of `launch.json`: + +```json + { + "name": "(gdb) Launch Remote", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/bd/src/nbody/nbody", + // "args": [], + "cwd": "${workspaceRoot}", + // "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "miDebuggerPath": "riscv64-unknown-elf-gdb", + "miDebuggerServerAddress": "localhost:3333", + "hardwareBreakpoints": { "require": true, "limit": 2 }, + }, +``` + +Invoke an OpenOCD server (See above). + +`Run`->`Start Debugging` (or `F5`), Select `(gdb) Launch Remote`. +Use `-exec load` command in `DEBUG CONSOLE` to reload a recompiled program. +Now you can debug a program using the common VS Code GUI. diff --git a/config/riscv32/boards/freedom-e310-arty/board.cfg b/config/riscv32/boards/freedom-e310-arty/board.cfg new file mode 100644 index 00000000..bd3fa8c1 --- /dev/null +++ b/config/riscv32/boards/freedom-e310-arty/board.cfg @@ -0,0 +1,82 @@ +# Board configuration for Freedom E SDK on Arty A7 +# +# Copyright (C) 2021 Hiroo HAYASHI +# Copyright (C) 2019 Embecosm Limited and the University of Bristol +# +# Contributor Graham Markall +# Contributor Jeremy Bennett +# +# This file is part of Embench and was formerly part of the Bristol/Embecosm +# Embedded Benchmark Suite. +# +# SPDX-License-Identifier: GPL-3.0-or-later + +# This is a python setting of parameters for the board. The following +# parameters may be set (other keys are silently ignored). Defaults are shown +# in brackets +# - cc ('cc') +# - ld (same value as for cc) +# - cflags ([]) +# - ldflags ([]) +# - cc_define_pattern ('-D{0}') +# - cc_incdir_pattern ('-I{0}') +# - cc_input_pattern ('{0}') +# - cc_output_pattern ('-o {0}') +# - ld_input_pattern ('{0}') +# - ld_output_pattern ('-o {0}') +# - user_libs ([]) +# - dummy_libs ([]) +# - cpu_mhz (1) +# - warmup_heat (1) + +# The "flags" and "libs" parameters (cflags, ldflags, user_libs, dummy_libs) +# should be lists of arguments to be passed to the compile or link line as +# appropriate. Patterns are Python format patterns used to create arguments. +# Thus for GCC or Clang/LLVM defined constants can be passed using the prefix +# '-D', and the pattern '-D{0}' would be appropriate (which happens to be the +# default). + +# "user_libs" may be absolute file names or arguments to the linker. In the +# latter case corresponding arguments in ldflags may be needed. For example +# with GCC or Clang/LLVM is "-l" flags are used in "user_libs", the "-L" flags +# may be needed in "ldflags". + +# Dummy libs have their source in the "support" subdirectory. Thus if 'crt0' +# is specified, there should be a source file 'dummy-crt0.c' in the support +# directory. + +# There is no need to set an unused parameter, and this file may be empty to +# set no flags. + +# Parameter values which are duplicated in architecture, board, chip or +# command line are used in the following order of priority +# - default value +# - architecture specific value +# - chip specific value +# - board specific value +# - command line value + +# For flags, this priority is applied to individual flags, not the complete +# list of flags. + +try: + e_sdk_path = os.environ['FREEDOM_E_SDK_PATH'] +except KeyError as e: + log.error(f'ERROR: Environment variable {str(e)} is not set') + raise + +cpu_mhz = 1 +cc = 'riscv64-unknown-elf-gcc' +cflags = [ + '-c', '-march=rv32imac', '-mabi=ilp32', '-mcmodel=medlow', '-ffunction-sections', '-fdata-sections', + '-I' + e_sdk_path + '/bsp/freedom-e310-arty/install/include', '--specs=nano.specs', '-O2', '-Os', '-g' +] +ldflags = [ + '-march=rv32imac', '-mabi=ilp32', '-Wl,--gc-sections', '-nostartfiles', '-nostdlib', + '-L' + e_sdk_path + '/bsp/freedom-e310-arty/install/lib/debug/', + '-T' + e_sdk_path + '/bsp/freedom-e310-arty/metal.default.lds', + # The default stack size 0xf00 is too small. + # See freedom-e-sdk/bsp/freedom-e310-arty/metal.default.lds + '-Xlinker', '--defsym=__stack_size=0x1f00', +] +user_libs = ['-Wl,--start-group', '-lc', '-lgcc', '-lm', '-lmetal', '-lmetal-gloss', '-Wl,--end-group'] diff --git a/config/riscv32/boards/freedom-e310-arty/boardsupport.c b/config/riscv32/boards/freedom-e310-arty/boardsupport.c new file mode 100644 index 00000000..3c87b2b5 --- /dev/null +++ b/config/riscv32/boards/freedom-e310-arty/boardsupport.c @@ -0,0 +1,56 @@ +/* Copyright (C) 2021 Hiroo HAYASHI + + This file is part of Embench and was formerly part of the Bristol/Embecosm + Embedded Benchmark Suite. + + SPDX-License-Identifier: GPL-3.0-or-later */ + +#include +#include +#include + +// RTC is not implemented +// #include + +// gdb "info reg mcycle" does not return proper value. +uint64_t mcycle; + +void +clear_mcycle () +{ + __asm__ volatile ("csrwi mcycle, 0"); + __asm__ volatile ("csrwi mcycleh, 0"); + __asm__ volatile ("csrwi mcycle, 0"); +} + +uint64_t +rdmcycle () +{ + uint32_t lo, hi1, hi2; + // cf. RISC-V Unprivileged ISA, 10.1 Base Counters and Timers + __asm__ __volatile__ ("1:\n\t" \ + "csrr %0, mcycleh\n\t" \ + "csrr %1, mcycle\n\t" \ + "csrr %2, mcycleh\n\t" \ + "bne %0, %2, 1b\n\t" \ + : "=r" (hi1), "=r" (lo), "=r" (hi2)); + return (uint64_t)hi1 << 32 | lo; +} + +void __attribute__ ((noinline)) __attribute__ ((externally_visible)) +initialise_board () +{ + __asm__ volatile ("li a0, 0" : : : "memory"); +} + +void __attribute__ ((noinline)) __attribute__ ((externally_visible)) +start_trigger () +{ + clear_mcycle(); +} + +void __attribute__ ((noinline)) __attribute__ ((externally_visible)) +stop_trigger () +{ + mcycle = rdmcycle(); +} diff --git a/config/riscv32/boards/freedom-e310-arty/boardsupport.h b/config/riscv32/boards/freedom-e310-arty/boardsupport.h new file mode 100644 index 00000000..9f46db95 --- /dev/null +++ b/config/riscv32/boards/freedom-e310-arty/boardsupport.h @@ -0,0 +1,10 @@ +/* Copyright (C) 2017 Embecosm Limited and University of Bristol + + Contributor Graham Markall + + This file is part of Embench and was formerly part of the Bristol/Embecosm + Embedded Benchmark Suite. + + SPDX-License-Identifier: GPL-3.0-or-later */ + +/* #define CPU_MHZ 1 */ diff --git a/pylib/run_freedom-e310-arty.py b/pylib/run_freedom-e310-arty.py new file mode 100644 index 00000000..bbe46641 --- /dev/null +++ b/pylib/run_freedom-e310-arty.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python3 + +# Python module to run programs on an openocd server + +# Copyright (C) 2021 Hiroo HAYASHI +# Copyright (C) 2019 Embecosm Limited +# +# Contributor: Jeremy Bennett +# +# This file is part of Embench. + +# SPDX-License-Identifier: GPL-3.0-or-later + +""" +Embench module to run benchmark programs. + +This version is suitable for an openocd server. +""" + +__all__ = [ + 'get_target_args', + 'build_benchmark_cmd', + 'decode_results', +] + +import argparse +import re + +from embench_core import log + + +def get_target_args(remnant): + """Parse left over arguments""" + parser = argparse.ArgumentParser(description='Get target specific args') + + parser.add_argument( + '--gdb-command', + type=str, + default='riscv64-unknown-elf-gdb', + help='Command to invoke GDB', + ) + parser.add_argument( + '--gdbserver-command', + type=str, + default='extended-remote', + help='Command to invoke the GDB server', + ) + parser.add_argument( + '--gdbserver-target', + type=str, + default='localhost:3333', + help='target argument to the GDB server', + ) + + return parser.parse_args(remnant) + + +def build_benchmark_cmd(bench, args): + """Construct the command to run the benchmark. "args" is a + namespace with target specific arguments""" + + cmd = [f'{args.gdb_command}', '-q'] + gdb_comms = [ + 'set confirm off', + 'set style enabled off', + 'set height 0', + 'file {0}', + 'set remotetimeout 240', + f'target {args.gdbserver_command} {args.gdbserver_target}', + 'monitor reset halt', + 'monitor flash protect 0 64 last off', + 'load', + 'break _exit', + 'monitor echo \"running {0}\n\"', + 'run', + 'p exit_status', + 'p/x mcycle', + 'detach', + 'quit', + ] + + for arg in gdb_comms: + cmd.extend(['-ex', arg.format(bench)]) + + return cmd + + +def decode_results(stdout_str, stderr_str): + """Extract the results from the output string of the run. Return the + elapsed time in milliseconds or zero if the run failed.""" + # Return code is in standard output. We look for the string that means we + # hit a breakpoint on _exit, then for the string returning the value. + rcstr = re.search('^\$1 = (\d+)', stdout_str, re.M) + if not rcstr: + log.debug('Warning: Failed to find return code') + return 0.0 + exit_status = int(rcstr.group(1)) + if exit_status: + log.debug('Warning: verify_benchmark() failed') + return 0.0 + + # mcycle + rcstr = re.search('^\$2 = 0x(\w+)', stdout_str, re.M) + if not rcstr: + log.debug('Warning: Failed to find mcycle value') + return 0.0 + mcycle = int(rcstr.group(1), 16) + + # mcycle @32.5MHz clock + ms_elapsed = float(mcycle) / 32500.0 + return ms_elapsed From de60cc519a891a38378abdfab10e7e96f4f33dd8 Mon Sep 17 00:00:00 2001 From: hirooih <24754036+hirooih@users.noreply.github.com> Date: Thu, 28 Oct 2021 23:31:00 +0900 Subject: [PATCH 2/2] Add link to "Configuring C/C++ debugging" Remove useless comments. Add link to a link to VS code documentation. --- config/riscv32/boards/freedom-e310-arty/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/config/riscv32/boards/freedom-e310-arty/README.md b/config/riscv32/boards/freedom-e310-arty/README.md index ec91fc07..7c2536e5 100644 --- a/config/riscv32/boards/freedom-e310-arty/README.md +++ b/config/riscv32/boards/freedom-e310-arty/README.md @@ -187,6 +187,7 @@ Use `load` command to reload a recompiled program. ### Debugging in VS Code Example of `launch.json`: +See [Configuring C/C++ debugging](https://code.visualstudio.com/docs/cpp/launch-json-reference) for more configuration options. ```json { @@ -194,9 +195,7 @@ Example of `launch.json`: "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/bd/src/nbody/nbody", - // "args": [], "cwd": "${workspaceRoot}", - // "environment": [], "externalConsole": false, "MIMode": "gdb", "miDebuggerPath": "riscv64-unknown-elf-gdb",