首先建议设计文档里有一份顶层架构图,能够反映流水线运作原理,尤其是各级之间的转发。而画这个图的过程,本身也是对代码的数据通路 debug 的过程。
课上指令通常为三类:计算类、跳转类、访存类。
# 一、计算类
通常是 R 型指令, GPR[rs] 与 GPR[rt] 运算,结果存入寄存器 rd 中。
一般只需要修改 ALU 即可,复杂的运算可在顺序块 always @ (*) 中实现,注意循环时计数变量要初始化
# 二、跳转类
情况多种,主要体现在以下三个方面:
有 / 无 条件 跳转
在 CMP 模块中处理好 isBranch 信号即可
有 / 无 条件 链接
- 无条件链接 :通常是链接
PC+8到$ra。容易实现,与写寄存器相关的信号同 jal 指令即可。 - 有条件链接 :即条件不成立时,不链接。存在两种解决方案:
- 在 D 级引入新的写寄存器信号
RFWr_new,根据 CMP 模块的条件返回值对其赋值,然后将其流水至 W 级,代替原有的写寄存器信号。要注意当指令不是此指令时,RFWr_new信号应等于原来的RFWr信号。个人认为这种方法较为麻烦,不建议采用。 - 注意到,当被写的寄存器为
$zero时,将不会执行写入操作。于是,可以改变被写寄存器的控制信号,使写入的寄存器为$zero
- 在 D 级引入新的写寄存器信号
- 无条件链接 :通常是链接
条件不成立时,是 / 否 清空延迟槽
清空延迟槽,即废除延迟槽指令,不再执行,等价于将延迟槽指令替换成
nop。课下的 beq 指令是不清空的,而需要清空时,我们将 F_to_D 流水线寄存器清零即可(注意这和阻塞的区别)。这需要一个从 CMP 发往 F_to_D 的控制信号
D_clr。注意其置 1 条件 :(指令为此跳转指令) && (跳转条件不成立) && (此时非阻塞) 。一定要注意,阻塞时是不可清零的,因为此时还未获取最新的
GPR[rs]和GPR[rt],跳转条件成立与否未知。
本次课上 Q2 的指令 JTL ,属于条件跳转、无条件链接、清空延迟槽
| jtl<br>100110 | rs | rt | offset |
|---|---|---|---|
| 6 | 5 | 5 | 16 |
GTL 语言大致如下:
I:
temp1 ← GPR[rs]+GPR[rt]
temp2 ← PC+4+sign_ext(offset||0^2)
GPR[31] ← PC+8
II:
if(temp2<temp1):
PC ← temp2
else
PC ← temp1
NullifyCurrentInstruction()
注: 1.NullifyCurrentInstruction() 的意思是清空延迟槽
2.相加不考虑溢出
3.比较为无符号比较
笔者在实现时,在 CMP 模块中增加了 [31:0]jump ,专门用来计算 JTL 指令的跳转地址,并接到 NPC 模块上。同时将控制信号 NPCOp 拓展了一位,但是笔者最开始粗心忘记了在 NPC 模块也将其接口拓宽一位,导致 WA 了一会。
# 三、访存类
通常为条件访存, lw 的变式指令。需要改动的点主要是以下两个方面:
条件:
课下的
lw指令计算出基地址后无条件写寄存器,而课上指令一般会加以条件。条件可能会用到rt甚至别的寄存器。如果只是用到
rt,那么我们只添加一个该条件的组合逻辑即可,因为课下已经实现了此处rt的转发;如果是别的寄存器,譬如
$ra,那么需要在 GRF 模块增加一个raData的输出端口,并将其流水至 M 级,同时增加与它相关的暂停、转发逻辑。访存:
通常是根据条件,将数据写入指定寄存器。而这个指定寄存器大概率不再是
lw的rt寄存器。此时也需要改变数据通路,实现方式比较容易,只需在 M 级更新被写寄存器的编号,即增加
A3M_new的组合逻辑,然后令其替代原本的A3M即可。下面将以本次的课上题目为例进行说明。
本次课上 Q3 的指令 LWOC
| lwoc<br>111110 | base | rt | offset |
|---|---|---|---|
| 6 | 5 | 5 | 16 |
其 RTL 语言大致如下
I:
Addr ← GPR[base] + sign_ext(offset)
word ← Memory[Addr]
Re ← word3..0
condition ← (word<0x80000000)
II:
if(condition):
GPR[Re] ← word
else :
GPR[rt] ← word
本指令比较简单,无条件取字,仅需修改被写入的寄存器
首先我们在 M 级增加 A3M_new 的组合逻辑。(这里 DM_resultM 在有些指令时可能是不定值,但此时 InstrOpM 一定不是 LWOC ,故不会影响条件判断)
<img src="https://cdn.jsdelivr.net/gh/BUAA-Yzx2023/ImageBed/202411151022967.png" style="zoom:80%;" />
然后将 暴力转发、暂停判断、MW 流水线寄存器里所有的 A3M 替换成 A3M_new 即可