-
Notifications
You must be signed in to change notification settings - Fork 0
Available Instruction Set
The DRISC-V Architecture uses RV32I as its base, meaning it operates with 32-bit instructions and 32-bit memory addresses. It includes 32 general-purpose registers available for most operations.
The following table lists the registers available in the processor. While each register has a recommended role defined by the non-ISA ABI (Application Binary Interface) specification—and these roles are enforced in real-world applications—beginners don’t need to worry about them too much at this stage. This guide introduces them gradually, with deeper explanations provided in later pages.
| Register | ABI Name | Description |
|---|---|---|
| x0 | zero | Constant value 0 |
| x1 | ra | Return address |
| x2 | sp | Stack pointer |
| x3 | gp | Global pointer |
| x4 | tp | Thread pointer |
| x5 | t0 | Temporary register |
| x6 | t1 | Temporary register |
| x7 | t2 | Temporary register |
| x8 | s0/fp | Saved register / frame pointer |
| x9 | s1 | Saved register |
| x10 | a0 | Function argument / return value |
| x11 | a1 | Function argument / return value |
| x12 | a2 | Function argument |
| x13 | a3 | Function argument |
| x14 | a4 | Function argument |
| x15 | a5 | Function argument |
| x16 | a6 | Function argument |
| x17 | a7 | Function argument |
| x18 | s2 | Saved register |
| x19 | s3 | Saved register |
| x20 | s4 | Saved register |
| x21 | s5 | Saved register |
| x22 | s6 | Saved register |
| x23 | s7 | Saved register |
| x24 | s8 | Saved register |
| x25 | s9 | Saved register |
| x26 | s10 | Saved register |
| x27 | s11 | Saved register |
| x28 | t3 | Temporary register |
| x29 | t4 | Temporary register |
| x30 | t5 | Temporary register |
| x31 | t6 | Temporary register |
The following table shows every available instruction in the DRISC-V Architecture. Although only 5 bits are shown here, RV32I opcodes use 7 bits in total. The first 2 bits ([1:0]) are always 11, indicating a 32-bit instruction. While the instruction set may seem minimal, each opcode supports multiple variants and parameters that expand its functionality.
Note: An opcode (operation code) is the portion of a machine instruction that specifies the operation to be performed.
| Bits [6:2] | 000-- | 001-- | 010-- | 011-- | 100-- | 101-- | 110-- | 111-- |
|---|---|---|---|---|---|---|---|---|
| ---00 | LOAD | OP-IMM | STORE | OP | BRANCH | SYSTEM | ||
| ---01 | AUIPC | LUI | JALR | |||||
| ---10 | ||||||||
| ---11 | JAL |
The instructions are described in more detail in later pages of this wiki. For now, here's a brief overview of their functionality:
These instructions handle data exchange between system memory (RAM) and the processor’s internal registers. Since RISC-V is a register-register architecture, Load and Store are the only instructions that interact with memory directly. All other instructions operate solely on internal registers.
Short for Operation and Operation-Immediate, these instructions perform arithmetic and logic operations in the ALU (Arithmetic and Logic Unit). The immediate variants allow embedded constants to be used instead of registers. For example, you can add a register value to a 12-bit immediate encoded directly in the instruction. Immediate sizes vary across the instructions, but ALU operations typically use 12-bit immediates.
These are unconditional jump instructions. When executed, they change the program counter(PC) to a target address and save the return address in a register.
-
JAL(Jump and Link) uses a 20-bit immediate added to the current address. -
JALR(Jump and Link Register) adds a register value to a 12-bit immediate, allowing jumps to absolute memory positions.
Branch instructions perform conditional jumps based on comparisons between two registers. If the condition is met, a small immediate is added to the current address to determine the jump target. Unlike JAL and JALR, Branch instructions do not save the return address.
These instructions load 20-bit constants into registers.
-
LUI(Load Upper Immediate) places the value in the upper 20 bits of a register. -
AUIPC(Add Upper Immediate to PC) adds the immediate to the current program counter.
These are often used in combination with OP-IMM to construct full 32-bit constants.
System instructions provide access to privileged operations and special architectural features. These include environment calls, CSR (Control and Status Register) access, and other control mechanisms. More details are available in later pages of this wiki.
The DRISC architecture provides 4 ISA extensions: U, Zmmul, Zicsr and the Zicntr.
The Zmmul extension enables multiplication operations in the ALU (Arithmetic and Logic Unit). Its name may seem complex, but it simply refers to a subset of the broader M extension, which also includes division and modulo operations.
Division was intentionally excluded from this project to keep the implementation manageable. Division circuits are significantly more complex than multiplication, and while the internal logic of mathematical operations is abstracted in simulations, it was decided to omit division for now. However, it may be added in future versions.
All multiplication operations are handled through the OP instruction format and support 32-bit operands. The result of a multiplication can be accessed either as the lower 32 bits or the upper 32 bits of the full 64-bit result.
Currently, the implementation does not include any optimization for consecutive instructions that retrieve both the upper and lower parts of the result. This choice simplifies the design and keeps the architecture clean for educational and prototyping purposes.
With only the base instruction set, the RISC-V architecture operates exclusively in what is called Machine mode (also known as kernel mode in other architectures). In this mode, programs have unrestricted access to all system resources. While this may be acceptable for certain applications, modern general-purpose computing requires a more secure and controlled environment—where critical operations are reserved for the operating system (OS), and user applications are limited in what they can access.
RISC-V defines three privilege levels, but in DRISC-V only two are relevant: Machine mode (M) and User mode (U). The U extension introduces support for user mode by defining key registers and control signals that enable privilege separation. This allows the processor to distinguish between trusted system-level code and untrusted user-level applications, laying the foundation for multitasking, memory protection, and secure execution.
The Zicsr extension introduces support for Control and Status Registers (CSRs) in RISC-V, along with a set of system-level instructions that enable their manipulation. These instructions facilitate operations such as system calls, environment breaks, and other privileged tasks.
CSRs provide essential information about the processor’s current state. This includes details such as the processor’s version, supported instruction sets, privilege levels, and interrupt configurations. Their implementation may vary depending on the processor design and the supported extensions.
Note: Not all CSRs defined in the RISC-V specification are required to be implemented. Additionally, some implemented CSRs may not support all specified bits. Certain CSRs are introduced through other extensions, which will be discussed in later sections.
| Register | Description | Notes |
|---|---|---|
mvendorid |
Identifies the vendor | Fixed value: 0x00af001d
|
marchid |
Identifies the architecture | Fixed value: 0x00000000
|
mimpid |
Implementation ID | Unique per architecture revision |
mhartid |
Hardware thread ID | Fixed value: 0x00000000 (single-core) |
mstatus |
Processor status flags | Implements: Previous Privilege (PP), Interrupt Enable (IE), Previous IE (PIE) |
misa |
ISA extensions supported | Extensions: E, I, M (no division), U; disabling not supported |
mie |
Interrupt enable bits | Supports machine-level software, timer, and external interrupts |
mtvec |
Trap-handler base address | Default: 0x80000001 → base 0x80000000, vectored mode |
mstatush |
Upper bits of mstatus
|
Only relevant bit: user-mode endianness (fixed to 0) |
mscratch |
Temporary storage for trap handling | Used during trap execution |
mepc |
Exception program counter | Stores last accessed address before a trap |
mcause |
Trap cause | Includes interrupts and exceptions (e.g., misaligned address, illegal instruction) |
mtval |
Trap value | Contains the instruction or address that caused the trap |
mip |
Pending interrupt flags | Controlled by external devices; mirrors mie bits |
cycle |
Cycle counter | Increments every clock cycle; each pipeline stage takes 2 cycles |
time |
Time counter | Triggers a memory load when read |
instret |
Instruction retirement counter | Increments per instruction (every 2 cycles); does not increment during exceptions |
cycleh |
Upper 32 bits of cycle
|
|
timeh |
Upper 32 bits of time
|
|
instreth |
Upper 32 bits of instret
|
Each register has its own format, minimum privilege level required for access, and may contain read-only fields. Detailed information about these characteristics can be found in the Privileged RISC-V Specification. The previous table outlines the implementation of each CSR, indicating which bits are implemented and whether they are read-only.
The Zicntr extension defines three essential read-only counters in RISC-V: cycle, time, and instret. These counters track the number of clock cycles executed, real-time elapsed, and instructions retired, respectively. Zicntr depends on the Zicsr extension for CSR access.
These counters are fundamental for performance analysis, dynamic optimization, and real-time applications. Each counter is 64 bits wide, but since CSRs are limited to 32 bits in systems like DRISC-V, the lower and upper parts of each counter are accessed separately through different CSRs.
While the counters are standardized, their behavior may vary slightly depending on the execution environment. For example, the rate at which cycle increments depends on the processor's clock, and time reflects wall-clock time with platform-specific accuracy. Instruction retirement excludes operations that trigger synchronous exceptions, such as ECALL and EBREAK.
In DRISC-V, the instret counter increases once every two clock cycles, which corresponds to the length of each pipeline cycle and, consequently, the time it takes for each instruction to complete. Although time is intended to use a real-time clock, its value is simulated in DRISC-V environments. Further details on this simulation will be provided in the corresponding documentation pages.
-
- 1.1 Introduction
- 1.2 RISC-V Implementation
- 1.2.1 Available Instruction Set
- 1.2.2 Available Non-ISA Features
-
- 2.1 ALU
- 2.2 Register File
- 2.3 Program Counter
- 2.4 Input Buffer
- 2.5 RAM
- 2.6 Operation Controller
- 2.7 CSR Controller
-
- 3.1 Input Devices
- 3.1.1 Keyboard
- 3.1.2 Switches and Joystick
- 3.1.3 Random Number Generator
- 3.1.4 Real-Time Device
- 3.2 Output Devices
- 3.2.1 Screen
- 3.2.2 Terminal
- 3.2.3 Software Interrupt Register
- 3.1 Input Devices