Featured image of post 上机

上机

纯粹的杂谈


说在前面

  • 本系列从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]+…倒也未尝不可

1
2
3
4
5
always@*使用说明
0.全使用=
1.初始化所有变量
2.全是reg型和integer型
3.有用的东西最后再assign到某个wire变量上去

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的使用
伪代码如下

1
2
3
4
5
6
if (m / b != n / b) {
    printf("0");
}
else {
    printf("%d", m % b);
}

有没有\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
触发方式有二:IMWATCHDMWATCH

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上机结束,我也终于可以好好躺下,大脑放得很空很空,吸入又呼出些跳动的空气,悄悄捕捉又一颗充满爱与自由的心。

comments powered by Disqus
Easy Life and Easy Learning
使用 Hugo 构建
主题 StackJimmy 设计