lab3中的中断跳转与清空 #15
Replies: 3 comments 5 replies
-
同学你好,Lab3 是我设计的。其实在流水线中加入中断是一件挺麻烦的事,我在写代码时也在中断这块遇到了比较多的问题,加上中断是 Lab2 的主题,所以我在 Lab3 的实验设计中就刻意避开了中断这个话题,但是在心里又怕同学们做这种填空式的题目时只见树木,不见森林。所以我非常高兴你能够对基础作业要求以外的部分产生兴趣并进行探索。 有兴趣的话,你还可以看一下 YatCPU 原始的代码 和 文档。最初的三级流水线 YatCPU 是由 @howardlau1999 学长实现的,我在他的基础上又实现了五级流水线。再后来,我与另外两位同学分别修改 YatCPU 的代码,设计了这几个实验。(在主仓库的五级流水线 YatCPU 中,因为 IF 段通过总线取指需要多个周期,掩盖了阻塞和旁路中的几个 bug,后来我在写 Lab3 的代码时发现并改过来了,但是主仓库中的代码还没有修正,我应该会在寒假把这个坑填上……) 我一开始读三级流水线 YatCPU 的代码就觉得有些地方实现得比较繁琐,所以在我写代码的时候一直秉持着“放宽约束,简化逻辑的原则”,希望可以简化底层逻辑,节省硬件资源,减小组合逻辑延迟,同时也让代码更简洁。当然,这样也可能更容易出现 bug,在未来拓展其他指令的时候也可能会带来麻烦。但我还是把这个原则带到了 Lab3 的设计中:原来的 CLINT 是一个状态机,在处理中断时需要多个周期,对 CSR 逐个写入,我和其他设计实验的同学进一步把它简化为在 1 个周期内同时写入所有需要写入的 CSR。这样,中断对流水线的影响可以用一句话概括:中断发生时,相当于在处理跳转/分支的流水段上叠加了一条跳转指令。不知道这是否有解决你的第一个疑惑?下面我会做详细解释。 下面进入正题。
其实我已经有几个月没有接触 YatCPU 了,所以我的理解可能也不一定准确。如果还有任何问题,欢迎继续讨论~ |
Beta Was this translation helpful? Give feedback.
-
谢谢学长,我知道我final的疑惑出于哪里了——我对清空流水线寄存器的效果没有理解到位。在final里,指令跳转与中断跳转的效果是一样的,即在ID段发出一条跳转指令。我们在此时应该清空if2id,是清空原来的IF段的结果,是不会影响当前ID段的指令的。(效果则是IF段下一周期是跳转目标指令,ID段下一周期是气泡,EX段下一周期是原来的ID段指令) forwarding的问题在于我忘记了中断处理会保护现场,罪过罪过……不过jumping在实际效果上,它服务于的instruction_address也使用了jump_flag来Mux,使得jumping中的jump_flag没有效果,但是我理解jumping中的jump_flag的逻辑意义 |
Beta Was this translation helpful? Give feedback.
-
我在写实验报告Final的Control时,又遇到了一个问题 |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
我发现lab3的标准测试对于中断发生时,应该怎么清空流水线寄存器,管得很松,不过都很有意思。
Final实验。情景:当CLINT要执行中断跳转(mepc会保存当前PC的值),且此时CPU上没有跳转/分支指令,没有数据冒险,没有Load指令。
也就是说,IF模块的指令被替换成了中断处理程序的第一条指令,而与此同时ID/EX/MEM/WB模块的指令则需要照常执行,对不对?
也就是说,中断跳转根本不需要清空任何流水线寄存器对不对?
而由CPU中跳转/分支指令产生的跳转,需要清空一些流水线寄存器,因跳转清空时需要判断是哪种跳转对不对?
但是判不判定都能过欸……
然后是forwarding实验。贴上我实验报告的一部分:
(定义“依赖”为
rs_id === rd_ex
)现分析在同时满足阻塞和清空的条件的情况下,Control单元应该采取的行为:
if_jump_flag
信号为真,即(CLINT跳转信号 或 EX模块为跳转指令 或 EX模块为分支指令且分支判断)为真。因此两者同时发生时只有一种可能——即此时EX模块为Load指令,ID模块的指令依赖Load指令,CLINT发出跳转信号。(“依赖”定义为

rs_id === rd_ex
)那么这种情况Control单元究竟该阻塞,还是清空,还是同时阻塞清空呢?(虽然测试都能过,不过我在CLINT的代码中发现,助教大神已经考虑到了这个问题。)见源码图:
这种情况下,中断处理结束后将返回到此时的依赖指令,也就是说,此时Control单元应该将依赖指令清空且不阻塞。
不过我还是不明白为什么CLINT此时要保存ID的指令,明明ID的指令依赖于EX指令,在两者中间执行中断处理程序可能会导致ID指令的RegData错误吧?望指教。
Beta Was this translation helpful? Give feedback.
All reactions