Risk5 is a single-stage RISC-V CPU that implements the RV32I ISA. It is written with Hardcaml and can be compiled to Verilog or VHDL or simulated with a variety of backends -- see the Hardcaml README for more.
Though the current implementation is not (yet) pipelined, this design describes the five "stages" of the CPU. Data is depicted in black and control signals are in blue. PDF and tgif .obj versions of the design are in the diagram/
directory.
The modules in the lib/
directory map more-or-less directly to the modules described in the diagram. The most notable difference is that "instruction memory" is not implemented using Hardcaml's Ram
or multiport_memory
modules -- the program is loaded into the compiled HDL as a list of signals from which instructions are selected using the PC register. This was done primarily to simplify simulation and testing, as constructing a multiport_memory
module and writing program data to it proved to be difficult. The current implementation also includes an additional "CMP" module between "Decode" and "Next PC" that is used for comparison operations in branch instructions; the branch_cmp
signal is actually coming from CMP and not the ALU. This was also done to simplify the implementation at the cost of additional hardware.
To build the OCaml source code, you will need:
To build the verilog-generating executable, run dune build
. To run the inline tests, run dune test
.
The test/test_programs/
directory contains example RISC-V programs in assembly and plaintext hexdump formats. The build.sh
script compiles all assembly programs in the current directory. To build your own RISC-V programs, you will need the RISC-V GNU Toolchain.
To produce Verilog for a given program, build the risk5
executable with dune build
and run it as follows:
risk5 <program> <output>
For example, risk5 test/test_programs/load_store.txt output.v
will write Verilog that describes the CPU design and includes the program load_store.txt
to output.v
. To generate VHDL or simulate the CPU, use the --vhdl
and --waves
options as described in the risk5
usage instructions:
Usage:
risk5 [--vhdl] <program_path> <output_path>
risk5 --waves <num_steps> <program_path>
Run a RISC-V program on the Risk5 CPU or output a Verilog/VHDL specification
that includes the program data. Programs are formatted as plaintext hexdump files;
see test/test_programs/ in the Risk5 source directory for examples.
--vhdl Output VHDL instead of Verilog
--waves <num_steps> Simulate num_steps instructions and display waveforms in an interactive viewer
--help Display this list of options
-help Display this list of options
The following resources were very helpful in learning how to use Hardcaml and implementing a RISC-V CPU:
- hardcaml-mips and the accompanying blog posts
- The Hardcaml Manual
- RISC-V Specification
- RISC-V Opcodes
- CSCE 513 notes, specifically this PDF