As RISC-V is a new architecture so there will be new development at all layers of the software and hardware stack. Rather than write code based on human language specifications from scratch, a smarter way to work can be to translate a machine readable specification to code.
“Machine Readable” does not need to be an all encompassing formal model of the architecture, there are many convenient formats such as csv, yaml, xml and json that can be parsed and transformed using the packages available in most scripting languages.
My preferred method is to use a modern scripting language and a template language from the web development world.
- The flow for this blog: YAML -> Ruby + Liquid -> HTML
- The flow for code examples: SVD/XML/YAML -> Python + Jinja -> C/C++
More details are in these posts: RISC-V CSR Access and Code Generation from XML/SVD using Jinja
Looking at SiFive’s BSP/SDK generation flow you can see a similar flow for linker scripts using pydevicetree and Jinja.
ISA Data Files
This is a quick list of the machine readable specifications I’ve created or found while putting together this blog. These are files that can quickly transformed into code or documents.
These are available from the RISC-V foundation:
- The RISC-V Configuration Spec
- The purpose seems to be targeting compliance, to describe what features are implemented: Examples
- RISC-V Opcodes. A custom format that is quite easy to parse.
- Operations. Source code fragments per instruction from the spike simulator.
My quick and dirty attempts at assembling machine readable ISA data was put together a few years ago. The purpose generate code and quick reference pages with links to detailed specs. They are in this GitHub repo.
- Control and Status Registers.
- Instructions and Opcodes
- Registers, ISA Variants and Extensions
The main sources of data here I’ve found for platforms are SVD and Device Tree. These are not RISC-V specific and are used for many platforms.
e.g Platform Platform from SiFive’s BSP:
- freedom-e-sdk/bsp/sifive-hifive1-revb/design.svd. Readable with CMSIS-SVD python pip. (And itself generated from DTS and peripheral SVDs.
- bsp/sifive-hifive1-revb/core.dts. Readable with libfdt or pydevicetree.
An example of generating a fresh set of C++ device definitions from the above device data is here: https://github.com/five-embeddev/sifive-cxx-mmio-devices.
Formal ISA Specifications
At the other end of the spectrum are formal models. These describe the ISA for use with verification or behavioral synthesis design flows.
There is a RISC-V ISA model written in “Sail”.
I’ve put this last as domain specific languages/schemas are not as easy to parse and utilize, but on the other hand they are more powerful. (This post is about ARMv8, but it gives details on the power of formal machine readable specifications.)
Sail seems to be designed for verification flows. Other ISA specification languages are designed for behavioral synthesis of Application Specific Instruction set Processor (ASIP) (such as nML from Synopsys). I don’t know if there is such a RISC-V implementation.