csr_registers
Introduction
RISC-V Control and Status Registers (CSRs) are an integral part of the RISC-V architecture, serving as a set of special-purpose registers that control and manage the processor's behavior, as well as store system status information. They play a crucial role in handling privilege levels, exceptions, and various system operations.
The CSR registers are categorized into machine-level CSRs, supervisor-level CSRs, hypervisor-level CSRs (in systems that support virtualization), and user-level CSRs. Each privilege level has its own set of CSRs, providing control over different aspects of the processor's functionality. 1
The CSRs handle a wide range of functionalities, including:
Control of Privilege Levels: Certain CSRs manage the transition between privilege levels, facilitating the shift between user mode and higher privilege modes (supervisor or machine mode).
Exception Handling: CSRs hold information related to exceptions, interrupts, and traps, enabling the processor to handle these events effectively. They store exception causes, trap handling addresses, and interrupt enable/disable flags.
Performance Monitoring: Some CSRs are dedicated to performance monitoring and counters, offering insights into the processor's performance metrics and aiding in optimization.
System Configuration: These registers often contain system configuration and setup details, allowing the processor to control various functionalities, such as cache behavior or memory mapping.
Machine Specific Registers: CSRs that cater to specific functionalities or extensions, which can vary based on the particular implementation or optional extensions of the RISC-V architecture.
Understanding and managing CSRs are crucial for system developers, as they directly impact how the processor operates at different privilege levels, handles exceptions, and interacts with the system. However, the specifics of these registers, including their number, functionalities, and their accessibility across different privilege levels, can vary based on the RISC-V implementation or extensions used in a particular system.
The RISC-V architecture's openness and modularity allow for flexibility in implementing CSRs, providing space for customization and adaptation to various system requirements. This adaptability also facilitates the incorporation of new extensions and features into the processor design without altering the fundamental architecture, making RISC-V CSRs a pivotal aspect of its versatility.
RISC-V defines a separate address space of 4096 Control and Status registers.
CSR specifications and implementations
To implement RISC-V Control and Status Registers (CSRs), two RISC-V specifications are used: one is the unprivileged spec and the other is the privileged spec.
Within the CSR context, the unprivileged specification covers fundamental aspects, such as general read and write conditions and types of csr instructions. On the other hand, the privileged specification delves deeper, offering detailed insights into these registers, including their specific addresses and accessibility criteria, defining which privilege levels, such as user or supervisor, can access them.
CSR Instruction Types
The following information is based on unprivileged spec, chapter 9.
The
csrfield represents the address of the CSR. We can understand that there are 4096 possible csr registers(we wont use them all)1.The
rs1field represents the source register. This is the register from which the value is read and written to the CSR, it also represents the immediate value instructions.2The
funct3field represents the function of the instruction. It can be eitherread,writeorread and write.
001 - for csrrw - read and write
010 - for csrrs - read and set
011 - for csrrc - read and clear
101 - for csrrwi - read and write immediate
110 - for csrrsi - read and set immediate
111 - for csrrci - read and clear immediate
The
rdfield represents the destination register. This is the register to which the value is written to from csr.The
opcodefield represents the opcode of the instruction. It is always1110011for csr instructions.
CSR Read and Write Conditions
The following information is based on unprivileged spec, chapter 9.
- Register Operand (rs1 is a register) read/write policy:
| Instruction | rd | rs | read CSR? | write CSR? |
|---|---|---|---|---|
| CSRRW | x0 | - | no | yes |
| CSRRW | !x0 | - | yes | yes |
| CSRRS/C | - | x0 | yes | no |
| CSRRS/C | - | !x0 | yes | yes |
- Imemdiate Operand (rs1 is a
uimmfield) read/write policy:
| Instruction | rd | rs | read CSR? | write CSR? |
|---|---|---|---|---|
| CSRRWI | x0 | - | no | yes |
| CSRRWI | !x0 | - | yes | yes |
| CSRRS/CI | - | 0 | yes | no |
| CSRRS/CI | - | !0 | yes | yes |
- Those tables implemented inside the control unit of the big core.
assign CsrInstQ101H.csr_wren = (OpcodeQ101H == SYSCAL) && !(((Funct3Q101H[1:0] == 2'b11) || (Funct3Q101H[1:0] == 2'b10)) && (CtrlQ101H.RegSrc1 =='0 ));
assign CsrInstQ101H.csr_rden = (OpcodeQ101H == SYSCAL) && !((Funct3Q101H[1:0]==2'b01 ) && (CtrlQ101H.RegDst =='0 ));
CSR instructions examples
csrrw a5,vxsat, a4
- In that instruction, the value of
vxsatis written toa5and the value ofa4is written tovxsat. Do not spend time to understand the meaning of thevxsatregister, generally speaking it just a CSR register name. You can find other CSR register names in the privileged spec, chapter 2 but its not that important for now. - for example: suppose that
vxsatis equal to 0x00000100 anda4is equal to 0x00000001, after executing the instruction,a5will be equal to 0x00000100 andvxsatwill be equal to 0x00000001.
csrrwi a5,vxsat,27
- In that instruction, the value of
vxsatis written toa5and the value of 27 is written tovxsat.
csrrs a5,vxsat,a4
- In that instruction, the value of
vxsatis written toa5and the value ofa4is used to set the bits ofvxsatto 1 any place thata4has 1 otherwise the bits ofvxsatwill not be changed. - for example: suppose that
vxsatis equal to 0x00000100 anda4is equal to 0x00000001, after executing the instruction,a5will be equal to 0x00000100 andvxsatwill be equal to 0x00000101.
csrrsi a5,vxsat,27
- In that instruction, the value of
vxsatis written toa5and the value of 27 is used to set the bits ofvxsatto 1 any place that 27 has 1 otherwise the bits ofvxsatwill not be changed.
csrrc a5,vxsat,a4
- In that instruction, the value of
vxsatis written toa5and the value ofa4is used to clear the bits ofvxsatto 0 any place thata4has 1 otherwise the bits ofvxsatwill not be changed. - for example: suppose that
vxsatis equal to 0x00001100 anda4is equal to 0x00000111, after executing the instruction,a5will be equal to 0x00001100 andvxsatwill be equal to 0x00001000.
csrrci a5,vxsat,27
- In that instruction, the value of
vxsatis written toa5and the value of 27 is used to clear the bits ofvxsatto 0 any place that 27 has 1 otherwise the bits ofvxsatwill not be changed.
CSR instructions examples (read or write only)
There are some CSR instructions that are read or write only. Those instructions can be done by using the above instructions for example:
Write to CSR only:
csrrw x0, vxsat, rs
- You may use pseudo instruction
csrw vxsat, rsinstead of the above instruction.
csrrwi x0, vxsat, imm
You may use pseudo instruction
csrwi vxsat, imminstead of the above instruction.Read from CSR only:
csrrs rd, csr, x0
- You may use pseudo instruction
csrr rd, csrinstead of the above instruction.
For more information about the CSR read/write only instructions, refer to the unprivileged spec, chapter 25 - RISC-V assembly Programmer's Handbook.

Generate CSR instructions in C code
- In order to use CSR instruction in C code and not directly in assembly, we need to use the
asm volatilecommand. The following code snippet shows how to use CSR instructions in C code.
asm volatile ("csrw 0x009, 0x7");
This instruction will write the value 0x7 to the CSR register 0x009 and generate the following instruction in
_elf.txtfile :csrwi vxsat,7In our implementation we are using the CSR register
scratchpad_csrwhich address is equal to 0x009. The compiler change its name tovxsatas described in the privileged spec, chapter 2. Please do not worry about the names of the CSR registers, you may play with those addresses as you wish and examine_elf.txtfile to see the changes. Make sure to supply the correct address of the CSR as defined int_csr_addrenumerator in the big core package file.For more instructions using asm volatile, please go to
/verif/big_core/test/alive_csr.c, We suggest to compile the file and look at the_elf.txtfile to see the generated instructions.
CSR instructions implemented in the big core
- CSR control signals are generated in the control unit of the big core. The following code snippet shows the CSR control signals generation.
// CSR Control Signals
assign CsrInstQ101H.csr_wren = (OpcodeQ101H == SYSCAL) && !(((Funct3Q101H[1:0] == 2'b11) || (Funct3Q101H[1:0] == 2'b10)) && (CtrlQ101H.RegSrc1 =='0 ));
assign CsrInstQ101H.csr_rden = (OpcodeQ101H == SYSCAL) && !((Funct3Q101H[1:0]==2'b01 ) && (CtrlQ101H.RegDst =='0 ));
assign CsrInstQ101H.csr_op = InstructionQ101H[13:12];
assign CsrInstQ101H.csr_rs1 = CtrlQ101H.RegSrc1;
assign CsrInstQ101H.csr_addr = InstructionQ101H[31:20];
assign CsrInstQ101H.csr_data_imm = {27'h0, CtrlQ101H.RegSrc1};
assign CsrInstQ101H.csr_imm_bit = InstructionQ101H[14];
The used typedef struct is defined in the big_core package file
CSR unit located in
Q102Hexecution stage because we need to forward data to rd if necessary.CSR register defined in the core package file under
t_csr_addrenumerator which includes all the CSR addresses used in the core and the registers them self in thet_csrstruct
PMON measurments
note: The following csr's defined in source/big_core core.
- Please refer to pmon link.
Custom CSR's
note: The following csr's defined in source/big_core core.
- timer interrupt exception csr's:
csr_custom_mtime- Used to measure time of our system. This csr is read only from software and can be updated only in HW. Each clock it decrements by one. Used only in machine mode.csr_cutome_mtimecmp- This csr is RW csr and used for comparison withcustom_mtime. We use it in Timer interrupt exception. See exceptionscsr_custom_LFSR- Used for generating pseudo random numbers. The algorithm is based on LFSR algorithm. For biggest cycle we used the following Polynom:x^32 + x^22 + x^2 + x^1 + 1. That Csr is RO and can be updated by HW for seed value update.