内容发布更新时间 : 2024/11/14 15:26:59星期一 下面是文章的全部内容请认真阅读。
Design and Implementation of RISC I
[摘要]RISC是专门用来单片VLSI计算机执行的计算机体系结构,它证明了通过正确的选择一小部分指令和微体系结构的设计能够获得高产量的机器。有限的指令条数和寻址方式使得控制部分变小,同时缩短了机器的时钟周期,这样的机器对设计投入的要求大大降低,从而缩短了设计周期。
这样的RISC体系结构课程已经作为UCBerkeley大学的课程,课程分为四个部分:设计和评价体系结构思想,设计LSI组件,将这些组件放入VLSI片上,最后对VLSI片进行测试。CAD和芯片用来测试的环境同样也做了描述。
VLSI技术的发展使得在单硅片上实现微计算机成为了可能,但是这个和主框架的实现技术有很大的差别。
为实现一个高效的单片计算机,需要根据现在计算机发展的各种限制重新设计实现,有限的晶体管需要明智得分配给处理器、主存、通信接口、和其他需要的功能。 本文发现,通过合适的对一小部分经常被执行的知名的约束,结合专门被用来快速执行这一部分的所有指令的体系结构,这样的机器的执行效率出乎意料的高。
RISC I:Goal chip RISC II : Goal Chip
RISC工程以六个月的调研学习为基础,在这段时间里各种基础的概念都被考虑。RISC的设计着重考虑了高级程序语言的需求。RISC I选用的是C语言和Pascal语言。由于受到晶体管数量的限制,RISC I的大部分都由软件实现,硬件用来处理最耗费时间的项目,对于使用者来说这样的设计是不可见的,且没有多大影响。但这样的实现方式就需要一个高效的编译器和HLL调试工具。给定这样的框架,这个体系结构的重点在于决定哪些功能由硬件实现,哪些由软件实现
由于片周围带宽的限制,因此VLSI芯片必须强调独立动作。指令通过单独的短周期被执行,并且32位定长,不常用的指令则通过指令序列或者子程序来实现。
需要统计高级语言程序中各种语句的使用频率,这样能够更好的预测各语句类型执行的相应的代价。
3、重叠寄存器组
程序的使用过程包括两组耗费时间的操作:在每个调用和返回时保存和存储寄存器,在不同程序间传递参数和结果,可以通过使用多个寄存器组降低这个门槛,本地标量数据变量的使用频率通过将它们至于寄存器中能够证明这一点。
在RISC I芯片上,那些通过简化控制电路产生的区域被用来放置一大组32位的寄存器。处理器为每一个程序调用分配一组新的寄存器,这个过程通过简单的改变硬件指针实现,由此从而避免节约寄存器在内存中造成的高时间开销。返回指令将寄存器组指针重新置为先前的值,从而恢复寄存器组中原来的值。也有是个寄存器用作全局寄存器,因此每一个程序能够访问如图
1所示的32个寄存器。
第26到31号寄存器,用来保存当前程序的上一个程序传入的参数,比如程序调用时;16到25号寄存器用来进行局部标量存储;10到15号寄存器用来保存需要传入下一个程序的参数和本地存储内容,如程序被调用过程。
相邻寄存器组被调用者和被调用者重复使用,因此参数传递不需要做任何数据移动。对于每个程序都会调用一组新的寄存器,称为10-31号寄存器。然而下层寄存器的调用者将会变成上层寄存器的被调用者,因为他们在物理上是同一组寄存器,因此在10-15号寄存器中的参数会出现在被调用程序的25-31号寄存器中。这样的设计大大降低了访问数据寄存器的次数。
在许多程序中,程序嵌套调用的深度会超过处理器寄存器池提供的寄存器的数量,因此需要提供一种机制,通过将寄存器数据移入主存从而释放寄存器。本文已经研究了在不同的程序中一系列的程序调用和返回情况。一个典型的小程序递归调用所产生的程序嵌套深度统计如图3所示,每一个虚线框代表没有上下溢出的嵌套深度范围,当嵌套深度超过了当前物理寄存器文件所能够表示的范围,一个硬件陷阱指令将会终断程序,然后将一些寄存器值移入或者移出内存。一个独立的寄存器移出堆栈被放置在存储器的一个特定的区域,上溢和下溢都会使一个指针指向这个堆栈的顶端,这种程序调用的效率取决于上溢和下溢发生的概率。因为寄存器文件总是包含很少的顶层程序记录,因此上溢和下溢发生的频率取决于本地变量所处的堆栈的深度,而不是绝对深度。本文研究表明,通过8个寄存器组,上溢和下溢在所有的程序调用和返回中发生的频率将会少于1%。
为了使得寄存器能够通过指针访问,它们应当被编址。为了这个目的,在RISC I中,所有的寄存器被编入通常的存储器地址空间中。单独的地址和一个8-input AND域能够决定当前指针所指向的寄存器组在芯片上还是在存储器中。这种编址技术也被用来解决“up-level addressing”问题。Pascal和其他高级程序语言允许嵌套程序定义,因此需要建立一类变量,这类变量既不属于全局变量也不是单个程序的本地变量。编译通过静态或者动态链接或者呈现器保存每个程序的环境轨迹。RISC编译器能够使用存储器地址达到这个目的,然而在最初的RISC I和RISC II中并没有被应用。
RISC I的目标是以尽可能低的复杂度获得尽可能高的性能。
在最后的指令集中毫不吃惊的只有31条指令,这些指令拥有极其相似的格式,都是32位长。RISC I和RISC II都支持32位地址,同时支持8位、16位以及32位的数据。指令可以被划分位四类:算术逻辑指令,访存指令,分支指令,冗余指令。所有的算术、逻辑和移动指令都在寄存器之间实现,RISC I的周期由度寄存器,执行ALU运算,将运算结果写回寄存器三个部分组成。这个执行周期在预取指令和译码下一条指令部分重叠。
载入和存储指令在寄存器和存储器之间移动数据,这些指令占用两个CPU周期。八种存储器指令,支持不同数据类型,但是只支持一种寻址模式,其余寻址模式可通过与0号寄存器合成得到。
分支指令包括调用,返回,条件和非条件跳转指令
指令总共有三种形式
另一个产生高性能的一点是重叠的取指令和执行指令,但是控制流指令中的分支指令将可能产生问题。许多高级终端机器已经阐述过在分支指令后预取正确指令的技术,但是RISC I通过冲定义跳转,延迟跳转直至下一条指令。
延迟跳转允许RISC I总是可以载执行当前指令时预取下一条指令,机器语言被安排一个合适的执行顺序从而可以获得正确的结果。RISC I编译器包含一个优化器来重新排列指令的顺序,从而使得在跳转指令后能够做一些有用的事,如果做不到,则会插入NOP指令,从而跳转指令将会在两条指令中起作用。无条件跳转指令能够减少90%的NOP,但是条件跳转指令则只能减少20%NOP。当跳转的目的也被考虑进来后能够获得更好的结果。 5.微体系结构
RISC 1的简单性和规律性允许大多数指令执行遵循相同的基本模式:
(1)读取两个寄存器,(2)执行同一个操作,(3)把结果存回一个寄存器。Jump,call,和return
指令, 添加一个寄存器和一个偏移量,将结果存储到相应的PC锁存器。load和store指令违背了原来的约束:为了给主存足够的时间,我们添加索引寄存器并在第一次循环立即偏移并在一个额外的周期中执行访存指令。微体系结构的实现决定于这两个特征。 CPU可以自然地被细分为以下功能块:寄存器文件、ALU(运算器)、移位器、一系列程序累加寄存器、数据I/O锁存器、程序状态字寄存器、控制器、指令解码器、时钟周期。既然同时需要两个操作数,寄存器文件至少需要两个独立的主线和一个双端口单元的设计。在速度方面,寄存器由动态的预充电位线读取。这需要如下的基本时间序列:(1)寄存器读取(2) 算术/逻辑/转移操作(3)寄存器写,和(4)总线预充电来供下一次读。时间周期由这个操作序列决定。第三个总线的消耗,(3)和(4)可能重叠,相位(4)可以消除:然而结果可以通过额外的总线写回寄存器文件,为了读阶段两个读总线被预充电。三相方案采用了RISC处理器。在图4中显示了基本组织的两个只读总线(A,B)和一个只写总线(C)。
在RISC1的设计进化过程中,三总线寄存器单元发生显著消耗。既然大部分芯片的面积是为寄存器文件工作,这个设计把重点更集中地放在一个小的单元。经典的六晶体管单元RAM被选择用来在紧密度方面。读取是通过有选择地放电的两个预先给电位线充电的主线。其中一个携带数据的补充形式。与商业上可得到的静态RAM不同,那样的放大器是没有意义的。这样会产生一个速度上的损失,因为单元必须要给电容总线放电。但是关于典型的静态RAM取而代之的是,它提供了一个双端口的阅读能力。写是通过把两个数据和她的补充写到两个总线上。RISC2的设计就是基于这个双总线,双端口寄存器单元。
在芯片尺寸方面,较小的寄存器单元可以有可以预想的减小。在数据流的多晶硅的控制线方面因为更短的RC延迟,也有性能上的提高。允许寄存器写来使接下来的指令并行执行也能提高运行性能。一个操作数的结果保存在一个临时锁存器,只写寄存器文件在随后的算数/逻辑/移位操作阶段。如果结果在下一个指令马上用到,一个寄存器文件绕过传输这个值直接到ALU/移位器。事实上每个指令现在都回延伸到三个机器周期:1.指令取指和指令译码;2.寄