Rocket - core - 中断对流水线的影响
https://mp.weixin.qq.com/s/6d9_j-wAPmOwGjCosqRb9A
简单介绍中断对流水线的影响。
本文目录:
1. 即时影响 : ID
2. 即时影响 : EX
3. 即时影响 : MEM
4. 即时影响 : WB
5. 后续影响
以下正文:
1. 即时影响 : ID
csr.io.interrupt在ID阶段的使用有两处:
a. 在检查异常时使用:
b. 在ctrl_killd赋值时使用:
如果ctrl_killd为真,则id阶段的状态不再向ex阶段传递:
所以,中断的发生立即导致ID阶段当前的指令不再继续执行。
2. 即时影响 : EX
csr.io.interrupt在EX阶段的使用也有两处:
a. 用于对ex_reg_xcpt_interrupt进行赋值:
因为ex_reg_xcpt_interrupt是一个寄存器,所以影响需要在下一个时钟周期才会生效。
b. 用于对ex_reg_pc等寄存器进行赋值:
如果发生了中断,则使用ex_reg_pc等记录相关信息。这些都是寄存器,所以影响需要在下一个时钟周期才会生效。
总结上面两处用法,中断的发生不影响EX阶段当前正在执行的指令。但下一个时钟周期受到影响。
3. 即时影响 : MEM
因为csr.io.interrupt在MEM阶段没有使用,所以中断的发生不会立即影响到MEM阶段。
4. 即时影响 : WB
因为csr.io.interrupt在WB阶段没有使用,所以中断的发生不会立即影响到WB阶段。
5. 后续影响
从上面的分析可以看出,中断的发生立即对ID阶段产生影响,对EX/MEM/WB阶段没有立即影响。其中ID阶段的指令被kill,EX/MEM/WB阶段的指令在中断发生的时钟周期得以执行。那么后续的时钟周期ID阶段处于什么状态呢?中断如何逐步对EX/MEM/WB产生影响呢?
1) ID阶段的状态
如果csr.io.interrupt的状态没有清除,则ctrl_killd一直被触发,导致ID阶段一直无法进行工作。
这里出现一个问题:如果ID阶段一直无法工作,那么中断处理程序如何得到执行呢?
如果在用户态发生中断,那么执行中断处理程序之前,中断使能标志会被清除,同时变更核心到S/M态。这些变化会导致csr.io.interrupt标志被清除,这样ID阶段就可以进行工作了。
在中断发生的时钟周期(t):
a. ctrl_killd被触发,无法向EX阶段传递当前正在执行的指令:
b. 寄存器ex_reg_xcpt_interrupt的值将在下一个时钟周期更新为1;
c. 寄存器ex_reg_valid的值将在下一个时钟周期更新为0;
d. 寄存器ex_reg_pc的值,将在下一个时钟周期更新:
在下一个时钟周期(t+1):
因为ctrl_killd只是对EX阶段起作用,所以ID阶段仍然可以正常工作。状态如同在上一个时钟周期(t)。
2) EX阶段的状态变化
在中断发生的时钟周期(t),EX阶段不受影响。
在下一个时钟周期(t+1):
a. ex_reg_xcpt_interrupt = 1,mem_reg_xcpt_interrupt的值将在再下一个时钟周期赋值为1;
b. ex_pc_valid = 1 ;
c. ctrl_killx = 1:
d. ex_reg_pc等寄存器存入新值;
e. 因为ex_pc_valid = 1,所以mem_reg_pc寄存器的值将在下一个时钟周期被更新:
3) MEM阶段的状态变化
在中断发生的时钟周期(t):
MEM阶段不受影响,正常执行。
在时钟周期t+1 :
MEM阶段不受影响,执行时钟周期t传递过来的指令。
在时钟周期t+2 :
a. mem_reg_xcpt_interrupt = 1,mem_xcpt = 1,wb_reg_xcpt将在下一个时钟周期更新为1;
b. mem_reg_pc的值更新;
c. mem_pc_valid = 1,wb_reg_pc的值将在下一个时钟周期更新:
4) WB阶段的状态变化
在中断发生的时钟周期(t):
WB阶段不受影响,正常执行指令。
在时钟周期t+1:
WB阶段不受影响,正常执行指令。
在时钟周期t+2:
WB阶段不受影响,正常执行指令。
在时钟周期t+3:
a. wb_reg_xcpt = 1,触发take_pc_wb,导致执行流程跳转到mtvec中存放的异常处理基地址;
b. wb_reg_pc的值更新;存入epc寄存器: