本文已收录到:MIPS架构CPU设计 专题
本节位于书中P174页,如果没有纸质书可参考自己动手写CPU之第七阶段(5)——流水线暂停机制的设计与实现
[title]为什么要引入流水线暂停机制[/title]
在第七章开始,我们陆续实现了下列指令:
- add addi addiu addu sub subu指令——加法减法指令
- slt\sltu\slti\sltiu指令——比较指令
- clo\clz 指令——计数指令
- mul、mult、multu 指令——乘法指令
在第七章第二部分我们讲实现比较复杂的算数指令,主要是累乘加减和除法指令。这两种指令我们分别来看:
累乘加、累乘减指令:需要两个部分才能实现,分别是乘法运算和加法运算,所以我们需要两个时钟周期才能实现。
除法指令:在本章中我们采用试商法处理除法问题(关于试商法会在下面的文章讲述)。而试商法需要至少32个时钟周期才能实现。
如果我们在执行累乘加减指令和除法指令的时候占用很多时钟周期,不去暂停后续的指令就会出现覆盖问题。所以我们要引入时钟暂停机制。
在本处理器中,只有译码、执行阶段可能会有暂停请求,取指、访存阶段都没有暂停请求。
[title]暂停流水线的方法[/title]
要暂停流水线,只需保持取指令地址PC的值不变,同时保持流水线各个阶段的寄存器(也就是IF/ID、ID/EX、EX/MEM、MEM/WB模块的输出)不变。
增加新的 ctrl.v 模块
[title]流水线暂停机制实现[/title]
在我们这次实现的处理器中采用一种特殊的手法:
- 需要在译码阶段占用多个时钟周期的指令:暂无,在执行完一个周期后,保持取指令地址PC值不变,另外保持取值、译码阶段的寄存器不变(暂停),而执行、访存、回写指令继续执行。
- 累乘加减指令在执行阶段需要两个时钟周期,在执行完第一个周期后,我们保持取指令地址PC的值不变,另外保持取值、译码、执行阶段的寄存器不变(暂停),而访存、回写指令继续执行。
如下图所示:
视频讲解
[title]修改顶层模块 openmips.v[/title]
这里我与原作者的实现方式不同,我认为后面的访存和回写阶段既然无论是单周期还是多周期都不会被暂停,那么根本就不需要被ctrl模块控制,也就无需连接,只按照下图连接即可:
视频讲解
更正/修改:在 后续 章节中,madd的实现遇到了问题,经检查是流水线暂停机制的实现有错误。请参考 链接 :
[title]本节代码[/title]
请自行在github上下载并回溯到本节:https://github.com/gzhy5111/cpu
参考文献:https://blog.csdn.net/leishangwen/article/details/38856217