Soft AVR Core + Interfaces

Project maintainers


Name: softavrcore
Created: Jun 16, 2020
Updated: Aug 19, 2023
SVN Updated: Dec 7, 2020
SVN: Browse
Latest version: download (might take a bit to start...)
Statistics: View
Bugs: 0 reported / 0 solved
Star10you like it: star it!

Other project properties

Development status:Stable
Additional info:Design done, FPGA proven
WishBone compliant: No
WishBone version: n/a
License: LGPL

Soft AVR Core + Interfaces


This package is a full-stack implementation of the AVR 2-stage pipeline, featuring synthesis for AVR2 (classic core), AVR2.5 (classic plus), AVR3 (with extended program memory), AVR4 (enhanced core) and AVR5 (enhanced core with extended program memory). Interrupts are supported with customized number of IRQ vector width, including automatic interrupt acknowledgement. The core is capable to run FreeRTOS.

The project comes with some example peripherals, such as UART, SPI, a basic timer, output port, SysTick timer and a CRC calculation unit.

Synthetized and tested using various tools, including free & open source packages:

  • iCE40HX8K-BG121 and iCE40HX8K-CT256 (on ICE40HX8K-B-EVN and custom design boards): Project IceStorm: yosys-0.9, nextpnr-ice40 and icestorm utilities;
  • iCE40HX8K-BG121 and iCE40HX8K-CT256 (on ICE40HX8K-B-EVN and custom design boards): Lattice iCEcube2; and
  • XA7A100T-1CSG324 (on a Digilent Nexys A7 board): Xilinx Vivado 2019.1.

Software run by the core can seamlessly be built with the AVR-GCC toolchain. This bundle includes utilities aiding the conversion from ELF output to BRAM initializations (designed for iCE40 EBRs) or generic synchronous ROM interface to set up the initial program memory. A configurable startup code (crt0.s, crt0.S) is included in the package with options to be matched to the synthetized core architecture.

Flight heritage: This core, along with the peripherals included this package - and extended with custom ones - are in operation onboard the GRBAlpha nanosatellite since 2021-03-22. GRBAlpha is an 1U CubeSat technology demonstration mission where the goal is to validate the feasibility of detecting and characterizing gamma-ray bursts on such a small satellite.


This package is available from Select the softavrcore-latest.tar.gz file for the latest version. Comments are welcomed! Contact information: see ./core/avr_core.v.

Getting started

  • On a Linux system, install the following toolchains and utilities:

    • gcc-avr
    • avr-libc
    • binutils-avr
    • icestorm
    • yosys
    • nextpnr-ice40

    then enter make in the main directory. This will compile the example C code (found in ./build, which is actually a symlink to ./build-test by default) and then run the synthesis and place-and-route targeted for the ICE40HX8K-B-EVN board. This step is automatically following by the generation of the FPGA configuration bitstream for iCE40HX8K-CT256 in the file top.bin.

  • On another operating systems for non-Lattice FPGA targets:

    • use the corresponding AVR port to compile the source and create the main.bin file. A working bash/awk is needed to automatically create the *.v files containing the flash interface for this virtual MCU. These are available on MacOS by default. On Windows, you may need to install additional components (e.g. Cygwin).
    • Collect the source .v files, including the core (avrcore.v), peripherals (avr_io.v), flash interface (main.v), data memory (ram.v) and the top module (top.v) into a single directory if your operating system does not support symlinks.
    • Import the top.v to your synthesis toolchain (icecube2, vivado, ...). You can use the shipped *.pcf files for Lattice tools (such as icecube2) without any further modifications. For Xilinx, you may use the file top-digilent_nexys_a7-cx7a100t.xdc as a starting point, or use it without any modifications for the Digilent Nexys A7 board.

Note that changing the layout of the system memory configuration requires some attention during the build process and the synthesis and needs to be performed in accordance. The examples found in the project have only hard-wired values for program memory size and RAM size. Therefore modifications of the source code must be performed in accordance to the synthesis parameter configurations.

  • By default, the example code (./build-test/main.c) sends the following series of messages via the built-in secondary UART interface of the ICE40HX8K-B-EVN board at 115200 baud:

    [x] 0 => 0

    [x] 1 => 1

    [x] 2 => 4

    [x] 3 => 9

    [x] 4 => 16

    [x] 5 => 25

    [x] 6 => 36

    Here the cadence is one message per minute. The cores and the C code expect a 12MHz clock input for baud rate configuration and during the computation of the timer delay. You may change the contents of the main() function to switch to another examples. Note also that the example is fitted for 4096 words of program code (i.e. 8k bytes of program flash memory), however, the actual binary size is less than 2048 bytes so less amount of embedded block RAM cells are also sufficient. Change top.v and ./build-test/Makefile accordingly for another program memory configurations.

  • The FreeRTOS port (./build-freertos/main.c) exploits the SysTick peripheral to generate interrupts for the AVR port (see ./build-freertos/port.c). Due to the simplicity of the SysTick peripheral (see ./peripherals/avr_systick.v), this port, esp. the timer configuration (see ./build-freertos/port.c:prvSetupTimerInterrupt) is much more lightweight than the original FreeRTOS port for AVRs. Besides this SysTick peripheral, the port itself is nearly identical to the default AVR FreeRTOS port. This example running FreeRTOS creates and runs two tasks: one of the tasks is blinking a LED periodically while the another task reads and writes two FreeRTOS queues in order to access the serial port (UART0, see ./peripherals/avr_io_uart.v). These queues feed and are fed by the interrupt service routine assigned to the UART. The task then converts lowercase text received from this UART (via the respective queue) to uppercase text and sends the text back to the UART (via its queue). Otherwise, the idle tasks put the CPU into sleep mode to save power.

Note that the synthesis grabs the flash contents from the ./build directory, i.e. it should be a symlink to one of the aforementioned examples. Change this link to ./build-freertos to test and run the FreeRTOS example on the FPGA board.

Known issues for the most recent version (softavrcore-20230819.tgz)

  • SPM instruction is not supported, however, equivalent self-programming interfaces can be synthetized by custom peripherals.
  • Fuse bits and in-system programming are not supported. These are, in practice, nearly meaningless on such an FPGA-based CPU/MCU implementation.

See also CHANGELOG for the most recent changes.

Hopefully coming soon

  • I2C peripheral
  • CAN bus interface
  • An implementation of the AVR architecture using a 4-stage pipeline
  • some more detaild documentation