北航计组-P6课上
通过阅读本文,你可以大致了解BUAA 2024秋季 P6课上测试的相关内容
题目每年都会发生变化,题面仅靠回忆,题意描述可能与原题有一定差异
前言
这次P6挂辽😭
T1卡了老半天才A掉,确实不难,但是细节和小坑点比较多,自己一上来还是太心急了,没有把握好细节。
晃了一眼T2,是访存,按照经验,比较难受,果断切T3,可惜的是,“经验主义”并不总是对的,这次T2很容易,卡时间周期的反而是T3 的跳转,而我最后也就输在了最后一个点的TLE的上
2024.12.02 Updated
这次T3极其抽象,最后刚做完,就交不了了,本地还没来得及测试,估计还得调一会儿😇
顺便吐槽下今天的机房电脑屏幕是19寸的,14,40*900,跟平常比起来,小太多了,不过其实也没啥😀
T1 mpm
题面
mpm rd, rs, rt
1 |
|
其实就是求最小的大于tmp1的2的幂
忽略加法过程中的溢出
思路
直接对着翻译差不多,不过几个细节需要注意
- tmp2 应该至少为33位,因为tmp1 可能为0xffff_ffff,这样需要0x1_0000_0000才能大于tmp1,这一点从循环 i in 32……0也可以看出
- RTL语言中是从32遍历到0,而我们可能习惯的是0到32,这样的话无法求出“最小的”,因为当满足条件时,你缺少了一个break
毫无疑问,两个坑我都踩了,并且第一个坑我开始还把tmp1也改成33位的了,这样导致忽略溢出这一操作无法实现,并且我最后才发现这个问题😭
至于第二个问题,也好办,如果你是32到0 的遍历,那没有任何问题,如果你是0到32 的遍历,需要在满足条件时直接把 i 赋值为32即可,因为verilog中没有break语句
T1(2)
题面
就是将GRF(rs) 循环右移32次的结果相加,将GRF(rt) 循环右移32次的结果相加,两者比较,前者小于后者就赋值rd 为-1, 大于的话就赋值1,相等赋值0
思路
RTL语言是说
1 |
|
注意,位宽的中括号两边不能有变量,因此无法直接翻译RTL语言
解法如下,最后比较tmp3和4就好
1 |
|
T2
题面
没有详细的RTL语言,我就描述一下吧
跟正常的sw差不多,但是 high_1 = GRF(rt)中最高位1 的位置,addr = base + offset + high_1 || 00,
最后Mem[addr[31:2] || 00] = GRF(rt),大致是这样
思路
感觉实现起来不难,DM加一个输入信号即可,可悲的是我并没有做这道题
T3
题面
似乎是叫mpl,不管了
大致是说
tmp = GRF(rs) + GRF(rt)
如果rs == rt,就跟beq一样跳转,否则如果rs rt奇偶性相同,就跳转到 tmp[31:2] || 00,如果都不满足就不跳
无论是否跳转都要链接
注意比较的是rs rt 本身这个编号,而不是寄存器的值
思路
整体上搭建起来也不算太难,CMP, NPC新增端口, 加一点逻辑,不需要改基本上就可以实现
但是,你交上去,会发现你过了9个点,剩下的那个点会告诉你,你TLE了
课下我基本已经全速了,只缺一个lui可以E到D的转发,懒得加了,后来证明,加这个还是会被卡
所以,也就是说,如果只将新指令的Tuse设为0,并且不对阻塞单元加点逻辑,那么一定会被卡 😇助教坏坏
具体怎么办呢?我们发现并不是所有情况下这条新指令都需要使用寄存器,当且仅当 rs != rt && rs[0] == rt[0]的情况下才需要使用寄存器,那么我们就需要在阻塞单元加一个特判,举一个例子
1 |
|
总结
- 决策失误了,默认T2访存恶心,结果反倒简单,还是建议大家把3道题都读一读,思考一下,再做决策吧,不要像某人一样😇
- T1太过着急,细节没把握好,浪费大量时间
- T3属实没想到这么卡时间,因为之前都是访存类W级才确定写寄存器和写数据,所以无脑阻塞2周期卡时间,这次属实没想到这么卡,有点阴间了