概况
本次NSCSCC比赛,我们NoAXI团队取得了二等奖,使用乱序双发射实现CPU,IPC为0.78,频率为83MHz。
比较遗憾的是,我们没有在规定的时间内成功启动Linux系统,导致我们最终的系统成绩分偏低。所幸答辩成绩还算过关,最终顺利拿到了二等奖。
心路历程
我们团队一开始都是打个人赛的,直到6月中旬才决定转成团队赛。所以我必须得介绍一下我们团队在组队之前的神奇经历。
我在3月底开始接触的龙芯杯,先花了半个月时间,配置环境并且学习chisel的语法。大概到了4月中旬的时候,我写出了一个最朴素的顺序五级流水。此后就在此基础上不断完善,一直到6月份写到了Cache和TLB的开发。当时并不知道个人赛会有这么多简化,直到6月份自己做到了TLB才发现,已经走的太远了。我们的AXI状态机和TLB都没法用在个人赛当中,只能去团队赛了。
于是果断转团队赛,跟涛哥一起组了NoAXI队。从6月中旬开始,我花了一周时间啃完了《超标量》并设计了乱序的基础结构。考试周期间比较忙,一直到7月份才有空写代码。我们团队从零开始,完全抛弃了原有的5级流水线设计,重写了一份乱序的代码,我主要负责的就是乱序架构相关的内容。大概到了7月中旬,终于成功地跑通了仿真。
但是当时我们因为DCache中SRAM实现上的问题,出现了仿真通过,上板未通过的情况。我们前后花了一周的时间去debug,在vivado里面拉debug信号进行调试,一跑就是两个小时,可以说是非常痛苦。
调完bug之后,我们的初赛也差不多相当于准备完毕了。此后我跑去起SoC,涛哥则准备启动linux。原本我设想的是起一个往年一等奖级别的定制化SoC,能够启动大部分的外设的,但因为驱动相关的原因,我最终没有成功启动以太网口,只能使用官方提供的SoC。我们最后的Linux也因为分支预测一致性问题而启动失败。可以说决赛相关的工作我们几乎全军覆没。
最后两天我们连续熬了两个通宵,改了起Linux过程中的五六个bug,但最终差临门一脚,没有成功。算是留下了挺多的遗憾。
启示,反思和总结
我们最终的设计版本其实很早就设计完毕了,但最终我们在访存相关的维护上面花了非常多的时间,尤其是访存的唤醒信号时延和一致性维护问题。我也希望,读到这篇文章的人在设计乱序CPU后端访存部件的时候,务必注意这些问题。
其实很多东西,不去实操是绝对不会懂得的。永远不要想当然,永远不要去优化自己猜想的路径,而应该根据数据进行优化。我在做访存之前,甚至想象过访存是一个与算术流水线差不多复杂度的东西,这使得我们在设计推测唤醒和优化时序的时候付出了惨重的代价。我们的唤醒也做得有点问题,我把一个串行逻辑写了进去,导致我最终无法把访存的推测唤醒加到里面去。这些问题很大程度上都是我想当然导致的。
说实话,我们这次比赛全程都在和时间赛跑,DDL一个接着一个地来,把我压的喘不过气来。6月中旬开始做乱序,8月中旬就要决赛提交,2个月的时间对于我们来说实在是太短了。我不止一次地想,如果再多给我们一个星期,说不定就能有新的转机了呢。但不论如何,我们既然做了乱序,就必须克服乱序带来的诸多设计难题。赶不上DDL也只能说是情有可原。
希望明年学弟加油吧,争取不留遗憾。