- Assembly 55.5%
- Forth 16.6%
- Verilog 11.1%
- Pascal 11%
- C 3.1%
- Other 2.7%
| common | Playground | |
| hello_gcc | Playground | |
| mecrisp-quintus | Playground | |
| openxc7 | Playground | |
| vivado | Playground | |
| LICENSE | Playground | |
| README.md | Playground | |
RISC-V Playground for Digilent Genesys 2
This projects contains an example for a simple RISC-V RV32IMC microcontroller based on the FemtoRV32-Gracilis written by Bruno Levy and Matthias Koch:
https://github.com/BrunoLevy/learn-fpga/
https://github.com/BrunoLevy/learn-fpga/blob/master/FemtoRV/RTL/PROCESSOR/femtorv32_quark.v
Peripherals included for default:
- VGA 800x600 textmode with 7-Bit ASCII 8x16 font
- Random number generator using a ring oscillator defined in logic
- GPIO registers for PMOD pin access
- LEDs
- UART terminal, 115200 Baud 8N1
- 64 kb initialised RAM
Notes on toolchain usage
The Digilent Genesys 2 features a xc7k325tffg900-2 FPGA, from the Xilinx/AMD Kintex-7 family.
It is supported out of the box by the FOSS openXC7 toolchain, which nicely integrates yosys, nextpnr-xilinx and the project x-ray chip databases.
If you change the initial memory images, make sure to copy the changed .hex files to the common folder before launching bitstream synthesis.
As this is a quite large FPGA, it is not supported by Vivado for default. You need a paid licence if you want to use it in combination with the proprietary Vivado toolchain.
First step: Install nix package manager
Run as root:
sh <(curl -L https://nixos.org/nix/install) --daemon
Run as normal user:
nix-shell -p nix-info --run "nix-info -m"
Second step: Install openXC7 as nix flake and enter the environment
nix develop github:openxc7/toolchain-nix
Third step: Try official examples
git clone https://github.com/openXC7/demo-projects
nix develop github:openxc7/toolchain-nix
cd demo-projects/blinky-genesys2
make
openFPGALoader --board genesys2 --bitstream blinky.bit
This will also create the chipdb (xc7k325tffg900.bin) file which you need for the next step.
Fourth step: Synthesise the contents of this repository
nix develop github:openxc7/toolchain-nix
export KINTEX7_CHIPDB=~/your-path-here/chipdb
cd openxc7
make clean all
Fifth step: Load the bitstream (you can try with the one included first)
openFPGALoader --board genesys2 --bitstream forth.bit
Connect a display to the VGA port, and open a terminal on the on-board USB-serial bridge using 115200 baud 8N1:
picocom -b 115200 /dev/ttyUSB0 --imap lfcrlf,crcrlf --omap delbs,crlf --send-cmd "ascii-xfr -s -l 30 -n"
Memory map and IO
Memory areas are selected using bits [15:14].
- 0x00000000 - 0x00010000: 64 kb initialised RAM for firmware
- 0x40000000 - 0x7FFFFFFF: Peripheral IO registers
- 0x80000000 - 0x80000FFF: 4096 bytes character buffer, 100x37=3700 chars visible, byte access only
- 0x80001000 - 0x800015FF: 1536 bytes font data, 96 characters, 16 bytes per character, byte access only
For using the display, all you have is to write characters into the 3700 bytes starting at 0x80000000. The font (starting at 0x80001000) contains 96 glyphs (32 to 127), taken from FreeBSD "iso-8x16" bitmap font. The MSB (0x80) selects a "highlight" color.
The 24 glyphs for ASCII 8 to 31 are in the invisible part of the character memory area from 0x80000E80 to 0x80000FFF and can be freely used for custom characters.
Both character and font data areas can be read and written using byte access only.
The IO registers with base 0x40000000 are word addressable.
-
0x40000004: RW [7:0] Eight LEDs
-
0x40000008: RW Serial terminal. Write: Send character [7:0]. Read: Received character [7:0] and flags.
-
0x40000010: RO For reading flags [11] Pseudorandom [10] Random [9] Busy [8] Valid without removing character [7:0] from receive FIFO.
-
0x40000020: RO [7:0] PMOD JD IN
-
0x40000040: RW [7:0] PMOD JD OUT
-
0x40000080: RW [7:0] PMOD JD DIR
Peripheral address bits are one-hot decoded. Every register has its own bit, which simplifies the decoding logic, and also allows to set multiple registers at once.
The serial terminal flags contain a ring oscillator used for random numbers, but wait (a few) 100 clock cycles before capturing the next random bit because one gets correlations between the bits when reading too fast. Just give the ring oscillator a little bit of time to drift away.
There is also a faster xorshift based pseudo random number generator.
Reset the CPU by pressing the RESET button. This does not, however, reload the bitstream with the memory initialisation. It just re-starts with the memory as left before.
Example firmware
Mecrisp-Quintus (included into bitstream for default):
A Forth compiler and environment to explore the logic design.
Hello GCC:
A small project in C featuring serial terminal, LEDs and VGA.