README ====== This README discusses issues unique to NuttX configurations for the IQ-Analog NR5M100 FPGA implementation of a RISC-V core on the Digilent Nexys4 FPGA board. The port is currently very minimal, though additional support may be added in the future to address more of the board peripherals supplied on the FPGA board. Those peripherals include: Supported: - USB UART (console port) - 16 single color LEDs - 16 slide switch inputs - Two tri-color LEDs - 5 Joystick style pushbuttons - 16 GPIO pins on 2 of the PMOD expansion connectors Not supported: - VGA display port - 8 digit 7-segement display - SD card slot - SPI FLASH memory (shared with FPGA configuration data). - USB HID (single device) connector serviced by external PIC uC - Non-DDR (older version): 16 MB Cellular SRAM - DDR (newer version): 128 MB DDR2 SDRAM - Microphone - 10/100 Ethernet PHY - 3-Axis accelerometer - Temperature sensor See http://store.digilentinc.com/nexys-4-ddr-artix-7-fpga-trainer-board-recommended-for-ece-curriculum/ or http://store.digilentinc.com/nexys-4-artix-7-fpga-trainer-board-limited-time-see-nexys4-ddr/ for more information about these boards. Contents ======== - NR5M100 Overview - Development Environment - GNU Toolchain Options - Debugger - IDEs - LEDs - PWM - UARTs - Timer Inputs/Outputs - FSMC SRAM - SSD1289 - Mikroe-STM32F4-specific Configuration Options - Configurations Development Environment ======================= The NR5M100 RISC-V core was designed as a low gate count / low performance micro controller for inclusion in an ASIC. It is based on a Verilog RISC-V called picorv32, but has many additions beyond that baseline. The design running on the Digilent Nexys4 FPGA is a validation platform for the core and is presented as an open source project. The reason NR5M100 is "low performance" is that it is a state machine based core (like the picorv32) and not a multi-stage pipeline core. This means that it requires an average of 4.5 clock cycles to execute each instruction. On a multi-stage pipeline architecture, this average would be closer to 1 clock cycle per instruction (though a bit higher due to pipeline branch misses). The tradeoff for lower performance is a simpler design. There is a single memory bus interface for both instructions and data. Multi-stage pipeline cores require a separate I and D bus with cache SRAM and an external memory cache controller, etc. This in addition to the pipeline registers adds additional gate count. The nr5m100-nexys4 core runs at 83.333 MHz which provides about 18 MHz effective operating speed with the multi-clock per instruction architecture. If you are looking for a higher performance platform, you should check out the PULP Platform ( http://www.pulp-platform.org ). That is an FPGA design with a 4-stage pipeline RISC-V core, though not currently supported by NuttX. The NR5M100 project will likely pull in the RISC-V core from that design next, though this will probably not be available soon. With a bit of work, it is possible to run the nr5m100-nexys4 core at 170 MHz with a 6.5 clocks-per-instruction state machine. This would give an effective performance of about 26Mhz. Development Environment ======================= Linux is the best choice for development, though Cygwin on Windows may work. The source has been built only using the GNU toolchain (see below) under a Linux environment. Other toolchains will likely cause problems or not be available yet. RISC-V GNU Toolchain ==================== To compile the code, you must first build a RISC-V GNU Toolchain from the sources at https://github.com/riscv/riscv-gnu-toolchain. I don't know of any sources for pre-compiled toolchains (though there may be some out there). To build this toolchain, follow these instructions (tested on Ubuntu 12.04): 1. Create a working directory in your home folder: mkdir ~/riscv cd ~/riscv 2. Clone the GNU source tree: git clone --recursive https://github.com/riscv/riscv-gnu-toolchain 3. Ensure the following packages are installed: sudo apt-get install texinfo bison flex autoconf automake libgmp-dev libmpfr-dev libmpc-dev 4. Configure and build the toolchain: cd riscv-gnu-toolchain ./configure --with-xlen=64 --with-arch=I --disable-float --disable-atomic --enable-multilib --prefix=~/riscv make -j4 (or -j8 based on how many cores you have) 5. Setup your PATH environment variable to include the toolchain (you may want to add this to your shell login script, such as .bash_profile, etc.): export PATH=~/riscv/bin:$PATH Windows based toolchain ----------------------- May be possible to compile the GNU toolchain described above using Cygwin, but havne't tried it. Debugger ======== The Debug Module within the NR5M100 RISC-V has been designed to work with the RISC-V gdb debugger interfaced with the SiFive implementation of OpenOCD. The interface has been tested with a J-LINK JTAG probe connected to PMOD header B on the FPGA using an adapter board that I designed and fabbed at OSHPark. I will update this README.txt file soon with a link to the shared project for anyone who wishes to build one. To build OpenOCD, perform the following: 1. Ensure the proper packages are installed: sudo apt-get install autoconf automake libtool libusb-1.0-0-dev 2. Download the latest OpenOCD sources from the SiFive github repo: cd ~/riscv git clone --recursive https://github.com/sifive/openocd.git 3. Configure and build OpenOCD. The x86_64 GCC compilers will give errors because of shadowed variable warnings, so disable the -Werror flag also: cd openocd sed -i.bak 's/ -Werror//g' configure.ac ./bootstrap ./configure --enable-jlink --enable-maintainer-mode --enable-ftdi --prefix=~/riscv CFLAGS=-g The configuration scripts for openocd and nr5m100-nexys4 have been provided in the nuttx/boards/nr5m100/nr5m100-nexys4/scripts directory. They are configured to use a J-LINK JTAG probe and to search for the IQ-Analog (the company I work for) IDCODE and part number for the FPGA board (7a10 for Artix xc7a100 part on the Digilent Nexys4 board). With FPGA source directly from the nr5m100 github site (to be provided), this ID will match the hardware. If changes are made to the JEDEC ID and/or part number, then the nr5m100.cfg file will need to be modified with the proper CPUID value. IDEs ==== NuttX is built using command-line make. It can be used with an IDE, but some effort will be required to create the project. While I haven't tried it as I am not an IDE guy, the team at SiFive have reported that they now have Eclipse working with the RISC-V gdb debugger. NOTE: The notes below are taken from an ARM build of NuttX, not RISC-V, so they may or may not work. Try it and see I suppose. Makefile Build -------------- Under Eclipse, it is pretty easy to set up an "empty makefile project" and simply use the NuttX makefile to build the system. That is almost for free under Linux. Under Windows, you will need to set up the "Cygwin GCC" empty makefile project in order to work with Windows (Google for "Eclipse Cygwin" - there is a lot of help on the internet). Native Build ------------ Here are a few tips before you start that effort: 1) Select the toolchain that you will be using in your .config file 2) Start the NuttX build at least one time from the Cygwin command line before trying to create your project. This is necessary to create certain auto-generated files and directories that will be needed. 3) Set up include paths: You will need include/, arch/risc-v/src/rv32im, arch/risc-v/src/common, arch/risc-v/src/nr5m100, and sched/. 4) All assembly files need to have the definition option -D __ASSEMBLY__ on the command line. Startup files will probably cause you some headaches. The NuttX startup file is arch/risc-v/src/nr5m100/nr5_vectors.S. With RIDE, I build NuttX one time from the Cygwin command line in order to obtain the pre-built startup object needed by RIDE. LEDs ==== The Nexys4 board has 16 single-color LEDs onboard, as well as 2 tri-color LEDs. These are supported using GPIO Ports A (16-single color) and B (tri-color). Additionally the tri-color LEDs can be driven from the Timer 1 or 2 PWM output signals. PWM === The nr5m100-nexys4 design has PWM capabilities within the Timer 1 and Timer 2 modules. These PWM signals can be muxed to the tri-color LEDs or to I/O pins on one of the PMOD expansion headers. UARTs ===== The nr5m100-nexys4 design has an onboard USB-UART providing an RS-232 interface via the same USB cable that is used to program the FPGA. The core proivdes a fixed 8-Data bit, 1 stop bit, no parity UART connected to this intrface. UART PINS --------- UART1 RX FPGA C4 (USB UART device) TX FPGA D4 (USB UART device) Default USART/UART Configuration -------------------------------- UART1 is enabled in all configurations (see */defconfig). Configurations ============== Each nr5m100-nexys4 configuration is maintained in a sub-directory and can be selected as follow: tools/configure.sh nr5m100-nexys4: Where is one of the following: nsh --- This is an NSH example that uses UART1 as the console. UART1 is connected to the USB UART bridge on the FPGA board.