计算机组成原理课程设计总结

课程设计简介

设计的目的及要求

本课程设计是计算机科学与技术专业重要的实践性教学环节之一,是在学生学习完《计算机组成原理》课程后进行的一次全面的综合设计。目的是通过一个完整的8位指令系统结构(ISA)的设计和实现,加深对计算机组成原理课程内容的理解,建立起整机系统的概念,掌握计算机设计的基本方法,培养学生科学的工作作风和分析、解决实际问题的工作能力。

要求学生综合运用计算机组成原理、数字逻辑和汇编语言程序设计等相关知识,理解和熟悉计算机系统的组成原理,掌握计算机主要功能部件的工作原理和设计方法,掌握指令系统结构设计的一般方法,掌握并且运用微程序设计(Microprogramming)思想,在设计过程中能够发现、分析和解决各种问题,自行设计自己的指令系统结构(ISA)。

设计内容

基于TDN-CM++计算机组成原理实验教学系统,设计并实现一个8位指令系统结构(ISA),通过调试和运行,使设计的计算机系统能够完成指定的功能。

  1. 指令系统风格:寄存器-寄存器风格;

  2. 寄存器组:三个通用寄存器R0、R1、R2,三个专用寄存器IR、AR、PC;

  3. 存储器组成与划分:

    • 主存:地址空间256个,寻址能力8 bits,存储容量256 Bytes;
    • 控存:地址空间64个,寻址能力24 bits,存储容量192 Bytes;
    • 存储器指令区:00H~77F,数据区:80H~FFH;
  4. 指令编码格式:

    • 字段划分:操作码、操作数;
    • 字节划分:单字节,双字节;
  5. 指令功能类别:

    • 算术/逻辑运算:ADD、SUB、AND、XOR;
    • 程序流控制:JUMP、BRANCH、NOP、STOP;
    • 存储器访问:STA、LOADI、LOAD;
    • I/O:IN、OUT;
    • 移位运算:SR、CSR、SL、CSL;
  6. 数据类型:有符号整型数;

  7. 寻址方式:

    • 立即数寻址:LOADI;
    • 寄存器寻址:ADD、SUB、AND、XOR、JUMP、BRANCH、IN、OUT、SR、CSR、SL、CSL;
    • 直接寻址:STA、LOAD;
  8. 条件码:进位位(CY),判零位(ZI);

  9. I/O设备管理方式:分离式I/O;

  10. 依据CPI(静态、动态)值对指令系统进行性能分析。

难点

咧威认为完成这个课程设计有三方面的难点:1)理解TDN-CM++计算机组成原理实验教学系统;2)自行设计自己的指令系统结构(ISA);3)实现具有挑战性的测试程序。

理解TDN-CM++计算机组成原理实验教学系统

在做课程设计之前,一共要做七个实验来熟悉实验设备。熟悉了之后才能了解设备的局限性,在之后设计 ISA的时候做出权衡(Trade off)。咧威在做完七个实验之后,并没有完全理解实验设备的原理。原因有两个:1)实验的难度不大,即使没有理解透彻也能做出来;2)咧威当时没有想过要去完全弄懂实验设备,觉得完成实验即可。 PS:在次感谢老师的用心良苦,若不是接下来要求自己设计 ISA这么有挑战性的任务,咧威根本没有达到加深对计算机组成原理课程内容的理解,建立起整机系统的概念的实验要求。

自行设计自己的指令系统结构(ISA)

咧威一开始先模仿实验七已经实现的加法指令,增加其他的运算类指令。此时咧威发现实验七的两个问题:

  1. 通过控制台把机器代码存入存储器(Memory),如果存错了一条代码,必须重头再来,无法直接修改存错的代码。

    原因: 地址由 PC寄存器决定,而 PC只有清零和 PC + 1 两种操作。当前地址存错机器码了,只能清零 PC,然后不断 +1 直到出错的地址,再修改内容。

    解决方法: 修改控制台,存储器地址可以由输入设备提供,这样可以直接输入出错的地址,修改内容。[1]

  2. 实验七的加法指令是寄存器-存储器风格,意味着每执行这条指令,都得访问一次存储器,增加了CPI( Clock Cycles Per Instruction,平均每条指令所执行的指令数) 。

    改进方法: 改为寄存器-寄存器风格。

对比了实验七采用的寄存器-存储器风格和自己采用的寄存器-寄存器风格之后,理解了 RISC的好处,于是其他的指令也效仿 MIPS,尽量简单,只做一件事(想到了 KISS原则 ^_^)。比如设计分支指令。

由于分支指令需要根据条件码进行判断,做出选择,大部分同学都是把产生条件码的操作加入到分支里。比如减法运算能产生条件码,那么就分支指令就做了一遍减法的操作,然后再分支。咧威觉得太累赘,而且不灵活。如果想通过逻辑与运算产生条件码呢?之前设计的减法产生条件码的分支指令就不适用了,难道要再加一条逻辑与产生条件码的分支指令?或者是把减法产生条件码修改成逻辑与产生条件码?

咧威设计的分支指令只干一件事,直接根据条件码进行判断,至于如何产生条件码,那是其他指令的事情,与分支指令无关。在写机器码的时候,要实现分支,就得用两条指令:1)产生条件码的指令(比如减法指令);2)分支指令。

其实这样的设计非常好理解,但真正这么做的同学也不多。原因还是已经提到过的:怕出错,Debug成本太高。

咧威的设计还有跟其他改进,尽量向 MIPS的 RISC风格靠拢,在此不一一说明。感兴趣的可以通过邮箱,咧威会发给你详细文档,通过邮件详细交流。

实现具有挑战性的测试程序

在做这个课程设计之前,听学长说看谁最后设计的测试程序厉害,于是存在这个误区:课程设计的评价标准就是看测试程序是否创新,有挑战性(算法复杂)。这让咧威为了测试程序所用到的指令而去设计 ISA,这样的 ISA局限性很大。

直到老师强调:设计 ISA要通用,不是只能运行你的测试程序,还要能运行别人的。咧威这才醒悟,设计 ISA才主要的,测试程序,顾名思义,就是用来测试 ISA的实用性。原来之前没有分清主次,明白之后就开始完善 ISA的指令功能类别。

咧威做的测试程序是乘法运算,先从无符号整型数的乘法入手,采用教科书《计算机组成与设计:硬件/软件分界面(英文版,第四版)》3.3节实现乘法的算法。完成这个测试程序之后,还没有到规定的十天时间(每天11个小时),咧威开始考虑实现有符号整型数的乘法,想到课上老师讲过的布斯算法(Booth’s Algorithm),参考文献是《In More Depth Booth’s Algorithm》。

布斯算法不难理解,但是用自己设计非常简单的 ISA来实现,就比较繁琐,也不算难。一条 for 语句能搞定的事情,这里就得用有条件分支(类似 if)和无条件跳转(类似 goto)实现循环,跳转地址还得根据内存具体的代码行数自己计算,总之注意的地方很多,非常繁琐。于是出错不可避免。Debug 是单步调试,看实验设备各个部件的运行状态,修改内存里的代码还得扳好几个开关,然后一调试就是一上午,一下午和一晚上,整整11个小时。若不是老师规定实验室要关门,咧威估计就停不下来了。调不出来就总是惦记着,第二天就早早来到实验室,继续调。期间还会被同学打断,帮助他们调程序。这个实验挂了,是没有毕业证的。鉴于问题的严重性,同学的问题优先于自己的问题。自己怎么说也能应付过去,而基础差的同学,咧威能帮就帮。

心得体会

计算机组成原理课程设计的动手阶段,咧威几乎用完十天的工作时间[2]才能完成。这次课程设计过程中极大锻炼了我耐心,以及学会如何权衡之后再做出相应的妥协。

咧威在连线这个阶段就摔过很多跟头。第一次的时候,用了两个小时排错,最后才发现是连线的插头错位了。写测试程序的时候,都用单步运行的模式进行调试。这是调程序最耗时的办法,必须沉得住气,静下心去分析每条微代码是怎么运行的。

设计指令集的时候,考虑到咧威的方案最多只能形成16个微操作的入口地址,而咧威的设计有17个指令。咧威采用的办法是在某个入口地址里用分支实现多条指令。这样做的好处是节省控存空间,但坏处是,整合在同一入口地址的指令,会多执行一条进行译码的微指令,使得CPI的值增大。

在课程设计过程中,咧威得到了很多同学的帮助,没有他们的指教,咧威会走更多的弯路,也不可能在规定的十天时间之内完成,在此感谢他们。

总而言之,在连续高强度的工作时间里,咧威遇到很多错误,有粗心的连线错误,也有算法本身的错误。为了排除这些错误,咧威选择了最有效,但也最费时的方法,分析每条微指令是怎么执行的,极大考验了咧威的耐性,也发现了自己考虑问题不够全面,做事不够细致的不足之处,今后咧威会多加注意,努力完善自身的不足之处。

脚注:

  1. 修改控制台的思路很简单,但是 去做的同学很少。当时的氛围是,能够用的(即使很麻烦,比如刚提到的控制台问题)就不会去修改。原因有两个:1)机器问题:用的有一定年头,担心机器抽风,把以前做好的设计不能实现了;2)个人问题:这个设备的 Debug没有编码的 IDE方便,需要自己推测出错原因,然后不断扳开关(相当于输入0或1)地测试,设备只认0和1。咧威 Debug的耐性就是这么磨练出来的。

  2. 大概连续工作七八天(没具体记录,略遗憾),每天11个小时。本来安装老师要求,是连续工作十天,每天11个小时。最后由于上课和考试,用零碎的时间段补完两三天的工作时间,凑够 110个小时。