雄关漫道真如铁,而今迈步从头越。


你好!这是我的2025年计算机组成原理实验的学习经验总结,既自留以怀古,亦求为后人留下福泽。我将尽可能详细的讲述CO实验的实验流程,罗列我的学习资源,以及我的心得感想(碎碎念),希望能对你有所帮助。

实验流程

如你所见,这是一篇总结性的博客,为尊重“总”与“结”之本意,我并不会详细的写出我的实验思路,更不会直接贴出我的过关代码。我要做的,是复盘计组实验学习的内容,总结我在漫长的三个月中曾受的困惑,并希望能为遇到同样问题的你指点迷津。

Pre

Pre是CO学习中最关键的阶段,COPre一般开始于八月份,没错,是暑假期间。在Pre中,你将会学习CO实验的三大工具:Logisim,Verilog,MIPS汇编语言。

Logisim

其中,Logisim作为第一门工具,本身具有可视化的性质,也因此相对易懂。如果你严格按照课程组教程进行学习,你大概会遭遇CO课程中第一道坎:状态机。

状态机分为Moore状态机Mealy状态机,这里着重讲一下两者的区别。

Moore状态机的输出只取决于当前状态,而Mealy状态机的输出同时取决于当前状态和即刻的输入——打个比方,你是一名拥有“增加攻击力并同时造成伤害”技能的角色。如果你是一个RPG游戏高手,也许这会引起你的警觉:是先造成伤害,再增加攻击力,还是先增加攻击力,再造成伤害

其实这就是两者的区别,将增加的攻击力看作输入,将角色现在的攻击力看作状态机中存储的状态,将造成伤害看作输出。Moore状态机是前者:先进行输出,再改变状态,增加了多少攻击力并不影响打了多少伤害;Mealy状态机是后者:先改变状态,再进行输出,增加的攻击力也决定了伤害。

Verilog

Verilog将是CO实验中陪伴你最久的语言,所幸你学过C语言,对敲代码与代码逻辑应该并不陌生,但我还是需要提醒你,Verilog是一门硬件语言,而非编程语言,其与C语言有着重要区别,即语句的执行顺序,写一个例子你就懂了:

1
2
3
4
always @(*) begin
count <= count + 1;
ans <= count;
end

这段代码执行后,ans中存储的数据是count + 1吗?并非,其实是count,因为这两句语句是同时进行的,第二句执行时,count还没有进行自增呢。

此外,还必须要强调两点。一是非阻塞赋值=阻塞赋值<=的用法,实际上只需要记住:always块中,尤其是时序逻辑中,通常都需要用<=,而其他地方用=即可。二是$signed()的使用,Verilog里的符号运算有一套相当复杂的规则,如果搞不明白就记住:当需要符号运算时,把你能看到的一切数都套上$signed()一定不会错。

MIPS汇编语言

这应该是Pre中最痛苦的一章,从简单的运算语句,到函数,到递归,每一步的理解难度都成倍上升,既不像Logisim一样可视化,也不像Verilog可以类比其他语言学习。好在,MIPS难入门,却不难精通(或者说课程要求不高),在这一部分,不用太纠结于做出复杂的题目和实现复杂的算法,更重要的是理解何为机器码,这在后续CPU的搭建与测试中至关重要,而其实若只是为了测试CPU,会一些基本的运算就可以了。

当然,为了Pre以及后续的P2成绩能好看一些,我还是需要做一个提醒:如果你想尝试涉及函数与递归的程序编写,要尤其注意压栈,在一个函数被重复执行第二次前,要将其中会被赋值的寄存器原本的值压入栈中,在第二次执行完后再取出。否则你的程序结果会相当疯狂!debug完全无从下手。当然,如果发现你的程序输出一团乱麻,首要检查的也是压栈是否正确实现。

.macro宏定义相当好用,大胆使用吧!print,scan,exit,push,pop,getMatrixIndex都是我很爱用的宏,Pre和P2教程中都教了如何定义,理解后大胆copy(背诵上机)即可。

Pre上机

按往届经验,Pre上机是不占分的,挂零还是全AC都不影响最终成绩,但这不意味着Pre的学习不重要。鉴于Pre开始于八月,而Pre上机大概率在国庆前的最后一周。我的建议是:在暑假期间先学习Logisim(因为它真的很有趣,有趣到假期都能学的进去),尝试读一读Verilog的教程。而MIPS的学习,可以在开学后跟着理论课的学习一起(不然你会极度怀疑学习的意义)。至于Pre中的课下题,能不能通过当然也是不要紧的,量力而行即可。

P0 - P2

虽然已经学习了两个月的计组~~(如果你真的学了Pre的话)~~,但是CO实验从P0才算正式开始。现在是时候讲一下CO实验的记分规则了。

在近几届,CO都是5.5学分的课,而实验的占比是40%,即2.2学分——与法科社分数相等,实在是个食之无味,弃之可惜的分数——除了Pre外,一共会有P0-P7共八项任务。其中,P0-P2是每周发布一项,无论你课下题目是否做完,下一周都能顺利上机,上机一般是三道题目,做出两道过关,做出三道优秀,在P0-P2中,会有180分钟的答题时间,前120分钟是自主答题,最后60分钟可以询问助教。具体给分情况每届不同,但可以确定的是,只要在180分钟前做出两题以上,和满分都不会有太大差距,毕竟P0-P2的占比本身较小。

而从P3开始,便采用令人闻风丧胆的闯关制:每周需要完成课下任务才能在下一周获得上机机会,而课上依旧是三道题目,两道过关三道优秀,但只会给你120分钟时间。如果某一周没能上机成功,即课下没完成or上机测试没做出两道题,则下一周的课下任务不能推进(其实可以提前往后做,但系统不会给你后面的提交窗口),并且下下周你上机还要重复考上周的内容,俗称gap。一个学期有3次gap机会,即:如果你上机失败3次,你依然可以在最后一次上机中达到最后一关。

最终你的实验成绩,绝大部分取决于你最终止步于哪里,小部分取决于你每次上机成绩做出几道题。如果你最终顺利通过了P7却经常只做出两道题,大可不必为此懊恼,因为本人也是这样,一两个优秀绝对不会比理论考试一道选择题占分多。

此外,在每次上机的最后,会有助教问答环节,据说答不上来问题的话会对分数有影响。问的问题一般都不会太难,但答不上来还是会很尴尬~

在这一部分说这些算分规则主要是不想让P0-P2这块太空(乐),毕竟P0-P2确实没什么好讲的,三个P分别对应Logisim,Verilog,MIPS的专项练习,难度并不比Pre里的某些题大多少,安心准备吧。

不过值得说道的是,P1中Verilog即使顺利通过了,也请在接下来几周略微保持对Verilog的语感,因为P4之后还需要大量使用Verilog(真的很大量!)。而P2中MIPS即使折戟也不必为之后CPU感到焦虑,因为以后要用到的MIPS很简单(真的很简单!)。

P3 & P4

准备好了吗,计组要开始加速了——

从P3开始,就要进行CPU的搭建了,这会是计组中第一次艰巨的任务:从完成一个个的计算小模块,上升到用各种小模块组成一个项目。经过P0的历练,你对小模块的搭建应该很熟悉了,最大的难点就是小模块的连接方式。

在这一章中,对官方教程感到困惑在所难免,因此我强烈建议找一找往届学长的参考文件,但是不要先看搭建流程教学。反复品读学长的完整项目,相信你每次浏览都会有新理解。而为了帮助你更快的理解别人的CPU,我也在这里做一些简单的提示,这都是我曾感到困惑的点:

  • 这个CPU的起点在哪里?不同于以前写的Logisim项目,CPU中没有显而易见的输入——因为输入隐藏在了IM模块里。因此我建议你从**IM(取指令模块)**中的ROM开始看起(有的项目也会把IM放在PC里),这里可以存放一系列机器码指令,IM每个周期的输出其实就相当于CPU每个周期的输入。

  • Controller输出的都是些什么鬼?这些东西统称为控制信号,有点类似在C语言中写的那些flag1,flag2,flag3(如果你和我一样编程习惯不太好的话),用在各种地方作为if-else选择的判断信号。非常建议在设计CPU前绘制一个指令与控制信号的对应表格,这对你理清哪些信号用在哪里很有帮助。

  • 跳转指令?还记得我说从IM的ROM开始向前推进吧?可别忘了IM的后面其实也有人呢!IM被输入地址的地方其实就是跳转指令的实现场所,在那里会有一个大多选器,用来分别实现PC正常自增,绝对跳转,相对跳转。当然,选择哪一个取决于Controller传来的控制信号。

在自己实现的过程中,也有一个小的tips:在顶层模块中适量使用tunnel,用的太少会导致接线很乱,用的太多找tag又很麻烦,我的个人建议是除了控制信号全部使用tunnel外,其他的连线只有横跨CPU的那种长连线才使用tunnel。

如果你顺利提交了P3的课下,恭喜你!完成一周的任务真的会如释重负,而且Logisim的可视化CPU真的酷毙了,甚至让人忍不住反复打开欣赏,实在太有成就感了。不过别高兴太早,我还是要为你敲响警钟:

P3开始,课上三道题将变为在课下设计的基础上加指令,并且课程采取强弱测制度,即课下通过并不保证项目完美无缺,就像大一程设课的代码示例通过也并不等同于AC。如果你不想课上宝贵的120分钟用来debug还课下的债,最好想尽一切办法在课下就测试好你的CPU完全正确。如果你对自己构造的数据不放心,可以试试我后面贴的COT自动评测机,不过不要过度依赖哦,自己构造数据debug也是一项重要的能力。

顺便一提,课上题目的测试点中大概率有一两个不涉及新代码,而是纯粹的课下任务强测。所以你可以试试在开考第一分钟直接裸交一份课下工程,以确定CPU本身的正确性。

如果你已经不留遗憾的走出P3的考场,那这回是真的要恭喜你了,因为下周的P4任务只是把P3的Logisim几乎原封不动的翻译成Verilog语言,可以称得上是休息一周了——如果你和Verilog还没有成为陌生人的话。不过相对于P3,简洁与易读的设计架构对P4而言更加重要,因为P5-P7都是在P4的项目上迭代加工,如果P4的架构不够简洁,后续大概率要进行重构。这时你的OOpre项目大概已经完工了,你应该懂得重构的痛。

无论如何,尽情享受P4周的欢愉吧,因为下周大的就要来了!

P5 & P6

P5是计组实验过程中码量最大的一章,理解难度也数一数二。在这一章中,需要将P4的Verilog单周期CPU升级为流水线CPU,顶层模块即将迎来大变(意味深)。此处不再赘述讲CPU升级为流水线CPU的具体流程,直接跳到理解难度最大的部分:阻塞与转发。

为何需要阻塞与转发?想象这么一段代码:

1
2
addi $t1, $t0, 1
addi $t2, $t1, 1

仔细想想,若按照流水线CPU的运行,在第一条指令在E级运算新的$t1值的同时,第二条指令在D级将旧的$t1值用来运算了,这显然不是一般的错误了,必须要出重拳!你一定能想到的思路是:等到第一条指令在W级把新值送进$t1后再执行第二条——这便是阻塞。

然而,一个程序里类似的错误不知道要发生多少次,如果每一次都阻塞,那你的CPU一定是World’s slowest CPU。这时候就需要用到转发了:不难发现,第一条指令的结果其实在E级就算出来,只是在W级才写入,那其实在E级的ALU之后,我们就能提前取出这个数据给第二条指令用了。不过,实际实现中,我们一般在M级的开头取出数据,原因与CPU的运行周期有关,此处不赘述。

有人看出我在捏他World’s smallest violin了吗?没有的话也太尴尬了。

转发的触发条件?即何时转发,何时阻塞。我实在没有三言两语讲清楚的能力,甚至我在顺利通关后仍会在别人向我询问时感到惶恐——好在Kamonto’s Little Planet中讲的非常清晰易懂——我能通过P5也是多亏了这位。已严肃学习(敬礼

P6与P4类似,也是休息周:在这一周中,只需要添加乘除模块,实现内存外置,以及适配存取halfword和byte的指令——这一功能在做P5题的时候你应该已经实现过了,这次只是写的更加规范完整。P6的上机题目甚至和P5用的几乎一致的题库,既然P5已完成从斗圣到斗帝的突破,P6中稳固修为一定不成问题。接下来距离达到斗帝巅峰大圆满,只剩P7一步之遥了。

P7

P7的工程量不如P5那么庞大,但是理解难度却更上一层楼,并且改动任务十分繁杂。即使官方教程在本届已经进行了升级,我仍然在看教程的过程中怀念起了三岁时学着大人装模做样看人民日报的岁月。在这一周,你需要完成一个MIPS微系统,落实到具体就是实现转发和异常处理。其实真的很难解释他们是什么,因为这与下学期将学的操作系统有关——准确来说,在CO中,我们需要做的是告诉操作系统有异常和中断,至于具体怎么处理,不是现在需要考虑的事。

此外,P7还有一个重要任务,是实现外设与CPU之间的交互。一台计算机当然不能只有CPU,键盘,鼠标等外设才是用户与CPU交互的关键。课程组会将外设代码写好,你需要做的只是用一个叫Brigde的模块连接而已。好吧,你也许会对各种十几个字母的变量名颇有微词,但是细心一点,像缝针绣花一样仔细把每一种颜色穿进每一个正确的孔,写CPU并不比十字绣难很多,对吧?

无论你是希望独立完成任务的大神,还是和大多数人一样想从往届博客中寻找灵感,细心与耐心,是P7中最需要的能力,P7中会有许多在以前代码中插入一两个变量,或是加入一两个小条件的工作,东一榔头西一锤会让你在debug时苦不堪言。当你真的无计可施,试试从从头再来一次,不要在意沉没成本,这一定值得。

完结?

CO-OVER

如果你看到了这里,已经斩首巨龙,意气风发,首先——恭喜你!勇者击败了巨龙,接下来的故事,就是荣归故里,在一片欢呼与喝彩声中,接受象征着荣耀的表彰。现在,请好好享受这段难忘的时光吧!

如果你还在某处踌躇不前,甚至已经折戟沉沙,也不要就此消沉。正如Kamonto所说:

如果你已经挂过几回了,千万不要灰心!要相信,即使是一次又一次的挫败,你的能力也是在不断积累的。能够一路闯到这里,现在的你已经变得比之前任何时候的你都更加强大。休息一下,然后重整旗鼓,去面对最后的挑战吧!
如果你已经被迫止步于此,也不要为此过于悲伤,毕竟理论课的成绩才占计组课程的大头,我们还有着翻盘的机会,从现在开始准备起来吧!计组课程虽然是一门大课重课,然而研究的方向更偏向于硬件,可能会和很多同学感兴趣和擅长的领域并不重合,不要因为第一门专业课的失手就选择放弃,相信你能够找到自己热爱的领域,在亲手辛勤浇灌的土地上闪闪发光!

在旅途中失意过,彷徨过,遗憾过的旅人啊,请让我对你许以敬意——不为终点的功成与归乡的荣耀,只为浸入眼角的汗水,与膝盖上的擦伤。

学习资源

隆重感谢2025年六系的神,伟大的Kamonto先生:Kamonto’s Little Planet

同样是23级的大神,Lazyfish先生,记录了若干上机题,也是与我们最接近的P7任务教学:Lazyfish & chilly_river

两位往届的学长:

两位的教程年份差距较大,部分细节不同,但仍然是我P7搭建的重要老师。

上机强心针,在P7课下给我莫大帮助的COT自动评测机,配置简单,测试可靠。也请大家支持原作者Trash Bin for Chi

关注LanC1oud’s Blog谢谢喵,咕咕嘎嘎

一切资源仅供参考,严禁抄袭,违规后果自负。小心助教的大手!

碎碎念