Rocket - core - bypass或者stall

https://mp.weixin.qq.com/s/g2oTABxX1RXp03sod87hmw

 

简单介绍bypass或者stall之间的差异。

 

 

1. 概述

 

bypass的条件与stall的条件并不相同,甚至应该互斥。即不能bypass的则stall,不stall的则bypass。前提条件是存在hazard。下面针对这两种情况进行分析。

 

2. bypass的判断条件

 

bypass的条件由id_bypass_src根据bypass_sources中定义的情况确定:

以ID/EX两个阶段的hazard为例,要bypass的情况,简单而言就是RAW,即Read After Write,即ID阶段的指令,需要EX阶段指令要回写的寄存器的值。(由于用来做bypass的数据来自于mem_reg_wdata,而mem_reg_wdata使用alu.io.out进行更新,所以EX阶段指令的rd的值必须来自于alu.io.out。)

 

3. stall的判断条件:以ID/EX两个阶段的hazard为例

 

以ID/EX两个阶段的hazard为例,stall的条件为:

忽略fpu hazard,就是data hazard去掉一些不能bypass的情况。

 

这里的data hazards包含RAW和WAW两种情况:

a. ex_waddr与id_raddr1/id_raddr2进行比对;

b. ex_waddr与id_waddr进行比对;

 

不能bypass的情况,则不是单纯的从理论上来考虑,还包括一些实现上没有bypass的情况。

首先从理论上而言,不能bypass而必须stall ID阶段的指令的原因,就是EX阶段的指令无法及时的给出所需要的数据。包括:

a. 计算需要的时间过长;

b. 读取所需要的时间过长;

 

从当前的实现而言,

a. mul/div/fp/rock/scie表示计算所需要的时间过长;

b. mem表示获取所需要的时间过长(在最快即dcache命中的情况下,在WB阶段才能返回数据);

 

那么另外的两种情况呢?为什么csr和jalr不能bypass呢?这是因为实现的原因。

 

4. 为什么jalr不能bypass而jal可以?

 

这是一个很容易联想到的问题。

首先看jal指令的情况:

其效果如下:

a. PC + imm => target address;

b. PC + 4 => rd;

 

jalr指令在规范中的描述如下:

其效果如下:

a. rs1 + imm => target address;

b. PC + 4 => rd;

 

看上去并没有太大的差异。在看二者的实现:

可以看到,虽然都使用alu做加法运算,但是jal指令使用alu计算PC + 4,而jalr使用alu计算rs1 + imm。jal指令的PC + 4后续回写到rd,而jalr指令的rs1 + imm却不会回写到rd。

 

所以对jalr指令,不能将alu.io.out的值用于bypass。而在bypass的实现中,只使用的是mem_reg_wdata进行bypass,其值来自于alu.io.out:

 

所以jalr不能用于bypass,而jal可以。CSR指令的情况也类似:

 

alu计算的结果要存入csr,而不是rd:

 

5. 小结:以ID/EX两个阶段的hazard为例

 

1) data hazards

使用图形表示,data hazards的情况,包括在如下的矩形中:

 

2) RAW和WAW

data hazards包括RAW和WAW两种情况:

 

3) ex_cannot_bypass

如果加上ex_cannot_bypass代表的情况,其关系图示如下:

其中:

针对RAW的情况:

a. bypass判断时,判断了RAW的情况:

b. ex_cannot_bypass从RAW中排除了一些不能bypass的情况,必须要stall;

c. RAW中剩余的情况,就是实际bypass了的情况;

 

针对WAW的情况:

a. WAW的全部情况都不需要bypass;

b. WAW的部分情况需要stall,如ex_ctrl.mem代表的情况。所以ex_cannot_bypass也从WAW中排除了一些情况;

 

4) 跳出data hazards之外

如果跳出data hazards之外,考虑与ex_cannot_bypass的关系,其关系如下图:

ex_cannot_bypass中包含了一些data hazards中不包含的情况。如果没有data hazards的限制,这些情况也会导致stall。加上了data hazards的限制之后,这些情况则不会导致stall。也就是说存在一些情况,虽然前面一条指令需要花较长时间而没有执行完成,但后一条指令却没有被stall而继续执行。在这种情况下,后一条指令先于前一条指令完成。

 

考虑如下指令序列:

1: load

2: nop

第1条指令属于ex_cannot_bypass的情况(ex_ctrl.mem = true),但两条指令不是data hazards(既不是RAW,也不是WAW)。不满足id_ex_hazard的条件:

所以不会导致第2条指令stall在ID阶段。而是会继续沿着流水线经过EX/MEM/WB阶段执行完毕。

 

因为第一条指令的信息存放在sboard中,另一部分经过io.dmem.req被dcache模块记录,dcache模块返回时会带有相关的信息,所以不影响返回结果回写寄存器。

 

posted @ 2022-03-21 20:16  wjcdx  阅读(243)  评论(0编辑  收藏  举报