From e42de8fe520916a105b4f98569530dbe16159a56 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Fri, 26 Apr 2019 14:28:20 -0500 Subject: [PATCH 1/6] docs: Adding script to pull useful docs from LiteX BuildEnv's wiki. --- doc/pull-docs-from-buildenv-wiki.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100755 doc/pull-docs-from-buildenv-wiki.sh diff --git a/doc/pull-docs-from-buildenv-wiki.sh b/doc/pull-docs-from-buildenv-wiki.sh new file mode 100755 index 000000000..04690d647 --- /dev/null +++ b/doc/pull-docs-from-buildenv-wiki.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +# Soft-CPU - Description about supported Soft-CPUs. +# BIOS - Information about the BIOS and what it is used for. +# Firmware - Information about compatible Firmware. + +for page in Soft-CPU BIOS Firmware; do + curl https://raw.githubusercontent.com/wiki/timvideos/litex-buildenv/${page}.md > ${page}.md + git add ${page}.md +done + +GIT_MSG=$(tempfile) || exit +trap "rm -f -- '$GIT_MSG'" EXIT +git commit --message "Updating documents from LiteX BuildEnv Wiki" From 39c579baa2adbdb2b16af4930bc9a6a735e163e7 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Fri, 26 Apr 2019 16:20:21 -0500 Subject: [PATCH 2/6] Standardize the `cpu_variant` strings. Current valid `cpu_variant` values; * minimal (alias: min) * lite (alias: light, zephyr, nuttx) * standard (alias: std) - Default * full (alias: everything) * linux Fully documented in the [docs/Soft-CPU.md](docs/Soft-CPU.md) file mirrored from the [LiteX-BuildEnv Wiki](https://github.com/timvideos/litex-buildenv/wiki). Also support "extensions" which are added to the `cpu_variant` with a `+`. Currently only the `debug` extension is supported. In future hope to add `mmu` and `hmul` extensions. --- litex/soc/cores/cpu/lm32/core.py | 10 +++-- litex/soc/cores/cpu/minerva/core.py | 4 +- litex/soc/cores/cpu/mor1kx/core.py | 7 ++-- litex/soc/cores/cpu/picorv32/core.py | 5 ++- litex/soc/cores/cpu/vexriscv/core.py | 59 +++++++++++++++++++--------- litex/soc/integration/soc_core.py | 58 ++++++++++++++++++++++++++- 6 files changed, 113 insertions(+), 30 deletions(-) diff --git a/litex/soc/cores/cpu/lm32/core.py b/litex/soc/cores/cpu/lm32/core.py index e7b18bf64..4fd6f1e59 100644 --- a/litex/soc/cores/cpu/lm32/core.py +++ b/litex/soc/cores/cpu/lm32/core.py @@ -12,8 +12,8 @@ class LM32(Module): gcc_flags = "-mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled" linker_output_format = "elf32-lm32" - def __init__(self, platform, eba_reset, variant=None): - assert variant in (None, "lite", "minimal"), "Unsupported variant %s" % variant + def __init__(self, platform, eba_reset, variant="standard"): + assert variant in ("standard", "lite", "minimal"), "Unsupported variant %s" % variant self.reset = Signal() self.ibus = i = wishbone.Interface() self.dbus = d = wishbone.Interface() @@ -66,7 +66,7 @@ class LM32(Module): self.add_sources(platform, variant) @staticmethod - def add_sources(platform, variant=None): + def add_sources(platform, variant): vdir = os.path.join( os.path.abspath(os.path.dirname(__file__)), "verilog") platform.add_sources(os.path.join(vdir, "submodule", "rtl"), @@ -93,5 +93,7 @@ class LM32(Module): platform.add_verilog_include_path(os.path.join(vdir, "config_minimal")) elif variant == "lite": platform.add_verilog_include_path(os.path.join(vdir, "config_lite")) - else: + elif variant == "standard": platform.add_verilog_include_path(os.path.join(vdir, "config")) + else: + raise TypeError("Unknown variant {}".format(variant)) diff --git a/litex/soc/cores/cpu/minerva/core.py b/litex/soc/cores/cpu/minerva/core.py index c864f3ae9..6b9cfa5dc 100644 --- a/litex/soc/cores/cpu/minerva/core.py +++ b/litex/soc/cores/cpu/minerva/core.py @@ -12,8 +12,8 @@ class Minerva(Module): gcc_flags = "-D__minerva__ -march=rv32i -mabi=ilp32" linker_output_format = "elf32-littleriscv" - def __init__(self, platform, cpu_reset_address, variant=None): - assert variant is None, "Unsupported variant %s" % variant + def __init__(self, platform, cpu_reset_address, variant="standard"): + assert variant is "standard", "Unsupported variant %s" % variant self.reset = Signal() self.ibus = wishbone.Interface() self.dbus = wishbone.Interface() diff --git a/litex/soc/cores/cpu/mor1kx/core.py b/litex/soc/cores/cpu/mor1kx/core.py index 3b55991b6..f6611c3e6 100644 --- a/litex/soc/cores/cpu/mor1kx/core.py +++ b/litex/soc/cores/cpu/mor1kx/core.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import os from migen import * @@ -12,8 +13,8 @@ class MOR1KX(Module): gcc_flags = "-mhard-mul -mhard-div -mror" linker_output_format = "elf32-or1k" - def __init__(self, platform, reset_pc, variant=None): - assert variant in (None, "linux"), "Unsupported variant %s" % variant + def __init__(self, platform, reset_pc, variant="standard"): + assert variant in ("standard", "linux"), "Unsupported variant %s" % variant self.reset = Signal() self.ibus = i = wishbone.Interface() self.dbus = d = wishbone.Interface() @@ -47,7 +48,7 @@ class MOR1KX(Module): p_DBUS_WB_TYPE="B3_REGISTERED_FEEDBACK", ) - if variant == None: + if variant == "standard": # Use the default configuration pass elif variant == "linux": diff --git a/litex/soc/cores/cpu/picorv32/core.py b/litex/soc/cores/cpu/picorv32/core.py index 93f3358a2..e2f323932 100644 --- a/litex/soc/cores/cpu/picorv32/core.py +++ b/litex/soc/cores/cpu/picorv32/core.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import os from migen import * @@ -12,7 +13,7 @@ class PicoRV32(Module): gcc_flags_template = "-D__picorv32__ -mno-save-restore -march=rv32{ext} -mabi=ilp32" linker_output_format = "elf32-littleriscv" - def __init__(self, platform, progaddr_reset, variant): + def __init__(self, platform, progaddr_reset, variant="standard"): self.gcc_flags = "" self.reset = Signal() @@ -61,7 +62,7 @@ class PicoRV32(Module): "p_STACKADDR" : 0xffffffff } - if variant == None: + if variant == "standard": self.gcc_flags = PicoRV32.gcc_flags_template.format(ext="im") elif variant == "minimal": picorv32_params.update({ diff --git a/litex/soc/cores/cpu/vexriscv/core.py b/litex/soc/cores/cpu/vexriscv/core.py index 1c233f317..f66473be3 100644 --- a/litex/soc/cores/cpu/vexriscv/core.py +++ b/litex/soc/cores/cpu/vexriscv/core.py @@ -6,18 +6,51 @@ from litex.soc.interconnect import wishbone from litex.soc.interconnect.csr import AutoCSR, CSRStatus, CSRStorage +CPU_VARIANTS = { + "minimal": "VexRiscv_Min", + "minimal+debug": "VexRiscv_MinDebug", + "lite": "VexRiscv_Lite", + "lite+debug": "VexRiscv_LiteDebug", + "standard": "VexRiscv", + "standard+debug": "VexRiscv_Debug", + "full": "VexRiscv_Full", + "full+debug": "VexRiscv_FullDebug", + "linux": "VexRiscv_Linux", +} + + +GCC_FLAGS = { + # /-------- Base ISA + # |/------- Hardware Multiply + Divide + # ||/----- Atomics + # |||/---- Compressed ISA + # ||||/--- Single-Precision Floating-Point + # |||||/-- Double-Precision Floating-Point + # imacfd + "minimal": "-march=rv32i -mabi=ilp32", + "minimal+debug": "-march=rv32i -mabi=ilp32", + "lite": "-march=rv32i -mabi=ilp32", + "lite+debug": "-march=rv32i -mabi=ilp32", + "standard": "-march=rv32im -mabi=ilp32", + "standard+debug": "-march=rv32im -mabi=ilp32", + # Does full have floating point? - Add -march=fd, and -mabi=fd + "full": "-march=rv32imac -mabi=ilp32", + "full+debug": "-march=rv32imac -mabi=ilp32", + "linux": "-march=rv32imac -mabi=ilp32", +} + + class VexRiscv(Module, AutoCSR): name = "vexriscv" endianness = "little" gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf") - gcc_flags = "-D__vexriscv__ -march=rv32im -mabi=ilp32" linker_output_format = "elf32-littleriscv" - def __init__(self, platform, cpu_reset_address, variant=None): - variant = "std" if variant is None else variant - variant = "std_debug" if variant == "debug" else variant - variants = ("std", "std_debug", "lite", "lite_debug", "min", "min_debug", "full", "full_debug") - assert variant in variants, "Unsupported variant %s" % variant + def __init__(self, platform, cpu_reset_address, variant="standard"): + assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant + + self.gcc_flags = GCC_FLAGS[variant] + self.platform = platform self.variant = variant self.external_variant = None @@ -150,18 +183,8 @@ class VexRiscv(Module, AutoCSR): ) @staticmethod - def add_sources(platform, variant="std"): - verilog_variants = { - "std": "VexRiscv.v", - "std_debug": "VexRiscv_Debug.v", - "lite": "VexRiscv_Lite.v", - "lite_debug": "VexRiscv_LiteDebug.v", - "min": "VexRiscv_Min.v", - "min_debug": "VexRiscv_MinDebug.v", - "full": "VexRiscv_Full.v", - "full_debug": "VexRiscv_FullDebug.v", - } - cpu_filename = verilog_variants[variant] + def add_sources(platform, variant="standard"): + cpu_filename = CPU_VARIANTS[variant] vdir = os.path.join(os.path.abspath(os.path.dirname(__file__)), "verilog") platform.add_source(os.path.join(vdir, cpu_filename)) diff --git a/litex/soc/integration/soc_core.py b/litex/soc/integration/soc_core.py index 6cbd1dff4..f9507b731 100644 --- a/litex/soc/integration/soc_core.py +++ b/litex/soc/integration/soc_core.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import os import struct import inspect @@ -23,6 +24,42 @@ __all__ = [ ] +CPU_VARIANTS = { + # "official name": ["alias 1", "alias 2"], + "minimal" : ["min",], + "lite" : ["light", "zephyr", "nuttx"], + "standard": [None, "std"], + "full": [], + "linux" : [], +} +CPU_VARIANTS_EXTENSIONS = ["debug"] + + +class InvalidCPUVariantError(ValueError): + def __init__(self, variant): + msg = """\ +Invalid cpu_variant value: {} + +Possible Values: +""".format(variant) + for k, v in CPU_VARIANTS.items(): + msg += " - {} (aliases: {})\n".format(k, ", ".join(str(s) for s in v)) + ValueError.__init__(self, msg) + + +class InvalidCPUExtensionError(ValueError): + def __init__(self, variant): + msg = """\ +Invalid extension in cpu_variant value: {} + +Possible Values: +""".format(variant) + for e in CPU_VARIANTS_EXTENSIONS.items(): + msg += " - {}\n".format(e) + ValueError.__init__(self, msg) + + + def version(with_time=True): import datetime import time @@ -77,6 +114,7 @@ def get_mem_data(filename, endianness="big", mem_size=None): i += 1 return data + class ReadOnlyDict(dict): def __readonly__(self, *args, **kwargs): raise RuntimeError("Cannot modify ReadOnlyDict") @@ -162,7 +200,25 @@ class SoCCore(Module): if cpu_type == "None": cpu_type = None self.cpu_type = cpu_type - self.cpu_variant = cpu_variant + + # Support the old style which used underscore for separator + cpu_variant = cpu_variant.replace('_', '+') + # Check for valid CPU variants. + cpu_variant_processor, *cpu_variant_ext = cpu_variant.split('+') + for key, values in CPU_VARIANTS.items(): + if cpu_variant_processor not in [key,]+values: + continue + self.cpu_variant = key + break + else: + raise InvalidCPUVariantError(cpu_variant) + + # Check for valid CPU extensions. + for ext in sorted(cpu_variant_ext): + if cpu_variant_ext not in CPU_VARIANTS_EXTENSIONS: + raise InvalidCPUExtension(cpu_variant) + self.cpu_variant += "+"+ext + if integrated_rom_size: cpu_reset_address = self.mem_map["rom"] self.cpu_reset_address = cpu_reset_address From a43de8195f45b604fbfc558600dfb5d0396dfe86 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Fri, 26 Apr 2019 15:29:32 -0500 Subject: [PATCH 3/6] Updating documents from LiteX BuildEnv Wiki --- doc/BIOS.md | 9 ++ doc/Firmware.md | 7 ++ doc/Soft-CPU.md | 254 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 270 insertions(+) create mode 100644 doc/BIOS.md create mode 100644 doc/Firmware.md create mode 100644 doc/Soft-CPU.md diff --git a/doc/BIOS.md b/doc/BIOS.md new file mode 100644 index 000000000..f414c822d --- /dev/null +++ b/doc/BIOS.md @@ -0,0 +1,9 @@ +LiteX takes the philosophy of pushing as much onto the [[Soft CPU]] as possible. This means that most [[Gateware]] needs some accompanying code to initialize various settings and configurations. This specialized firmware is called the [[BIOS]]. + +The [[BIOS]] generally does tasks like; + * Train any external DDR memory + * Load the user's [[Firmware]] into external memory via; + * Communication channels like serial, tftp + * Other storage systems like external flash. + +This can make it very fast to do development as you can iterate on [[Firmware]] development quickly. \ No newline at end of file diff --git a/doc/Firmware.md b/doc/Firmware.md new file mode 100644 index 000000000..d9e5000ea --- /dev/null +++ b/doc/Firmware.md @@ -0,0 +1,7 @@ + * Baremetal + * MicroPython + * NuttX + * Zephyr + * Linux + +[Firmware which runs on LiteX Google Doc](https://docs.google.com/document/d/11uzjWRWk9-KuBFc7chUNUluL5ajysY2qfXvt1vttl7k/edit) \ No newline at end of file diff --git a/doc/Soft-CPU.md b/doc/Soft-CPU.md new file mode 100644 index 000000000..7ebcb61e2 --- /dev/null +++ b/doc/Soft-CPU.md @@ -0,0 +1,254 @@ +All LiteX SoCs need some type of CPU to operate correctly. Most use an "Soft CPU" embedded in the gateware for this purpose, but in some cases a host computer is used instead (for example this can be true in the PCIe card case). + +# Summary of Soft CPUs + +Currently the supported Soft CPUs are: + + * [`lm32`](https://github.com/enjoy-digital/litex/tree/master/litex/soc/cores/cpu/lm32) -- a [LatticeMico32](https://en.wikipedia.org/wiki/LatticeMico32) soft core. + +* [`or1k`](https://github.com/enjoy-digital/litex/tree/master/litex/soc/cores/cpu/mor1kx) -- an [OpenRISC 1000](https://openrisc.io/or1k.html) soft core (see also [Open RISC on Wikipedia](https://en.wikipedia.org/wiki/OpenRISC)). + +* [`picorv32`](https://github.com/enjoy-digital/litex/tree/master/litex/soc/cores/cpu/picorv32) -- a [Small RISC V core by Clifford Wolf](https://github.com/cliffordwolf/picorv32), implementing the `rv32imc` instruction set (or configured subsets) + +* [`vexriscv`](https://github.com/enjoy-digital/litex/tree/master/litex/soc/cores/cpu/vexriscv) -- an [FPGA Friendly RISC V core by SpinalHDL](https://github.com/SpinalHDL/VexRiscv), implementing the `rv32im` instruction set (hardware multiply optional) + +* [`minerva`](https://github.com/enjoy-digital/litex/tree/master/litex/soc/cores/cpu/minerva) -- an Minerva is a CPU core that currently implements the RISC-V RV32I instruction set and its microarchitecture is described in plain Python code using the [nMigen toolbox](https://github.com/m-labs/nmigen). + +# Soft CPU Variants + +Most of these CPUs have multiple configuration "variants" which customize the configuration to target a specific type of firmware and performance. All these CPUs can be used with your own bare metal firmware. + +## `minimal` + +Aliases: `min` + +Minimal is the smallest possible working configuration for a given CPU type. These features frequently disables a large number of useful such as illegal instruction exceptions and similar. It should only be used if the absolute smallest configuration is needed. + +### Supported CPUs + + * lm32 + * picorv32 + * vexriscv + +## `lite` + +**Aliases**: `zephyr`, `nuttx`, `light` + +Lite is the configuration which should work okay for bare metal firmware and RTOS like NuttX or Zephyr on small big FPGAs like the Lattice iCE40 parts. It can also be used for designs which are more resource constrained. + +### Recommended FPGAs + + * Lattice iCE40 Series - iCE40HX, iCE40LP, iCE40UP5K + * Any resource constrained design. + +### Supported CPUs + + * lm32 + * vexriscv + +## `standard` + +**Aliases**: `std` + +Standard is the default configuration which should work well for bare metal firmware and RTOS like NuttX or Zephyr on modern big FPGAs. + +### Supported CPUs + + * lm32 + * minerva + * picorv32 + * or1k + * vexriscv + +### Recommended FPGAs + + * Xilinx Series 7 - Artix 7, Kintex 7, Spartan 7 + * Xilinx Spartan 6 + * Lattice ECP5 + +## `linux` + +This target enables CPU features such as MMU that are required to get Linux booting. + +### Supported CPUs + + * or1k + * vexriscv + +--- + +# Soft CPU Extensions + +Extensions are added to the CPU variant with a `+`. For example a `minimal` variant with the `debug` extension would be `minimal+debug`. + +## `debug` + +The debug extension enables extra features useful for debugging. This normally includes things like JTAG port. + +### Supported CPUs + + * vexriscv + +## TODO - `mmu` + +The `mmu` extension enables a memory protection unit. + +### Supported CPUs + + * lm32 (untested) + * vexriscv + * or1k + +## TODO - `hmul` + +The `hmul` extension enables hardware multiplication acceleration. + +--- + +# Binutils + Compiler + + * lm32 support was added to upstream GCC around ~2009, no clang support. + * or1k support was added to upstream GCC in version 9.0.0, clang support was added upstream in version XXX + * riscv support (VexRISCV, PicoRV32 and Minerva) was added to upstream GCC in version 7.1.0, clang support was added upstream in version 3.1 + +You can compile your own compiler, download a precompiled toolchain or use an environment like [TimVideos LiteX BuildEnv](https://github.com/timvideos/litex-buildenv/) which provides precompiled toolchain for all three architectures. + +Note: RISC-V toolchains support or require various extensions. Generally `rv32i` is used on smaller FPGAs, and `rv32im` on larger FPGAs -- the `rv32im` adds hardware multiplication and division (see [RISC V ISA base and extensions on Wikipedia](https://en.wikipedia.org/wiki/RISC-V#ISA_base_and_extensions) for more detail). + +--- + +# SoftCPU options + +## lm32 - [LatticeMico32](https://github.com/m-labs/lm32) + +[LatticeMico32](https://en.wikipedia.org/wiki/LatticeMico32) soft core, small and designed for an FPGA. + +### CPU Variants + + * minimal + * lite + * standard + +### Tooling support + + * Upstream GCC + * Upstream Binutils + +### OS Support + + * No upstream Linux, very old Linux port + * Upstream NuttX + * No Zephyr support + +### Community + + * No current new activity + +--- + +## [mor1k - OpenRISC](https://github.com/openrisc/mor1kx) + +An [OpenRISC 1000](https://openrisc.io/or1k.html) soft core (see also [Open RISC on Wikipedia](https://en.wikipedia.org/wiki/OpenRISC)). + +### CPU Variants + + * standard + * linux + +### Tooling support + + * Upstream GCC + * Upstream Binutils + * Upstream clang + +### OS support + + * No Zephyr support + * No NuttX support + * Upstream Linux + +### Community + + * Reasonable amount of activity. + +--- + +## RISC-V - [VexRiscv](https://github.com/SpinalHDL/VexRiscv) + +A [FPGA Friendly RISC V core by SpinalHDL](https://github.com/SpinalHDL/VexRiscv), implementing the `rv32im` instruction set (hardware multiply optional). + +### CPU Variants + + * minimal + * minimal_debug + * lite + * lite_debug + * standard + * standard_debug + * linux + +### Tooling support + + * Upstream GCC + * Upstream Binutils + * Upstream clang + +### OS support + + * Upstream Zephyr + * Unknown NuttX support + * Upstream Linux (in progress) + +### Community + + * Lots of current activity + * Currently supported under both LiteX & MiSoC + +## RISC-V - [picorv32](https://github.com/cliffordwolf/picorv32/) + +A [small RISC V core by Clifford Wolf](https://github.com/cliffordwolf/picorv32), implementing the `rv32imc` instruction set (or configured subsets). + +### CPU Variants + + * minimal + * standard + +### Tooling support + + * Upstream GCC + * Upstream Binutils + * Upstream clang + +### OS support + + * Out of tree Zephyr + * Unknown NuttX support + * Too small for Linux + +### Community + + * Some activity + +## RISC-V - [`minerva`](https://github.com/enjoy-digital/litex/tree/master/litex/soc/cores/cpu/minerva) + +The Minerva is a CPU core that currently implements the RISC-V RV32I instruction set and its microarchitecture is described in plain Python code using the [nMigen toolbox](https://github.com/m-labs/nmigen). + +### CPU Variants + + * standard + +### Tooling support + + * Upstream GCC + * Upstream Binutils + * Upstream clang + +### OS support + + * Unknown Zephyr support + * Unknown NuttX support + * Unknown Linux support + +### Community + + * Some activity From 65650919a7b46d05320865de11dd4cb54e69f7fa Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Fri, 26 Apr 2019 17:00:52 -0500 Subject: [PATCH 4/6] Updating documents from LiteX BuildEnv Wiki --- doc/Firmware.md | 119 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 113 insertions(+), 6 deletions(-) diff --git a/doc/Firmware.md b/doc/Firmware.md index d9e5000ea..5324da75e 100644 --- a/doc/Firmware.md +++ b/doc/Firmware.md @@ -1,7 +1,114 @@ - * Baremetal - * MicroPython - * NuttX - * Zephyr - * Linux +# Firmware -[Firmware which runs on LiteX Google Doc](https://docs.google.com/document/d/11uzjWRWk9-KuBFc7chUNUluL5ajysY2qfXvt1vttl7k/edit) \ No newline at end of file +LiteX is normally used with custom firmware running on the Soft-CPU inside the gateware (although in some cases it can be used with software running on a computer connected to the FPGA). + +This firmware can either be custom bare metal C code or be built on top of an existing real time operating system or even full operating system. All Soft-CPUs let you write your own bare metal firmware, but only some configurations work with operating systems. + +[Firmware which runs on LiteX Google Doc](https://docs.google.com/document/d/11uzjWRWk9-KuBFc7chUNUluL5ajysY2qfXvt1vttl7k/edit) + +# Baremetal + +## Support Soft-CPU Configurations + +**All** Soft-CPUs let you write your own bare metal firmware. + + * `lm32` (any variant) + * `or1k` (any variant) + * `vexriscv` (any variant) + * `picorv32` (any variant) + * `minerva` (any variant) + +--- + +# MicroPython via [FuPy Project](https://fupy.github.io) + +From the FuPy website; +> The aim of this project is to make MicroPython run on FPGAs using the LiteX & Migen+MiSoC technologies. This allows you to do full stack development (FPGA gateware & soft CPU firmware) in Python! + +## When to use? + +MicroPython is great to use when ease and speed of development is more important than performance. When coupled with LiteX you can push MicroPython even further by moving performance critical parts into FPGA gateware. + +## Hardware Requirements + +MicroPython is very light on requirements; + * 32 kilobytes memory - can normally use internal block ram inside FPGA. + * 128 kilobytes of storage - can normally use spare space in SPI flash used to configure the FPGA. + +## Support Soft-CPU Configurations + + * `lm32` (any variant), in FuPy repository + * `or1k` (any variant), in FuPy repository + * (in progress) `vexriscv` (any variant), in FuPy repository + * (in progress) `picorv32` (any variant), in FuPy repository + +--- + +# [NuttX](http://www.nuttx.org/) + +From the NuttX website; +> NuttX is a real-time operating system (RTOS) with an emphasis on standards compliance and small footprint. Scalable from 8-bit to 32-bit microcontroller environments, the primary governing standards in NuttX are Posix and ANSI standards. Additional standard APIs from Unix and other common RTOS's (such as VxWorks) are adopted for functionality not available under these standards, or for functionality that is not appropriate for deeply-embedded environments (such as fork()). + +## When to use? + +NuttX is a good option if you are already using NuttX or need to use a function that is already available in the NuttX ecosystem. + +## Hardware Requirements + +Unknown. + +LiteEth networking is supported. + +## Support Soft-CPU Configurations + + * `lm32` (any variant), in upstream repository + +--- + +# [Zephyr](https://www.zephyrproject.org/) + +From the Zephyr website; +> The Zephyr Project is a scalable real-time operating system (RTOS) supporting multiple hardware architectures, optimized for resource constrained devices, and built with safety and security in mind. + +## When to use? + +Zephyr is a great choice if you don't want to write your own bare metal firmware. It is under active development and moving forward quickly. + +It also has a coding style which makes it easy to move to Linux at a later state if you outgrow the abilities of Zephyr. + +## Hardware Requirements + +Zephyr is very light on requirements; + * 32 kilobytes memory - can normally use internal block ram inside FPGA. + * Some storage - can normally use spare space in SPI flash used to configure the FPGA. + +## Support Soft-CPU Configurations + + * `vexriscv` (any variant), in upstream repository + * `picorv32` (any variant), out of tree port + +--- + +# [Linux](https://en.wikipedia.org/wiki/Linux) + +From Wikipedia; +> Linux is a family of free and open-source software operating systems based on the Linux kernel, an operating system kernel first released on September 17, 1991 by Linus Torvalds. ... +> Linux also runs on embedded systems, i.e. devices whose operating system is typically built into the firmware and is highly tailored to the system. This includes routers, automation controls, televisions, digital video recorders, video game consoles, and smartwatches. Many smartphones and tablet computers run Android and other Linux derivatives.[30] Because of the dominance of Android on smartphones, Linux has the largest installed base of all general-purpose operating systems. + +## When to use? + +Linux tends to run quite slowly on the soft-CPUs supported by LiteX and needs hardware acceleration to do most useful operations. Linux makes the most sense were the existing large pool of Linux drivers or software is helpful. + +## Hardware Requirements + +Linux operating support generally needs; + * Large and fast FPGA, something like Lattice ECP5 or Xilinx Artix 7 / Spartan 6. + * 32+ megabytes memory, generally meaning external SDRAM or DDR RAM. + * UART serial console. + * Fast Ethernet (100 Megabit or 1 Gigabit Ethernet). + * Some type of storage, large SPI flash or SD Card or SATA hard drives potential options. + +## Support Soft-CPU Configurations + + * `or1k` (`linux` variant), out of tree port being upstreamed + * `vexriscv` (`linux` variant), out of tree port being upstreamed From 71a837315acd8a3d4e3e92baa8db9e381edc189b Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Fri, 26 Apr 2019 17:08:07 -0500 Subject: [PATCH 5/6] Work with no `cpu_variant` provided. --- litex/soc/integration/soc_core.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/litex/soc/integration/soc_core.py b/litex/soc/integration/soc_core.py index f9507b731..c5fe7ad2f 100644 --- a/litex/soc/integration/soc_core.py +++ b/litex/soc/integration/soc_core.py @@ -202,6 +202,8 @@ class SoCCore(Module): self.cpu_type = cpu_type # Support the old style which used underscore for separator + if cpu_variant is None: + cpu_variant = "standard" cpu_variant = cpu_variant.replace('_', '+') # Check for valid CPU variants. cpu_variant_processor, *cpu_variant_ext = cpu_variant.split('+') From 5cbc5bc1998dce20753d2d66b428630dbda0b956 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Fri, 26 Apr 2019 17:13:28 -0500 Subject: [PATCH 6/6] Adding testing of cpu variants. --- litex/soc/integration/soc_core.py | 6 ++-- test/test_targets.py | 60 ++++++++++++++++++++++++++++--- 2 files changed, 58 insertions(+), 8 deletions(-) diff --git a/litex/soc/integration/soc_core.py b/litex/soc/integration/soc_core.py index c5fe7ad2f..a36b68a29 100644 --- a/litex/soc/integration/soc_core.py +++ b/litex/soc/integration/soc_core.py @@ -54,7 +54,7 @@ Invalid extension in cpu_variant value: {} Possible Values: """.format(variant) - for e in CPU_VARIANTS_EXTENSIONS.items(): + for e in CPU_VARIANTS_EXTENSIONS: msg += " - {}\n".format(e) ValueError.__init__(self, msg) @@ -217,8 +217,8 @@ class SoCCore(Module): # Check for valid CPU extensions. for ext in sorted(cpu_variant_ext): - if cpu_variant_ext not in CPU_VARIANTS_EXTENSIONS: - raise InvalidCPUExtension(cpu_variant) + if ext not in CPU_VARIANTS_EXTENSIONS: + raise InvalidCPUExtensionError(cpu_variant) self.cpu_variant += "+"+ext if integrated_rom_size: diff --git a/test/test_targets.py b/test/test_targets.py index 1b0151377..eadbd8e6d 100644 --- a/test/test_targets.py +++ b/test/test_targets.py @@ -1,3 +1,4 @@ +import subprocess import unittest import os @@ -6,6 +7,9 @@ from migen import * from litex.soc.integration.builder import * +RUNNING_ON_TRAVIS = (os.getenv('TRAVIS', 'false').lower() == 'true') + + def build_test(socs): errors = 0 for soc in socs: @@ -98,8 +102,54 @@ class TestTargets(unittest.TestCase): platforms += ["avalanche"] # PolarFire for p in platforms: - os.system("litex/boards/targets/simple.py litex.boards.platforms." + p + - " --cpu-type=vexriscv " + - " --no-compile-software " + - " --no-compile-gateware " + - " --uart-stub=True") + with self.subTest(platform=p): + cmd = """\ +litex/boards/targets/simple.py litex.boards.platforms.{p} \ + --cpu-type=vexriscv \ + --no-compile-software \ + --no-compile-gateware \ + --uart-stub=True \ +""".format(p=p) + subprocess.check_call(cmd, shell=True) + + def run_variants(self, cpu, variants): + for v in variants: + with self.subTest(cpu=cpu, variant=v): + self.run_variant(cpu, v) + + def run_variant(self, cpu, variant): + cmd = """\ +litex/boards/targets/simple.py litex.boards.platforms.arty \ + --cpu-type={c} \ + --cpu-variant={v} \ + --no-compile-software \ + --no-compile-gateware \ + --uart-stub=True \ +""".format(c=cpu, v=variant) + subprocess.check_output(cmd, shell=True) + + # Build some variants for the arty platform to make sure they work. + def test_variants_riscv(self): + cpu_variants = { + 'picorv32': ('standard', 'minimal'), + 'vexriscv': ('standard', 'minimal', 'lite', 'lite+debug', 'full+debug'), + 'minerva': ('standard',), + } + for cpu, variants in cpu_variants.items(): + self.run_variants(cpu, variants) + + def test_bad_variants(self): + with self.assertRaises(subprocess.CalledProcessError): + self.run_variant('vexriscv', 'bad') + + def test_bad_variant_extension(self): + with self.assertRaises(subprocess.CalledProcessError): + self.run_variant('vexriscv', 'standard+bad') + + @unittest.skipIf(RUNNING_ON_TRAVIS, "No lm32 toolchain on Travis-CI") + def test_variants_lm32(self): + self.run_variants('lm32', ('standard', 'minimal', 'lite')) + + @unittest.skipIf(RUNNING_ON_TRAVIS, "No or1k toolchain on Travis-CI") + def test_variants_or1k(self): + self.run_variants('or1k', ('standard', 'linux'))