说在前面
- 本系列从P6上机结束开始制作,因此靠前的一些P可能记不清楚
- 本系列主观色彩较强,不过尚有一定准确信息
- 作者在P6献出首挂,并玉玉了一周(?)
接下来,就以我的吐槽为主了
Pre上机
考三道题,分别为logisim,verilog,MIPS
原120min延时到180min
logisim考查:
-
同步复位
:不能使用clk和reset的与(clk在上升沿与clk == 1是两个概念!)正确的方法:1. 用reset,MUX控制输入数据,再把修正后的数据传给寄存器
2. 不使用MUX,而是将reset取反(再位拓展)后与Data与
起来(reset==1时,结果为0&Data=0),这样来控制输入数据
实质上两种方法都是保证给要写入寄存器的值做一个实时修正
保证只有上升沿那一瞬间,才能决定是否进行复位 -
状态机
: 已经很久远了,个人认为把斐波那契这种高阶的弄会就好加入An传进寄存器1,再传进寄存器2,再传进寄存器3,
那么当寄存器3为An时,寄存器2即为A(n+1),寄存器1为A(n+2)
这就是logisim里暂时保留数据若干个时钟周期的途径
verilog和MIPS考得都很水
建议一定要学好verilog的组合逻辑循环怎么写
或者你能够熟练地打表
让你求32位的和,你就用C写出来一个a[0]+a[1]+…倒也未尝不可
|
|
P0上机
三道题,logisim练习
原120min延时到180min
是谁国庆前一晚还在上机啊
但是贴心的助教们出了一次极水极水的题!
考察内容:善于封装子模块、Mealy(米利)机和Moore(摩尔)机的判别
大家都是一路AC
我WA了一次,比较器
要设置成Unsigned!!!
P1上机
三道题,verilog练习
原120min延时到180min
一般是一个简单的组合逻辑加两个状态机
本来以为没有延时,差点以为要挂了,所以第二题做出来就开始摆了
错因没有什么价值,纯粹打错符号了
第三题是一个很复杂的状态机
难度堪比cpu_checker(笑)
最后搭出来WA了几个点,也没弄明白WA在哪
P2上机
三道题,MIPS练习
原120min延时到180min
T1 未给出C代码
题面如下:
已知b,m,n,在[m,n]中找出一个整数a,使得a%b最小,输出a%b
看起来还唬唬人,但是真从m循环到n不动一点脑子肯定是会TLE的
这东西他让你输出的是余数,那可就太简单了
要么是0,要么是m%b
如果是0,说明m到n存在b的倍数,那么n/b就不等于m/b
所以其实就是考察div,mfhi,mflo的使用
伪代码如下
|
|
有没有\n我忘了()
T2考循环T3考递归
都有C语言代码,静静翻译就好,一般不会有bug
如果有,着重检查你的bgt,blt,beq,bne等等是否写反
递归就着重两个字“保护”
保护的时间是jal前和jal后(物理意义,不是代码执行顺序)
jal前表示进入递归之前做好现场保护
jal后则是退出上一层递归回到jal的PC+4的位置,恢复当时现场
P3上机
终于来到我们的CPU阶段!
以及闯关制的开始。
最后一次使用logisim
自此开始,课上是否通过基本等价于课下搭的CPU是否有误
三道题,新指令添加
原120min延时到150min(这个不同届不一样)
本次没有明显感受,难度不太高
课下的记忆点更充实些
P4上机
三道题,新指令添加
120min 无延时。
题目也不难,和T3难度相当
作者没能AK。
因为有课下bug!!!!!
但是这个bug太小了。
jr $rs
而非jr$31
玉玉随笔:
历经了轮轮评测,
也从未想过要在课上debug。
但我看到了完全与题意无关的报错信息,
我意识到了课下着实存在着的bug,
我惊惶,但又或是接受,接受我真的会在P4倒下,会在这条闯关路上走得一坨烂泥。
在课上最终de出了bug,确是万幸。
只是那瞬间,无休止的荒诞涌进一触即破的思绪,
畏惧后怕质疑庆幸猛地迸发开来,
只留呆滞的躯体挪动着不太灵光的鼠标,
看着界面的圆圈转着转着,拉着我去和P4说再见了。
P5上机
120min 无延时。
课上过一题 = 课下没问题 = P5必通过!
前两题顺风顺水
第三题做的悠哉悠哉不知不觉只剩10min
交了一发 10个点过9个 挂了个TLE
意识到这题卡时间
阻塞条件再细化 但是始终没有落实到寄存器冲突上
再交还是TLE
只剩下2min了
那 就交卷吧
越是静下来,越是容易意识到问题关键
为什么当时不把那17个寄存器都排除呢?
阻塞条件一定要细化!!
只是担心于它的不确定性,怎么不去研究他的变化范围。
2min很漫长。等了很久,等考试结束,
等未通过的同学都离开考场,
等问答环节来临,
我问助教究竟要优化到什么等级:
答案显然。
对于一定不被写的15个寄存器,不会有转发当然不必阻塞。
P6上机 —— 1
史上最惊为天人的一集
真的有人课下没bug课上还能全挂?!!
T1时序逻辑掺组合逻辑
在乘除模块里求最高位1最低位0结果一直输出xxxx
结果是因为没初始化
一de就是80min
T2更是荒谬
32位累加没有设置位宽
这么简单的问题在当时混乱的大脑下藏了40min
后续又做了一堆无用功,漫无目的地构造测试数据,感动自己地打表等等。。
最终以0题通过幸终。
P6上机 —— 2
时隔一个月的90min AK
怀揣着极度的不安与不满,
因为我真的不能保证我的课下确无问题。
就这样
踏入了大家都在P7gap的空旷的考场
T1已经退化成add类指令了。。
只是写入的值换成add结果的最高位1
最高位1
?这我可太熟了(苦笑
这不上周给我绊死的那位嘛
这周周中好好地跟他清算了一波
没想到还能见面,那就再也不见了
T2一看条件存储,我先跳了
T3经典跳转类
完成基础功能TLE
最后一个点
乘除模块偷跑
却又超速
一个点
意识到不能暗改乘除
但是我也不知道怎么做
此时我智慧的大脑居然认为测试点出错了
肯定有死循环
不然我有的点过快了这个点还能过慢?
然后去做P2了
大致扫一眼:什么条件跳转。。原来是标题欺诈。
再定睛一看:啊?又是最高位1
?
只是把DM写的地址
加上了一个与最高位1
有关的数
最麻烦的事大抵也就是DMWr的位扩展
但是还好我提前改成三位了
T2过关,我开始回去看T3
诶诶
这个T3一个点TLE
这不就是我的P5吗??
我P5的反思居然还派上用场了
我开始去思考我的阻塞……
用不到,不需转发就不阻塞!!
又写了四行优化阻塞逻辑
交了一发终于AC。
最后,还是喷一下上周。
课下无bug课上全挂真是神人了。
另外,如果感觉自己课下没bug还课上全挂的别担心
你的课下可能确无bug
考场上的蠢度永远是自己无法想象的。
P7上机 —— 1
紧接上文,考场外的蠢度你也无法想象。
四道强测:
功能强测
异常强测
中断强测
冒险强测
一道附加指令:Withdraw
120min
刚开始交前四题,全挂。
我有点崩溃,但是看到大家也是一片红,我深深感觉到强测之强。
(其实很多人都一遍过,只是我没看见)
直到……zzy 60min交卷 zjy 70min交卷
我开始怀疑自己是不是真的写的太烂了。
一直到我看到ALE里面没引入Instr,我终于意识到:
我最新版没提交!!!
一瞬间,像是通过了一束电流,整个人呆住了。
急忙地改回代码,中间还改错了一次,漏写了一个接口,让我期待落空了几分钟。。
不过当我把新版本改好,漫长的排队等待……
绿了,绿了,红了?绿了? 还差一个中断异常,有2个点挂了。
中断区别于异常,我觉得比较易错的是空泡的处理,琢磨了一段时间,我好像意识到自己应当采用两种不同的流水方式。
但是这时已经8:55了。如果我提交并通过,我将没有机会再去不通过。
我迟迟没有提交。
我只顾着懊悔为什么没提交最新版,却没想到其实我可以先把前面一道题弄错,从而能够判断这题能不能过的同时顺利不通过。
希望能给大家一点启发吧。
Update 12.3
没想到中测就能测出来这个问题。
我特意交了一版没修改nop流水方式的,居然挂掉了一个点,和当时中断强测的点略有类似。
而且修改之后便通过了。
那可能,就是这样了?
我好像安定下来了,但又诚惶诚恐。
跟P6好像啊,一场考试下来还不知道自己课下还有没有问题。
据说加指令的题也不简单。2h能拿下吗?
紧张,紧张。
P7上机 —— 2
在开考前进行了龙芯杯的宣讲。
考试时间7:40-9:40,注意时间把控。
其实对自己的MIPS还是略带自信的,因为我确实不相信他会加强测试点。
建议下载压缩包后直接速提交,不要再做解压,或是装进ISE等事项。你要提交的就是源代码。
否则就会喜提20min的gap,心神不宁地排300余人的队
强测过了之后,完全不可懈怠!一定要严谨严肃。
本次题目为:
添加异常WATCH
触发方式有二:IMWATCH
与DMWATCH
PC0添加18号寄存器与19号寄存器(支持正常读写)
19号寄存器为异常判断使能
18号寄存器高16位是IM敏感值,低16位是DM敏感值
异常逻辑就是
当前pc与IM敏感值相同
时且19号寄存器使能满足要求时触发IMWATCH
DM敏感值在sl指令读写地址范围内
时且19号寄存器使能满足要求时触发DMWATCH
几个注意点:
- 异常优先级。以往的异常是不会同时出现的,而如今IMWATCH随时可触发,DMWATCH可以与ADEL,ADES同时触发
-
- IMWATCH优先级低于取指异常,高于其他异常。
-
- DMWATCH优先级低于ADES,ADEL(对于同时出现的异常)
- 范围内。对于DMWATCH注意要匹配的是在范围内,如sw,DM敏感值是四个值中的一个即可。
这里我们可以大胆用ADDR<= watchaddr <=ADDR+3, 他一定字对齐,否则会出现优先级更高的ADES异常。
- 乘除槽。IMWATCH可以在任何指令上触发,因此乘除法也可能是异常指令,不能等到他走到M级在检测出来,此时为时已晚,乘除槽停不下来。
因此需要提前判断好IMWATCH异常,将其加入MDALU模块。 - 阻塞。mtc0 18和19都是危险的,会直接影响WATCH的判断,因此必须阻塞。
这决定了IMWATCH不能在F级判断,因为这样会使D级为mfc0 18,19也需要阻塞,而这会导致死循环,因为我们的阻塞逻辑就是在D级实现的,那么mtc0就被卡在D级不得动弹。
在D级判断IMWATCH是较为正确的选择。
作者其实没有一交即过。
让我以为这个测试很强。
其实是因为写成了CP018号寄存器31:16 == pc[31:16]…
应该是CP018号寄存器31:16 == pc[15:0],
或者{16’b0,CP018号寄存器31:16} == pc.
改完没想到就直接过了。 一瞬间,惊喜而释然。
说在最后
计组上机就这样圆满结束了。
在提问环节,助教问我:
你觉得你在计组闯关的收获是什么?
回首,一路走来实在坎坷。
Pre的茫然
P1的无力
P4的惊愕
P5的懊悔
P6的愚钝
P7的畏惧
平稳,或是激荡地
每一个Project都有着课上课下的呐喊
从第一个单周期CPU
到封装流水线CPU可支持中断支持外设支持异常处理支持30余条指令的MIPS微系统
诞辰不久的博客也日渐丰满
这像是一种高压下的凝聚
引领着我们去稳健处理庞大的项目
从形象框架到代码实现
从独立执行到高效流水
从单一指令到复杂延时
从固定运行到异常中断
不同的Project把步骤分离
并予以较强的正确性检查
使得P5不必担心P4部件的实现
P6不必担心P5转发阻塞的实现
P7不必担心P6CPU本身的实现…
未来的项目倘若没有这些具象的规划
根本不敢想有多困难。
当然,感谢每一位同行者的帮助与支持。非常感谢。
CO上机结束,我也终于可以好好躺下,大脑放得很空很空,吸入又呼出些跳动的空气,悄悄捕捉又一颗充满爱与自由的心。