Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A Board Configuration Example for The Freedom E310 Arty FPGA Dev Kit #148

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
212 changes: 212 additions & 0 deletions config/riscv32/boards/freedom-e310-arty/README.md
Original file line number Diff line number Diff line change
@@ -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
... <invoke an OpenOCD server (See above)> ...
$ 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": [],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these supposed to be removed?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean "args" and "environment"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. The two lines are useless for execution environments on FPGAs.

Instead, it's better to add the following line.

See Configuring C/C++ debugging for more configuration options.

"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.
82 changes: 82 additions & 0 deletions config/riscv32/boards/freedom-e310-arty/board.cfg
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
# Contributor Jeremy Bennett <[email protected]>
#
# 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']
56 changes: 56 additions & 0 deletions config/riscv32/boards/freedom-e310-arty/boardsupport.c
Original file line number Diff line number Diff line change
@@ -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 <support.h>
#include <stdint.h>
#include <stdio.h>

// RTC is not implemented
// #include <metal/rtc.h>

// 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();
}
10 changes: 10 additions & 0 deletions config/riscv32/boards/freedom-e310-arty/boardsupport.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* Copyright (C) 2017 Embecosm Limited and University of Bristol

Contributor Graham Markall <[email protected]>

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 */
Loading