Interrupts And Exceptions

Exceptions

An exception is a synchronous event that occurs during the execution of a program, disrupting the normal flow of instructions. Exceptions can arise for various reasons:

  • Fault exception: These occur when the CPU encounters an issue while executing an instruction. Examples include instruction address misalignment, instruction access faults (e.g., trying to access a protected memory region), illegal instruction execution…

  • Desired exception: Some exceptions are intentionally generated by the programmer. For instance, a system call instruction is designed to generate an exception, and this is typically initiated by the programmer for specific operations requiring privileged access.

Usually normal program execution, the CPU operates in the least privileged execution mode, referred to as U-mode (User Mode), limiting he programmer’s access to certain memory regions and instructions. When an exception occurs, the CPU saves the current execution mode and switches to the most privileged mode, called M-mode (Machine Mode). Subsequently, the program counter (PC) is loaded with the address of the exception handler routine.

RISC-V defines an exception code for each event:

Exception Codes

Code

Description

0

Instruction address misaligned

1

Instruction access fault

2

Illegal instruction

3

Breakpoint

4

Load address misaligned

5

Load access fault

6

Store address misaligned

7

Store/AMO access fault

8

Environment call from U-mode

11

Environment call from M-mode

In the RISC-V architecture, each exception event is associated with an exception code, providing information about the specific type of exception encountered. These exception codes are generated by instructions as they progress through the CPU pipeline, with earlier stages taking precedence. The exception code is crucial and is carried within the instruction packet throughout the pipeline. Exception handling is initiated when a specific bit is set in the instruction packet during the writeback stage.

Interrupts

Interrupts are asynchronous events that interrupt the normal execution flow of the CPU. Unlike exceptions, interrupts can occur independently of the CPU’s instruction execution and are typically triggered by external devices. There are several types of interrupts:

  • Normal Interrupt Request: General interrupt that comes from a system device / IO device.

  • Timer Interrupt Request: The RISC-V architecture includes a timer interrupt that generates a signal when a specific timer threshold is reached.

  • Non Maskable Interrupt Request: High priority interrupt signal that cannot be masked / ignored.

In addition to the interrupt pins, there’s a 7 bit bus that encodes an interrupt vector. In complex systems, multiple devices can generate interrupts, and the vector identifies a specific interrupting device. Vectored interrupts are supported in many architectures. In this mode, the PC is loaded based on a base address and an interrupt vector acting as an offset. This enables each interrupting source to have its own interrupt handler, and the PC points to a location in an interrupt table, typically containing a jump instruction to the actual handler.

Upon receiving an interrupt, the CPU follows a sequence of actions similar to exception handling. However, there’s an additional step known as the acknowledge cycle, during which the CPU briefly pulses the interrupt acknowledge pin to clear the interrupt source. This step ensures that the interrupt is properly acknowledged and does not cause repeated interruptions.