P6-流水线CPU-2¶
很好的博客 d=====( ̄▽ ̄*)b
- P6 课下 & 课上总结 - 北航计算机组成原理 | Test Blog = FlyingLandlord's Blog
- 「BUAA-CO」P6_流水线cpu(Plus) | Hyggge's Blog
- Computer-Organization-BUAA-2020/8-P6/P6课下解析.md at main · rfhits/Computer-Organization-BUAA-2020
- [BUAA-CO-Lab] P6 流水线 CPU-lite2
- P5 && P6-流水线CPU(verilog实现)(已更新)- BUAA-Wander - 博客园
- 【BUAA_CO_LAB】p5&p6碎碎念_buaa p5-CSDN博客
日志¶
Day 1¶
很优雅的半字节代码:
把官方 testbench 调换了顺序:
以便按照指令执行顺序输出,还修改了 Flying 的
Day 2¶
周二晚上一直在想乘除槽和乘除指令的阻塞问题,周三上午清醒的时候,正式动工接线
晚上正式 AC
找了一些自动化评测的工具:
- 学长的 Open Mars Here 小工具
Day 3¶
To Do:
- 走查整个 project,检查逻辑问题,完成设计文档
- 学自动化运行
真的看出了一个 bug,先前把 D_rs != 0
漏掉了
根据 warning 又找到一个潜在的 bug,线的位宽不一致
感觉 P6 好难构造数据,乘除槽很容易就除 0 了
Day N¶
madd
将两个数有符号相乘,计算结果与之前的 HI, LO 寄存器中的值相加:
错误1: 位拼接 {HI, LO}
默认被当做无符号数,无符号性传递到 $signed(A) * $signed(B)
,因此即使使用了 $signed()
还是会被当成无符号数进行乘法运算
错误2: 虽然使用了 $signed()
屏蔽了外界符号性的传入,但是也屏蔽了位宽信息的传入,所以 $signed($signed(A) * $signed(B))
的结果实际上是32位(因为 $signed(A)
和 $signed(B)
都是32位,又没有外界位宽信息的传入,因此结果被强制规定为32位),即高32位的数据被截去
所以需要把 64 位的信息传进乘法里:
这周的后面真的是过得很 awful 了,无所事事的,测试代码也感觉很难编,就到处翻翻找找的。还迷恋上了电子榨菜,熬夜刷手机……希望能改掉这个坏毛病,feeling ugly can make us more productive
遇到的 bug¶
busy 信号的设置¶
现 mult
位于 D 级, mflo
位于 F 级
下一个时钟上跳沿来临时: mult
进入 E 级,HILO 感受到的是前一个瞬间——E 级并非 mult
,所以 busy
保持 0,并未阻塞 D 级!
再下一个时钟上跳沿: HILO 感知刚刚是乘除法,根据条件 busy
置 1 ,后无指令了,出现高阻。总之达不到阻止 mflo
的效果
!!!
always @(posedge clk)
用的是前一个瞬间的组合逻辑的值,兜兜转转一个学期,终于也理解了
课上总结¶
T1 fmultu¶
fmultu rs rt
无符号乘法,计算占用3个周期
RTL:
highest_one_pos(prob)
函数返回 prob中 1 的最高位置的下标
思路: 改 CTRL 和 HILO 模块,全用了阻塞赋值
更好的方法:
bug:
- CTRL 里忘记加 MDOp = `MD_fmultu
- i < 63 ? I < 64!
T2 bnumeq¶
bnumeq rs, rt, offset
GPR[rs] 和 GPR[rt] 的 1 的个数相同时,跳转 (和 b 类指令的跳转一致)
思路: 归类到 b 类,修改 CMP 就好
T3 lwcm¶
名字可能记错了
lwcm rt, offset(base)
M 级增加寄存器 WD。按 lw 的方式从 memory 中读出 mem_read_m
,如果和 WD 内的值等,则写入 rt,否则 26 号。并且把这个新读到的值存入 WD。
思路: 加模块,改 SU / CTRL / M_BE…