课程设计简介
设计的目的及要求
本课程设计是计算机科学与技术专业重要的实践性教学环节之一,是在学生学习完《计算机组成原理》课程后进行的一次全面的综合设计。目的是通过一个完整的8位指令系统结构(ISA)的设计和实现,加深对计算机组成原理课程内容的理解,建立起整机系统的概念,掌握计算机设计的基本方法,培养学生科学的工作作风和分析、解决实际问题的工作能力。
要求学生综合运用计算机组成原理、数字逻辑和汇编语言程序设计等相关知识,理解和熟悉计算机系统的组成原理,掌握计算机主要功能部件的工作原理和设计方法,掌握指令系统结构设计的一般方法,掌握并且运用微程序设计(Microprogramming)思想,在设计过程中能够发现、分析和解决各种问题,自行设计自己的指令系统结构(ISA)。
设计内容
基于TDN-CM++计算机组成原理实验教学系统,设计并实现一个8位指令系统结构(ISA),通过调试和运行,使设计的计算机系统能够完成指定的功能。
指令系统风格:寄存器-寄存器风格;
寄存器组:三个通用寄存器R0、R1、R2,三个专用寄存器IR、AR、PC;
存储器组成与划分:
- 主存:地址空间256个,寻址能力8 bits,存储容量256 Bytes;
- 控存:地址空间64个,寻址能力24 bits,存储容量192 Bytes;
- 存储器指令区:00H~77F,数据区:80H~FFH;
指令编码格式:
- 字段划分:操作码、操作数;
- 字节划分:单字节,双字节;
指令功能类别:
- 算术/逻辑运算:ADD、SUB、AND、XOR;
- 程序流控制:JUMP、BRANCH、NOP、STOP;
- 存储器访问:STA、LOADI、LOAD;
- I/O:IN、OUT;
- 移位运算:SR、CSR、SL、CSL;
数据类型:有符号整型数;
寻址方式:
- 立即数寻址:LOADI;
- 寄存器寻址:ADD、SUB、AND、XOR、JUMP、BRANCH、IN、OUT、SR、CSR、SL、CSL;
- 直接寻址:STA、LOAD;
条件码:进位位(CY),判零位(ZI);
I/O设备管理方式:分离式I/O;
依据CPI(静态、动态)值对指令系统进行性能分析。
难点
咧威认为完成这个课程设计有三方面的难点:1)理解TDN-CM++计算机组成原理实验教学系统;2)自行设计自己的指令系统结构(ISA);3)实现具有挑战性的测试程序。
理解TDN-CM++计算机组成原理实验教学系统
在做课程设计之前,一共要做七个实验来熟悉实验设备。熟悉了之后才能了解设备的局限性,在之后设计 ISA的时候做出权衡(Trade off)。咧威在做完七个实验之后,并没有完全理解实验设备的原理。原因有两个:1)实验的难度不大,即使没有理解透彻也能做出来;2)咧威当时没有想过要去完全弄懂实验设备,觉得完成实验即可。 PS:在次感谢老师的用心良苦,若不是接下来要求自己设计 ISA这么有挑战性的任务,咧威根本没有达到加深对计算机组成原理课程内容的理解,建立起整机系统的概念的实验要求。
自行设计自己的指令系统结构(ISA)
咧威一开始先模仿实验七已经实现的加法指令,增加其他的运算类指令。此时咧威发现实验七的两个问题:
通过控制台把机器代码存入存储器(Memory),如果存错了一条代码,必须重头再来,无法直接修改存错的代码。
原因: 地址由 PC寄存器决定,而 PC只有清零和 PC + 1 两种操作。当前地址存错机器码了,只能清零 PC,然后不断 +1 直到出错的地址,再修改内容。
解决方法: 修改控制台,存储器地址可以由输入设备提供,这样可以直接输入出错的地址,修改内容。[1]
实验七的加法指令是寄存器-存储器风格,意味着每执行这条指令,都得访问一次存储器,增加了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的值增大。
在课程设计过程中,咧威得到了很多同学的帮助,没有他们的指教,咧威会走更多的弯路,也不可能在规定的十天时间之内完成,在此感谢他们。
总而言之,在连续高强度的工作时间里,咧威遇到很多错误,有粗心的连线错误,也有算法本身的错误。为了排除这些错误,咧威选择了最有效,但也最费时的方法,分析每条微指令是怎么执行的,极大考验了咧威的耐性,也发现了自己考虑问题不够全面,做事不够细致的不足之处,今后咧威会多加注意,努力完善自身的不足之处。