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:
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 https://szofi.net/pub/verilog/softavrcore/. Select the softavrcore-latest.tar.gz file for the latest version. Comments are welcomed! Contact information: see ./core/avr_core.v.
On a Linux system, install the following toolchains and utilities:
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:
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.
See also CHANGELOG for the most recent changes.