A 32 bit RISC-V processor with 5 pipeline stages and in-order execution. The architecture avoids speculative components to provide a predictable timing as required by hard real-time systems. It started as a submission to the 2018 RISC-V SoftCPU Contest called Danzig. RudolV won the third prize in the 2019 RISC-V SoftCPU Contest on Security .
EXCUSE: Xilinx and Altera ports are not up-to-date.
RISC-V SoftCPU Contest on Security
The objective of the contest is to thwart 5 particular attacks of RIPE, the Runtime Intrusion Prevention Evaluator. RudolV can detect all these 5 attacks and responds with an exception. No compiler modifications are necessary.
- Future Electronics - Microsemi Creative Development Board with IGLOO 2 M2GL025-VF256 FPGA
- Libero 12.1 (Howto install Libero on Ubuntu)
- Zephyr SDK 0.10.0 (only this version fits Zephyr OS v1.14.1-rc1 which is required by the contest)
- Plug in the Creative Board.
- Open the project file
- Choose the
schematictab and click on the leftmost icon to generate the component.
- Click on Program Design/Run PROGRAM Action within the
Design Flowtab to synthesize the bitstream and program the FPGA board.
Alternatively the complete bitstream can be downloaded as release
from the RudolV GitHub repository.
After pushing the reset button, RudolV waits for the binary application image to be transfered via the UART. The format is simple: first send the length of the image (in bytes) as decimal ASCII string. Followed by a blank (0x20) and then the binary data. The following script can be used:
sw/bootloader/send_image.sh /dev/ttyUSB0 image.bin
To check what happens without the grubby attack detection, edit line 74 in
scripts/libero/proj/iot_contest/hdl/withmem.v and set
MemRGrubby to 0.
After synthesis and programming the attacks will be successful.
Build the software
RudolV is binary compatible to Mi-V for the Creative Board therefore binaries
can be build the same way as descibed in the
After building an application, the raw binary image
zephyr.bin can be found
in the Zephyr build directory. To run it use
sw/bootloader/send_image.sh /dev/ttyUSB0 zephyr.bin
To build the RIPE binaries make sure that the environmental variable
ZEPHYR_SDK_INSTALL_DIR points to the Zephyr SDK directory.
If there is already a Zephyr installation, set
ZEPHYR_BASE accoringly and
ZEPHYR_TOOLCHAIN_VARIANT=zephyr. Otherwise Zephyr OS v1.14.1-rc1 can be
instaled locally with
cd sw/zephyr source ./make.sh zephyr
Build the RIPE attack binaries
Run the attacks
Use a terminal emulator like picocom at 115200 baud to receive the output of RIPE:
picocom -b 115200 /dev/ttyUSB0
Now push the reset button on the Creative Board and transfer the binary image of an attack to the bootloader of RudolV:
sw/bootloader/send_image.sh /dev/ttyUSB0 sw/zephyr/build/ripe1.rv32im.bin
For the other attacks use
How does the detection work?
All attacks have in common, that they alter the memory byte by byte, not with full 32 bit writes. Therefore RudolV uses an additional grubby bit for each memory location to keep track of words that were not written as a whole. If RudolV fetches an instruction word with the grubby bit set, it throws exception 14. If it loads a grubby word and uses it as target address for a jump, exception 10 is thrown.
Chip resources for the IGLOO 2 port of RudolV
Data hatzards are avoided by operand forwarding, therefore most instructions are executed in one cycle. Since the memory is single ported, memory accesses take two cycles. The jump target is computed in the execute stage, resulting in a two cycle latency. There is no dynamic branch prediction but subsequent instructions are only killed in the case of a taken branch. This behaviour can be considered as a static always not taken prediction.
|RV32M||MUL, DIV, ...||34|
|unconditional jump||JAL, JALR||3|
|taken branch||BEQ, ...||3|
|CSR access||CSRRW, ...||2|
|memory access||LB, LW, SH, ...||2|
|not taken branch||BEQ, ...||1|
|barrel shifter||SLL, SRL, SRA||1|
Simulation and testing with Icarus Verilog
Run riscv-tests with Icarus Verilog
make -C sw/tests/ make -C scripts/icarus/ test-all
Run riscv-compliance tests with Icarus Verilog
make -C sw/compliance/ cd scripts/icarus/ ./run_compliance_tests.h
Run Dhrystone benchmark from riscv-tests repository wirh Icarus Verilog
make -C sw/riscv-dhrystone/ make -C scripts/icarus/ riscv-dhrystone
Run Dhrystone benchmark from picorv32 repository wirh Icarus Verilog
make -C sw/picorv32-dhrystone/ make -C scripts/icarus/ picorv32-dhrystone
|DMIPS/MHz||Dhrystones/s/MHz||CPI||cycles per Dhrystone|
Synthesis with IceStorm
Synthesize with Project IceStorm and flash to a Lattice iCE40 UltraPlus MDP board. The board must be configured to flash and run FPGA U4.
cd scripts/icestorm ./make.sh uwg30 bootloader synth pnr prog
Now the processor within the FPGA executes the bootloader and waits for data from the UART. To run the Dhrystone benchmark on the FPGA use:
make -C sw/riscv-dhrystone sw/uart/send_elf.sh /dev/ttyUSB1 sw/riscv-dhrystone/dhrystone.elf
This Dhrystone version is derived from the risv-tests version, but with the correct clock frequency of 24 MHz and 100'000 iterations. The result is 32697 Dhrystones per second. To see the output use a terminal emulator like picocom at 115200 baud:
picocom -b 115200 --imap lfcrlf /dev/ttyUSB1
The processor logic and the bootloader are written to the flash memory. Hence, the
processor can be reset with switch SW2 of the MDP board. After switching it back and
send_elf.sh can be used again to start a new program on the processor.
|chip resources||unit||default||no counters||no exceptions||minimal|
CoreMark EEMBC benchmark scores
Run one iteration of EEMBC CoreMark with Icarus Verilog:
make -C sw/coremark/ run-icarus
The results can be found in
sw/coremark/coremark/run1.log. Since this is a
simulation, the error message can be ignored and the computed iterations/sec
corresponds to CoreMark/MHz.
To get the CoreMark of an FPGA implementation, build an image with UART output and send it to the bootloader:
make -C sw/coremark/ build-uart sw/bootloader/send_elf.sh /dev/ttyUSB1 sw/coremark/coremark_uart.elf
The CoreMark/MHz of RudolV is 0.892.
Licensed under the ISC licence (similar to the MIT/Expat license).