Rocket RISC-V processor - Adding a custom CSR, hardware point of view
Introduction
In the context of a research project related to RIMI [1], we need to add a new CSR (Control & Status Register) in the Rocket processor [2] in order to store new security settings. There are obviously modifications to do in the hardware description of the processor. This blog article tries to sum up what needs to be done.
Hardware stack of the Rocket Chip
The first difficulty with the Rocket Chip is its implementatinon langage, Chisel. It is recommended to learn the basics before going deeper in the Rocket Chip. Some resources:
- Chisel bootcamp. A bootcamp based on Jupyter notebooks. Docker container seems a bit buggy, but it is still possible to use it offline.
- Chisel book. A book with several exercises and slides!
Adding a custom CSR - Use case
Initial configuration
Let’s say we want to add a custom CSR labeled dmpcfg
at address 0x308
(CSR ID isn’t used by any existing register).
Declaring the CSR in the Rocket Chip
The first thing to do is to create the dmpcfg
register in Instructions.scala file. This file contains opcodes of each instruction as well as labels and addresses.
|
|
Note: line numbers may differ with an up-to-date Rocket Chip repository.
This step only declare the additional CSR. However, as it is left unconnected, the Scala-to-Verilog transformation will not keep the dmpcfg
CSR in its implementation.
Adding the CSR as default in the hardware implementation
|
|
Three lines have been added in the CSR Rocket file:
val reg_dmpcfg = Reg(UInt(width=xLen))
: declaring a register ofxLen
-long unsigned integers.xLen
is usually 64 bits.when (decoded_addr(CSRs.dmpcfg)) { reg_dmpcfg := wdata }
: when the core decodes the CSR address, it will copy the date in the register previously declared.CSRs.dmpcfg -> reg_dmpcfg
: adding the CSR in the CSR list known asread_mapping
.
read_mapping
and CSR subsets
The initial list of CSR is declared here: https://github.com/chipsalliance/rocket-chip/blob/v1.5/src/main/scala/rocket/CSR.scala#L610
|
|
As the Rocket Chip is more a processor generator rather than a basic implementation, we can add CSR subsets depending on some features. For instance, if we need debug:
|
|
These CSRs are added a bit later in read_mapping
:
|
|
In our case, for a first try, we have simply added the dmpcfg
register in the default CSRs subset. Then, the Scala-to-Verilog can be executed. We are able to see the new CSR in the Verilog file and play with the small software described in a previous article.
In the generated Verilog file:
|
|