简单RISC处理器设计.docx
- 文档编号:6259334
- 上传时间:2023-01-04
- 格式:DOCX
- 页数:46
- 大小:517.03KB
简单RISC处理器设计.docx
《简单RISC处理器设计.docx》由会员分享,可在线阅读,更多相关《简单RISC处理器设计.docx(46页珍藏版)》请在冰豆网上搜索。
简单RISC处理器设计
简单RISC处理器设计
6.3简单RISC处理器设计
前面我们已经学习了现代电子系统设计的基本方法,学习了使用VerilogHDL语言设计简单组合逻辑和简单时序逻辑模块,学习了自顶向下的设计方法,同时还学习了状态机的设计。
在这里,将综合运用以上所学的知识,设计一个简化的处理器。
“麻雀虽小,五脏俱全”,这里设计的处理器虽然是经过简化的,但是能对其进行综合、适配,最终可以在硬件上运行。
这里介绍的处理器由于主要用于教学,只是一个简单的教学模型,设计不一定合理,只是从原理上说明了一个简单的处理器是如何构成的。
6.3.1RISC处理器简介
中央处理器(CPU,CentralProcessingUnit)是计算机的核心部件。
计算机进行信息处理可分为两个步骤:
(1)将数据和程序(即指令序列)输入到计算机的存储器中;
(2)从第一条指令的地址起开始执行该程序,得到所需结果,结束运行。
CPU的作用是协调并控制计算机的各个部件并执行程序的指令序列,使其有条不紊地进行。
因此它必须具有以下基本功能:
◆取指令——当程序已在存储器中时,首先根据程序入口地址取出一条程序,为此要发出指令地址和控制信号。
◆分析指令——即指令译码,这是对当前取得的指令进行分析,指出它要求什么操作,并产生相应的操作控制命令。
◆执行指令——根据分析指令时产生的“操作命令”形成相应的操作控制信号序列,通过运算器、存储器及输入/输出设备的执行,实现每条指令的功能,其中包括对运算结果的处理及下条指令地址的形成。
将CPU的功能进一步细化,可概括如下:
(1)能对指令进行译码并执行规定的动作;
(2)可以进行算术和逻辑运算;
(3)能与存储器和外设交换数据;
(4)提供整个系统所需要的控制。
尽管各种CPU的性能指标和结构细节各不相同,但它们所能完成的基本功能相同。
由功能分析可知,任何一种CPU内部结构至少应包含下面这些部件:
(1)算术逻辑运算部件(ALU);
(2)累加器或寄存器;
(3)程序计数器;
(4)指令寄存器和译码器;
(5)时序和控制部件。
精简指令计算机(RISC,ReducedInstructionSetComputer)是一种20世纪80年代才出现的CPU,它与一般CPU相比不仅只是简化了指令系统,而且还通过简化指令系统使计算机的结构更加简单合理,从而提高了运算速度。
从实现的途径看,RISC处理器与一般的CPU的不同之处在于:
它的时序控制信号形成部件是用硬布线逻辑实现的而不是采用微程序控制的方式。
所谓硬布线逻辑也就是用触发器和逻辑门直接连线所构成的状态机和相应的组合逻辑,故产生控制序列的速度比用微程序控制方式快得多,因为这样做省去了读取微程序指令的时间。
下面就详细介绍一个简化的、用于教学目的的RISC处理器SimpleRISC,它是采用硬布线逻辑实现的控制,是一个可综合的CPU模型。
6.3.2SimpleRISC处理器结构介绍
一、处理器结构
这里首先对我们即将要进行设计的SimpleRISC处理器硬件结构作一个简要介绍。
这里所介绍的处理器结构只是SimpleRISC芯片的内部结构,或者说只是SimpleRISC的CPU核,所以不包括存储器单元和外设等。
SimpleRISC处理器的内核结构如图6-48所示。
图6-48SimpleRISC处理器内核结构
从图6-48中可以看出,SimpleRISC处理器内核包括以下功能单元:
控制器、程序计数器、通用寄存器、算术逻辑单元(ALU,ArithmeticLogicUnit)和总线接口单元(BIU,BusInterfaceUnit)。
以下的内容将依次讨论这些模块。
二、处理器内部子模块
1、控制器
控制器用于进行指令译码、产生ALU运算控制信号、产生通用寄存器读写控制信号以及协调处理器工作时序工作。
2、程序计数器
程序计数器用于指向下一条将要执行的指令的地址,它可以自动增值或是通过分支指令来设置其内容。
3、通用寄存器
SimpleRISC处理器内部有32个32位通用寄存器,ALU运算的源操作数、目的操作数大都来自这个通用寄存器堆。
4、算术逻辑单元
算术逻辑单元用于进行算术运算、移位操作、比较设置操作以及逻辑运算。
对于其他未能实现的运算,例如乘法、浮点运算等,可以使用软件来实现。
5、总线接口单元
总线接口单元用于SimpleRISC处理器与外部存储器和I/O口的连接,为了简单起见,SimpleRISC系统的存储器和I/O采用统一编址的方式进行组织,并且采用程序存储器和数据存储器分开的哈佛结构。
从图6-48可以看出,SimpleRISC处理器并没有实现中断处理以及Cache等功能,虽然如此,但是SimpleRISC处理器已经能进行一些简单的工作了。
下面将继续讨论有关SimpleRISC的一些细节。
6.3.3SimpleRISC处理器的指令集和寻址方式
一、SimpleRISC处理器的指令集
SimpleRISC处理器的指令集中包括以下指令:
(1)算术运算指令
算术运算指令包括加法(add)和减法(sub)指令。
(2)比较指令
比较指令只有小于则设置(slt)指令。
(3)移位指令
移位指令包括左移(ls)和右移(rs)指令。
(4)逻辑运算指令
逻辑运算指令包括与(and)、或(or)和非(not)指令。
这里的逻辑运算都是按位进行的。
(5)数据存储器访问指令
数据存储器访问指令包括存储器数据加载(load)和数据存储(store)两条指令。
数据存储器的访问都必须通过这两条指令来进行。
(6)分支指令
分支指令分为无条件分支和条件分支两类。
无条件分支指令只有一条:
branch;而条件分支只实现相等则分支(beq)指令。
二、SimpleRISC处理器的寻址方式
CPU的寻址方式指的是CPU在进行操作时如何找到操作数的方法。
一般来说,操作数可以存储在CPU内部寄存器中,也可以由指令提供,还可以存储在数据存储器中。
对于RISC处理器来说,操作数一般都由指令提供或存储在CPU内部寄存器中,而RISC处理器一般不直接使用数据存储器中的数据作为操作数。
这里的SimpleRISC处理器,其操作数也由指令提供或存储在CPU内部寄存器中,相应的寻址方式为立即寻址(操作数由指令提供)和寄存器寻址(操作数存储在CPU内部寄存器中)。
6.3.4SimpleRISC处理器的指令格式与编码
一、指令格式
这里假设设计的SimpleRISC处理器是32位的,由于它有32个32位寄存器,所以每个寄存器需要使用5位编码来寻址。
将以上讨论的指令分为三种类型的指令:
R-类型指令、I-类型指令和J-类型指令。
R-类型指令指的是操作数全部来自通用寄存器,包括寄存器操作数的算术运算指令、比较指令和逻辑运算指令。
由于这些指令的操作数都来自于通用寄存器,而一般的操作都有三个操作数:
两个源操作数和一个目的操作数,所以R-类型指令中需要使用5×3=15位来对寄存器进行编址,对于32位指令,使用了15位以后,还剩余17位,其余的17位都可用于指令的编码,所以一共可以有217=131072条R-类型的指令。
I-类型指令指的是操作数中有部分来自于通用寄存器,而另一部分是来自于指令本身的立即数,包括带有立即数的算术运算指令、比较指令、逻辑运算指令、移位指令、数据存储器访问指令和条件分支指令。
除移位指令外,立即数都是16位的,而另外还需要两个寄存器操作数,所以共需要16+5×2=26位编码,还剩余6位编码,所以可以有26=64条I-类型的指令。
对于移位指令,由于操作数是32位的,所以移位位数最多为32位,则只需要5位立即数即可,因此共需要5+5×2=15位编码,剩余17位可用于指令编码。
J-类型指令只有一条:
无条件分支指令Branch,它采用6位指令编码(为了与I-类型指令格式对齐),剩余的26位用于指明分支的目的地址到当前程序计数器的偏移量。
假设采用补码表示法,则最大偏移量在-225~+(225-1)之间,即-0x02000000~+0x01FFFFFF之间。
而前面讨论的条件分支使用16位偏移量,所以最大偏移量在-215~+(215-1)之间,即-0x00008000~+0x00007FFF之间。
通过以上讨论,可以定义出以下指令格式。
对于R-类型指令,指令中包括三个5位的通用寄存器地址域和一个17位的指令编码域,为了与I-类型及J-类型指令保持格式一致,将指令编码域分成了11位和6位两个部分,参见图6-49。
图6-49R-类型指令格式
图中的A、B、C为通用寄存器地址,OPX位11位指令编码,OP位6位指令编码。
对于I-类型指令,指令中包括四个域:
两个5位的通用寄存器地址、6位指令编码和16位地址偏移量,可以表示为图6-50所示的格式。
图6-50I-类型指令格式
图中的A、B为通用寄存器地址,IMM16为16位立即数(对于移位指令,只用最低5位),OP为指令编码。
对于J-类型指令,指令中包括两个域:
6位指令编码和26位地址偏移量,可以表示为图6-51所示的格式。
图6-51J-类型指令格式
图中的OP部分即为指令编码,而IMMED26是地址偏移量。
从以上三种类型指令的编码格式可以看出,SimpleRISC处理器的格式比较统一,设计起来也就会比较简单。
实际上,几乎所有的RISC处理器的指令格式都采用这里的设计思想,使得设计简单,译码逻辑也简单,从而提高处理器性能。
更重要的是,这种简单的设计有利于使用流水线来实现,能更进一步提高处理器性能。
二、SimpleRISC处理器的指令编码
1、加法
这里实现的是有符号数的加法,不考虑溢出。
(1)寄存器操作数相加
汇编语言表示形式:
addrt,rs1,rs2
操作说明:
rt=rs1+rs2
编码:
(2)寄存器操作数与立即数相加
汇编语言表示形式:
addirt,rs,imm16
操作说明:
rt=rs+imm16,对imm16进行符号扩展
编码:
2、减法
这里实现的是有符号数的减法,不考虑溢出。
(1)寄存器操作数相减
汇编语言表示形式:
subrt,rs1,rs2
操作说明:
rt=rs1-rs2
编码:
(2)寄存器操作数与立即数相减
汇编语言表示形式:
subirt,rs,imm16
操作说明:
rt=rs–imm16,对imm16进行符号扩展
编码:
3、小于则置一
这里实现的是无符号数的比较。
(1)寄存器操作数比较
汇编语言表示形式:
sltrt,rs1,rs2
操作说明:
rt=(rs1 编码: (2)寄存器操作数与立即数比较 汇编语言表示形式: sltirt,rs,imm16 操作说明: rt=(rs 编码: 4、左移 汇编语言表示形式: slrt,rs,imm5 操作说明: rt=rs< 编码: 5、右移 汇编语言表示形式: rlrt,rs,imm5 操作说明: rt=rs>>imm5 编码: 6、逻辑与 这里实现的是无符号数的逻辑与。 (1)寄存器操作数的逻辑与 汇编语言表示形式: andlrt,rs1,rs2 操作说明: rt=rs1&rs2 编码: (2)寄存器操作数与立即数的逻辑与 汇编语言表示形式: andlirt,rs,imm16 操作说明: rt=rs&imm16,对imm16进行零扩展 编码: 7、逻辑或 这里实现的是无符号数的逻辑或。 (1)寄存器操作数的逻辑或 汇编语言表示形式: orlrt,rs1,rs2 操作说明: rt=rs1|rs2 编码: (2)寄存器操作数与立即数的逻辑或 汇编语言表示形式: orlirt,rs,imm16 操作说明: rt=rs|imm16,对imm16进行零扩展 编码: 8、逻辑非 这里只实现了寄存器操作数的逻辑非。 汇编语言表示形式: notlrt,rs 操作说明: rt=~rs 编码: 9、从存储器取数据 汇编语言表示形式: loadrt,rs,imm16 操作说明: rt=memory[rs+imm16],对imm16进行符号扩展 编码: 10、存储数据到存储器 汇编语言表示形式: storers1,rs2,imm16 操作说明: memory[rs2+imm16]=rs1,对imm16进行符号扩展 编码: 11、无条件分支 汇编语言表示形式: branchimm26 操作说明: PC=PC+imm26,对imm26进行符号扩展 编码: 12、相等则分支 汇编语言表示形式: beqrs1,rs2,imm16 操作说明: if(rs1==rs2)PC=PC+imm16; elsePC=PC+1; 对imm16进行符号扩展 编码: 6.3.5数据通路的建立 前面我们讨论了将要设计的SimpleRISC处理器的指令集和编码,包括算术逻辑运算指令、存储访问指令和分支指令。 这些指令的实现过程大致相同,而与具体的指令类型无关。 实现每条指令的前两步是一样的: (1)程序计数器(PC)指向指令所在的存储单元,并从中取出指令; (2)通过指令字段的内容,选择读取一个或两个寄存器。 对于取字(load)指令,只需读取一个寄存器,而其他大多数指令要求读取两个。 这两步之后,为完成指令而进行的步骤则取决于具体的指令类型。 然而,对三种指令类型(存储访问、算术逻辑和分支)的每一种而言,其动作大致相同,与具体操作码无关。 即使是不同类型的指令,也有一定的共性。 例如,所有类型的指令在读取寄存器后,都要使用算术逻辑单元(ALU)。 存储访问指令用ALU计算地址,算术逻辑指令用来执行运算,分支指令用ALU进行比较。 可以看出,指令的简洁和规整使许多指令的执行很相似,因而简化了实现过程。 使用ALU计算完成之后,不同类型指令需要进行不同的操作。 存储访问指令需要对存储单元进行读出或写入;算术逻辑指令需要将ALU产生的数据写回寄存器中;而分支指令会根据比较的结果,决定是否需要更改下条指令的地址。 图6-52概括地描述了SimpleRISC的实现方式。 以下将介绍其细节。 这里需要加入更多的功能部件,以及功能部件间的连接,当然还要有控制单元以控制不同类型指令需要执行的操作。 图6-52SimpleRISC实现,包括主要的功能部件和它们之间的主要联系 开始设计数据通路比较合理的方法是先看看每种SimpleRISC处理器指令执行时所需的主要部件。 先来看看每条指令需要什么数据通路部件,再用这些部件为每种指令类型建立其数据通路。 在指出数据通路部件的同时,我们也会指出它们的控制信号。 首先需要的部件是一个存储程序指令的地方。 一个存储单元是一个状态单元,它用来存储指令,并根据所给地址提供指令,如图6-53所示。 指令的地址也必须存放在一个状态单元中,我们称之为程序计数器(PC),也在图6-53中示出。 最后,需要一个加法器增加PC的值以指向下条指令的地址。 图6-53存取指令需要两个状态单元,计算下条指令需要一个加法器 要执行任何一条指令,首先要从存储单元中将指令取出。 为准备执行下一条指令,也必须把程序计数器加到指向下条指令,即向后移动4个字节。 此时的数据通路,如图6-54所示,使用了图6-53中的3个部件。 图6-54用于取指和程序计数器增值的数据通路的一部分 现在讨论R型指令(参见图6-49)。 这种指令读两个寄存器,对它们的内容进行ALU操作,再写出结果。 我们将这类指令称为R型指令或算术逻辑指令(因为它们进行数学或逻辑运算)。 这个指令集合包括前面介绍的add、sub、slt、and、or和not指令。 这类指令的典型形式是addrt,rs1,rs2,它将读取rs1和rs2,并将结果写回到rt。 处理器的32个寄存器位于一个叫做寄存器堆(registerfile)的结构中。 寄存器堆即是寄存器集合,其中的寄存器都可通过指定相应的寄存器号来进行读写。 寄存器堆包含了计算机的寄存器状态。 另外,还需要一个ALU来对从寄存器读出的数值进行运算。 由于R型指令有3个寄存器操作数,对每条指令,都要从寄存器堆读出两个数据字,再写入一个。 为读出一个数据字,寄存器堆需要一个输入信号指定要读的寄存器号和输出信号指示从寄存器堆读出的结果。 为写入一个数据字,寄存器堆要有两个输入: 一个指定要写的寄存器号,另一个提供要写的数据。 寄存器堆总是根据输入的寄存器号输出相应的寄存器内容,而写操作由写控制信号控制,在写操作发生的时钟边沿,写控制信号必须是有效的。 这样,我们一共需要4个输入(3个寄存器号和1个数据)和两个输出(两个数据),如图6-55所示。 输入的寄存器号为5位,可指示32个寄存器中的某一个(25=32),一条输入总线和两条输出总线宽度均为32位。 图6-55中的ALU由3位控制信号控制,该ALU有两个32位输入,一个32位输出。 图6-55实现R型指令的ALU操作所需的两个状态单元: 寄存器堆和ALU 使用寄存器堆和图6-55中的ALU的R型指令的数据通路如图6-56所示。 因为寄存器号来自指令字段,我们将图6-54输出的指令与寄存器堆的寄存器号输入连在一起。 图6-56R型指令的数据通路 下面考虑SimpleRISC取数据指令和存储数据指令,其一般形式为: loadrt,rs,imm16或storers1,rs2,imm16 在这类指令中,通过将基址寄存器rs或rs2的内容与指令中的16位带符号偏移地址相加,得到存储器地址。 如果是存储数据指令,要从寄存器rs1中读出要存储的数据;如果是取数据指令,则要将从存储器中读出的数存入指定的寄存器rt中。 所以,图6-55中的寄存器堆和ALU都将被用到。 另外,还需要一个单元将16位的偏移地址符号扩展为32位的带符号值,以及一个存储读出和写入数据的单元。 存储单元在存储指令时被写入,所以它有读、写控制信号,地址输入和要被写入存储器的数据输入。 图6-57给出了这两个单元。 图6-57取数据指令和存储数据指令所需的两个单元: 数据存储器和符号扩展单元 图6-58显示了取指操作之后,所有上述单元如何构成取数据和存储数据指令的数据通路。 寄存器堆的寄存器号输入由指令提供,偏移量也是这样。 经过符号扩展,偏移量成为ALU的另一个输入。 图6-58加入取数据和存储数据指令之后的数据通路 beq指令有2个操作数,其中两个为寄存器,用于比较是否相等,另一个是16位偏移量,用以计算相对于分支指令所在地址的分支目标地址。 除了计算分支目标地址,还必须确定是顺序执行下一条指令,还是去执行分支目标地址处的指令。 当分支条件为真(即操作数相等)时,分支目标地址成为新的PC,我们就说实现了分支;若操作数不等,增值后的PC将取代当前PC(就像其他一般指令一样),这时就说没有实现分支。 所以,分支数据通路需要进行两个操作: 计算分支目标地址和比较操作数。 图6-59所示为分支数据通路。 图6-59分支指令的数据通路 为计算分支目标地址,分支目标通路包含了一个如图6-57所示的符号扩展单元和一个加法器。 为进行比较操作,要由图6-55的寄存器堆提供两个寄存器操作数(但不需要向寄存器堆写入数据)。 另外,比较操作由ALU完成。 无条件跳转指令将偏移地址的低26位左移两位后,以之代替PC的低28位(由于这里讨论的指令地址是字节地址,而实际的一条指令有4个字节,所以低两位指令地址无效)。 到此为止,我们已经讨论过单独的每种类型指令所需的数据通路,可以将它们合并成一个简单的数据通路,并且加上控制部分,以达到完整的实现。 6.3.6完整的数据通路 两个不同类型指令共享一个数据通路部件时,需要给部件连接多个输入,并设置控制信号以便在输入中进行选择。 这种选择通常由数据选择器来实现。 首先将图6-56所示的算术逻辑指令数据通路和图6-58所示的存储器指令的数据通路进行合并,得到如图6-60所示的数据通路。 图6-60算术逻辑指令和存储器指令的数据通路合并 图中,加入了一些数据选择器及相应的控制信号。 图6-61所示的是加入的取指部分的数据通路。 图6-61加入取指部分的数据通路 现在,加上图6-59所示的分支指令的数据通路,我们可以把所有部件加在一起建立起SimpleRISC处理器的一个简单数据通路。 图6-62给出了把独立部件连在一起之后得到的数据通路。 图6-62SimpleRISC处理器的数据通路 图中的指令和数据存储器使用总线接口单元BIU来进行连接。 在完成这个数据通路之后,可以加上控制单元。 控制单元接受指令输入,并产生每个状态单元的同步信号,每个数据选择器和ALU的控制信号。 加入控制单元后的数据通路如图6-63所示。 图6-63有控制单元的完整数据通路 6.3.7SimpleRISC处理器的实现 通过前面的介绍,我们知道SimpleRISC处理器需要设计如下子模块: (1)算术逻辑单元; (2)寄存器堆; (3)程序计数器; (4)总线接口单元; (5)控制器。 以下分别介绍各个模块的设计。 一、算术运算单元 算术逻辑单元根据输入的操作码,对两个源操作数进行算术逻辑运算,并产生相应的输出。 程序6-6是算术逻辑单元ALU的设计。 【程序6-6】 `timescale1ns/1ns moduleArithmeticLogicUnit( nReset,Clock,OperationCode, Source1,Source2,Destination ); inputnReset,Clock; input[3: 0]OperationCode; input[31: 0]Source1,Source2; output[31: 0]Destination; parameterADD=4'd0, SUB=4'd1, SLT=4'd2, SL=4'd3, SR=4'd4, AND=4'd5, OR=4'd6, NOT=4'd7, CMP=4'd8; reg[31: 0]Destination; always@(negedgenResetorposedgeClock) begin if(! nReset)Destination<=32'd0; else begin case(OperationCode) ADD: Destination<=Source1+Source2; SUB: Destination<=Source1-Source2; SLT: Destination<=(Source1 32'd1: 32'd0; SL: Destination<=Source1< 0]; SR: Destination<=Source1>>Source2[4: 0]; AND: Destination<=Source1&Source2; OR: Destination<=Source1|Source2; NOT: Destination<=~Source1; CMP: Destination
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 简单 RISC 处理器 设计