P7-CPU设计文档
本文最后更新于 2024年12月3日 中午
P7 debug总结
阻塞转发错误
上机的过程中遇到了转发错误,再三排查后,发现是mtc0
产生了不应该有的转发.
在ID的控制模块CTRL
中,我采用了一种过于"取巧"的方法,将rd写入了ID_A3(解码阶段输出的写入寄存器地址(向后传递直至WB阶段))
1 |
|
这个ID_A3
会随着流水线向后传递,并传递给HAZARD_CTRL
(冒险控制模块)中用于处理阻塞和转发的问题.例如:
1 |
|
那么问题来了,我的阻塞逻辑代码中,
1 |
|
这样看似没有问题.但其实这里mtc0
指令导入的A3
并不是真正用于写入寄存器堆的地址,而是CP0
的对应地址.因此有可能产生本不应该有的转发.例如以下代码
1 |
|
该代码中,第二行指令mtc0
错误地向add
指令转发了$12
的值,但它们指向的$12
根本不是同一个寄存器!
我的对应措施是取消执行mtc0
指令时rd
写入ID_A3
的做法,在HARZARD_CTRL
中,传入MEM_instr
和EX_instr
(MEM
,EX
区当前各自传递的指令)
1 |
|
中断错误
错误情况:
1 |
|
这个bug在课上并没有发现,喜提计组"再来一次"大奖
首先说错误点:
**在发生阻塞时,ID
和EX
间的流水寄存器接收到冲洗信号,但应当保留PC
和BD
(branch
delay)*两种信息的传递,也就是按正常传递的逻辑传递PC
和BD
**
前者PC
比较好理解,课下思考题也有问到这个问题.为了保证macroscopic_pc
不出现诸如0x0000_0000
这类的值.
但是BD
稍微有些理解的困难度.当外部中断信号产生时,CP0
会根据接受到BD
来决定EPC
存储的值,如果BD
有误,那么PC
跳转错误就很有可能发生,
1 |
|
我验证了多种ID,EX间流水寄存器处理阻塞的错误方法,例如
1 |
|
1 |
|
1 |
|
我们来看官方tb
中的中断逻辑处理代码:
1 |
|
用文字简述该逻辑:当macroscopic_pc
到达tb
指定的target_pc
时,interupt
置为1,即外部产生中断信号.
所以我们可以很容易的排除C:
当延迟槽指令位于ID区时,与流水线后面的指令发生阻塞冲突时(这种例子确实不太好列举):
1
2
3
4
5
6
7
8
9ori $20, 0x1001 # 3000
mtc0 $20, $12 // 允许中断 # 3004
ori $1, $0, 0x1234 # 3008
ori $2, $0, 0x2345 # 300c
mult $1, $2 # 3010
jal 0x3020 # 3014
mflo $3 # 3018(发生中断)
ori $5, $0, 0x5555 # 301c
ori $6, $0, 0x6666 # 3020
我们指定target_pc
为0x3018
,mflo
会与EX
区的MDU
模块产生的busy
信号发生冲突,因此在C情况下,ID
和EX
间的流水寄存器产生了nop
指令,该指令携带着0x3018
的PC
和0
的BD
,传递到MEM区时,PC
传递给macroscopic_pc
输出到外界,触发了外界中断信号的产生,CP0
接受到该中断信号进入中断处理逻辑,这时该模块依据接受到的BD
处理EPC
,但是BD
是错误的,也就最终导致了跳转错误.
至于A和B,上述代码确实无法证明它的错误,我猜测是课上测试tb
会有更复杂的中断信号产生的逻辑,总之,EX_PC <= ID_PC;EX_BD <= ID_BD;
确实是最好的,因为它保证了两点:
- 发生阻塞的指令对应
PC
会多次出现在macroscopic_pc
中(A,B无法做到这一点) - 指令传递中,
PC
一定与正确的BD
对应