流水线

RISC 五级流水

五级流水
IF(Instruction Fetch)ID(Instruction Decoder)EX(Execute)MEM(Memory)WB(Write)

异常源

IF

Fetch 过程需要访存, 可能会导致非对齐访问, 物理内存越界, 虚拟地址没有被映射, 内存无执行权限(页表没有X权限, 或特权模式异常).

ID

ID 过程对指令格式进行解析, 为后续的选择器指定信号源(相当于配置cpu功能).

可能导致的异常包括: 非法指令, ECALL/EBREAK 等特权指令.

EX

可能的异常包括: 算数异常(如: 除零).

MEM

大部分的异常发生在访存阶段: 非对齐地址, 物理内存不存在(mmio异常), 页异常(页权限不足, 页不存在).

同时, 注意: MEM 的行为是有副作用的, 例如某些外设寄存器被读/写之后的状态会改变.

WB

WB 在几乎所有的 architecture 下都不会产生异常, 因为通用寄存器的数量, 一般和指令中寄存器编码的宽度一致.

WB 与 MEM 一样, 都是有副作用的过程.

异常的处理

一条指令的流水中有非常多的过程会产生异常. 一但触发异常, 需要通过 Trap 的方式进行处理(可恢复的异常)/终止执行(不可恢复的异常). riscv 规定, Trap 发生在指令执行完之后, 经过 Trap 流程后, 回到 m/sepc 处恢复之前的执行流程.

对于产生异常的指令, 有的需要重新执行, 有的可以直接执行下一条(ECALL), 而对一条指令重新执行需要重点考虑.

CPU 是一个状态机, 因此, 对某一条指令执行两次, 有可能导致与执行一次的状态不同, 因此, 需要重点考虑会产生副作用的过程. 如果一条指令在 MEM 处发生异常, 那么此刻, 写入/读取操作必须没有被完成(否则, 重新执行该指令, 会得到不一样的结果). 如果异常发生在 WB 阶段, 此时访存操作已经发生, 那么该指令将无法被重复执行, 则导致异常处理的困难. 正因此, WB 阶段一般不允许抛出异常导致中断.