Skip to content

Commit dfa66dd

Browse files
committed
docs(IFU): v3 ifu
1 parent ecb9367 commit dfa66dd

18 files changed

+177
-217
lines changed

docs/zh/frontend/IFU/.index.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,11 @@
22

33
``` {.include}
44
index.md
5-
PreDecoder.md
5+
ifuTrigger.md
6+
instrBoundary.md
7+
instrCompact.md
8+
ifuUncacheUnit.md
9+
preDecoder.md
10+
predChecker.md
11+
ifuAlign.md
612
```

docs/zh/frontend/IFU/PreDecoder.md

Lines changed: 0 additions & 84 deletions
This file was deleted.

docs/zh/frontend/IFU/ifuAlign.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
## ifu的权衡与配合
2+
简单说明一下IBuffer的入队原理,IBuffer是先进先出的队列。enqPtr代表当前的IBuffer可入队第一项entry位置,enqPtr + 1代表当前的IBuffer可入队第二项的entry位置。如果IFU提供给IBuffer的是稀疏的有效指令,则IBuffer第一项可入队的entry需要从IFU提供的稀疏有效指令中选出第一项有效指令。则IBuffer第二项可入队的entry需要从IFU提供的稀疏指令中选出第二项有效指令。极端的由于IFU最多提供32条指令,IBuffer的每一项都会面临32选1的尴尬境地。
3+
4+
那么IFU和IBuffer能否相互配合做出一种特殊的约定呢?实际上是可以的,IBuffer实现写分bank策略,给IBuffer队列每一项进行编号,获得ibuffer_mod_id = IBuffer编号%4。IFU提供的入口指令也进行编号,获得对应的ifu_mod_id = IFU编号%4。IBuffer的entry只从对应的IBuffer_mod_id === ifu_mod_id项中进行选择。真是美妙的想法,从32选1变成了8选1。这对吗?理论上是否可行?代价是什么?
5+
6+
理论上还需要进一步的推敲。从连续性角度角度讲,如果IBuffer的当前entry为ibuffer_mod_id = 3的项入队了,则IBuffer的下一项entry的ibuffer_mod_id = 0。如果你不打乱顺序的话,则要求IFU送入的有效指令是连续的,稀疏的指令排布会打破对应的默契。图形是最为直观的,我将为你画出第一点要求。OK,现在我们知道了要求一:IFU的输出指令要求的是有效指令连续。图形是最为直观的,我将为你画出第二点要求。
7+
8+
![有效指令紧密排布与稀疏排布对比](../figure/IFU/instr-align.svg)
9+
![有效指令紧密对齐排布与紧密非对齐排布对比](../figure/IFU/instr-align1.svg)
10+
11+
代价:有效指令的排布,要求筛选出紧密排布的有效指令索引,IFU引入了相关的计算逻辑。权衡的艺术:相对于送入IBuffer时的每条指令携带的数据信息进行刷选,IFU计算指令索引需要的逻辑会少一点点。IFU将有效指令进行了紧密排列,意味着虽然有32个指令信息存储位置,但我们可以进行较为精细的时钟门控操作。偏移计算,这要求提前掌控IBuffer的入队指针,实际上偏移计算本身会带来一定的计算量。不过相对好些的是需要进行偏移计算的数据量较少。~~~ 哦我又发现了华点,也许偏移计算的大头可以直接砍掉了,但与功能没有关系。
12+
13+
前文已经讨论过了有效指令筛选机制,现在我们讨论一下IFU有效指令的对齐,我们需要将第一条指令偏移到,当前IBuffer入队指针enqPtr % 4对应的位置。所以最大偏移量是3,进行有效指令对齐的最大问题就是提前获取enqPtr的值。实际上我们能够做到这一点。enqPtr值实际上就是有效指令数量的不停累加。遇到后端重定向时,enqPtr的值复位为0。IFU能够确定送入IBuffer的有效指令数量,同时也会接收来自后端的重定向,因此我们可以提前计算prevIBufferEnqPtr,如下图所示:
14+
![提前计算入队指针](../figure/IFU/prevIBufferEnqPtr.svg)

docs/zh/frontend/IFU/ifuTrigger.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# 子模块 Trigger
2+
3+
## 功能描述
4+
Trigger的实现在后端,因为Trigger的一个子特性要求是执行前,需要前端IFU的配合。因此从IFU的角度描述一下对Trigger的理解:
5+
6+
触发器不在调试模式下工作,调试模式可以建立一系列的触发器。当同时分别触发进入调试模式和断点异常时,优先保证进入调试模式的发生。推荐是进入调试模式和生成断点异常,都要发生。触发器可以用于本地调试,即不依赖外部调试器(JTAG),而是通过异常机制来进行调试。触发器通常由用户态或监督态设置,但也支持机器态进行设置(M模式下,开发人员必须清晰的知道自己在干什么)。
7+
8+
触发寄存器仅在机器模式和调试模式下可设置。IFU中的trigger逻辑是为了配合后端实现的Trigger模块,目前来看只涉及到了送往IBuffer的PC对比。有关预译码和指令数据使用目前在IFU中的Trigger还没有支持。目前IFU的Trigger中有4个tdata寄存器,值由后端设置。遍历送入IBuffer的所有PC,根据matchType的匹配规则,进行匹配。在匹配的情况下,还需要判断是tdata.select是否为地址匹配目标,以及是否处于非debug模式,才能确定命中。即使是命中情况下,也还需要根据tdata.timing和tdata.chain以及tdata.action做出综合判断。(分别是触发的时机要求,触发的链式匹配要求,以及触发的动作)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# IFU 子模块 ifuUncacheUnit
2+
3+
## 功能描述
4+
5+
### 功能描述
6+
uncache模块主要负责从uncache总线提取指令,同时负责判断阻止MMIO指令的推测执行。受PBMT属性的影响,部分非缓存的指令数据是允许推测执行的,因此需要对MMIO指令进行特殊区分。需要强调一点的是,uncache的指令数据来自于s3级,因此任何在S1、S2级依赖指令数据计算出来的结果,都值得重新审视。
7+
8+
uncache本身不处理跨页的情况下,当遇到uncache指令跨页时将分为两个预测块进行处理。这与cache指令跨页的处理情况有些类似。uncache需要什么?uncache需要物理地址,用于向uncache总线发出取指请求。uncache需要ftqIdx,以便向FTQ请求查询预测块的提交状态用于处理MMIO的阻塞逻辑。uncache还需要pmp的结果和PBMT的结果,用于确认当前的uncache请求是否是需要进行推测阻塞的MMIO请求。需要注意的是对于处理器执行的第一条指令,其不存在更旧的指令,我们将越过阻塞机制直接向uncache总线发出取指请求。
9+
10+
需要注意的是对于uncache总线,它每次总是返回64字节对齐的数据,这意味着如果指令跨越了64字节的边界,将会发送两次请求,这个由前端的uncache通路完成,IFU对此无感。区别在于,当指令跨页时,理论上可能存在两个页的物理地址不连续,前端的uncache通路,将无力进行发送两次请求,它会返回crossPage的状态标志,这需要IFU做额外的拼接处理。
11+
12+
### uncache指令的处理流程
13+
- 第一步:uncache状态机接收来自IFU的uncache请求,判断是否为非MMIO。如果是非MMIO直接向uncache通路发送请求并转第三步,否则等待MMIO指令成为最旧指令并转第二步。
14+
- 第二步:如果MMIO指令是处理器执行的第一条指令或者MMIO指令是最旧指令,则转第三步,否则持续在第二步进行等待。
15+
- 第三步:如果uncache通道接收了请求,则转第四步,否则继续在第三步等待。
16+
- 第四步:如果接收到uncache通道的返回数据,uncache子模块将会把数据回传到IFU的主体,转IFU主体进行处理。否则继续在第四步中进行等待。
17+
- 无条件冲刷:uncache子模块接收到Flush信号后,不管处于第几步都将复位所有的控制寄存器。不考虑uncache通道是否处理完毕,因为uncache通道也会接收到Flush信号。
18+
19+
### ifu接收uncache子模块信息处理
20+
IFU主体在接收到uncache子模块的信息后,将会根据是否跨页分为两种情况处理:
21+
- 跨页情况下:1. 如果预测器给出的结果是顺序取指,IFU主体将暂存这半截的指令数据信息,等待下一个预测块继续走完uncache子模块流程。拼接两个预测块的指令数据。2.如果预测器给出的结果是跳转,IFU同样将暂存这半截的指令数据信息,但是会直接发送重定向,从而达到从正确的下一个预测块获得的另外半截数据。
22+
- 非跨页情况下:一条指令在一个预测块中取完。
23+
- 目前IFU在完成一条uncache的取指后,不管预测器是否给出顺序执行都会发送重定向要求顺序执行。如果对uncache取指有有速度的需求,这是可能的后续优化点。
24+
25+
### 整体框图
26+
![uncache结构](../figure/IFU/uncache_fsm.svg)

0 commit comments

Comments
 (0)