Skip to content

Available Instruction Set

Diogo Valadares Reis dos Santos edited this page Aug 26, 2025 · 5 revisions

[Português]

[← Previous Page | Next Page →]

Base 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.

RV32I Registers

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.

DRISC-V Opcodes

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:


Load and Store

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.


OP and OP-IMM

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.


JAL and JALR

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

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.


LUI and AUIPC

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

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.

ISA Extensions

The DRISC architecture provides 4 ISA extensions: U, Zmmul, Zicsr and the Zicntr.

Zmmul Extension

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.

U Extension

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.

Zicsr Extension

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.

Machine-Level CSRs and Counters

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.

Zicntr Extension

Zicntr Extension Summary

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.

Clone this wiki locally