Rocket - core - pipeline和replay
https://mp.weixin.qq.com/s/6PBY-seJ6Cj2-yzQD_HAJg
简单介绍流水线对replay的处理。本文不研究为什么会发生replay。
1. replay的效果
replay经流水线传递之后,最终在wb阶段起作用:
即触发take_pc_wb,以wb_reg_pc作为地址重新取指进行执行:
这个wb_reg_pc中存放的就是wb阶段当前指令的地址。也就是说要重新执行一遍,即replay。
2. replay的触发
replay的触发,包括如下几种情况。
id阶段的ibuf.io.inst(0).bits.replay声明指令需要重新执行:
两个是ex阶段的hazard导致:
两个是mem阶段的dcache_kill_mem和fpu_kill_mem导致:
一个是WB阶段io.dmem.s2_nack导致:
可以看到,几乎每个阶段都会触发指令的重新执行。
3. replay在流水线上的传播
1) ID阶段
ibuf.io.inst(0).bits.replay声明指令是否需要重新执行,在经过相应条件过滤之后,其值用于更新ex_reg_replay:
这里ibuf.io.inst(0).bits.replay导致了ctrl_killd,使得id阶段被kill,无法正常传播到ex阶段。跟中断的处理类似,当前指令的pc可以随流水线传递下去,以在wb阶段决定重新执行哪一条指令:
2) EX阶段
在EX阶段,ex_reg_replay的值用于生成replay_ex信号,而后replay_ex经过take_pc_xxx的过滤,用于更新mem_reg_replay:
这里除了ex_reg_replay之外,又增加了replay_ex_structural和replay_ex_load_use两种情况,触发replay_ex。
replay_ex触发ctrl_killx,导致ex阶段被kill,无法正常传播到mem阶段。跟中断的处理类似,当前指令的pc可以随流水线传递下去,以在wb阶段决定重新执行哪一条指令。所以这里ex_reg_replay用于改变ex_pc_valid的值。
3) MEM阶段
在MEM阶段,mem_reg_replay用于生成replay_mem信号,而后replay_mem经过take_pc_xxx的过滤,用于更新wb_reg_replay:
这里除了mem_reg_replay之外,又增加了dcache_kill_em和fpu_kill_mem两种情况,触发replay_mem。
replay_mem触发ctrl_killm,导致mem阶段被kill,无法正常传播到mem阶段。跟中断的处理类似,当前指令的pc可以随流水线传递下去,以在wb阶段决定重新执行哪一条指令。所以这里mem_reg_replay用于改变mem_pc_valid的值。
4) WB阶段
在WB阶段,wb_reg_replay用于生成replay_wb信号(不考虑rocc),而后用于生成take_pc_wb信号:
这里除了wb_reg_replay之外,又增加了io.dmem.s2_nack这种情况(不考虑rocc),触发replay_wb。
而后take_pc_wb触发take_pc,要求流水线重新取指,把WB阶段的当前指令重新执行。