数字系统设计实验--流水线MIPS微处理器设计(完整版)资料.doc
-
资源ID:91695010
资源大小:3.78MB
全文页数:61页
- 资源格式: DOC
下载积分:12金币
快捷下载
![游客一键下载](/images/hot.gif)
会员登录下载
微信登录下载
三方登录下载:
微信扫一扫登录
友情提示
2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
|
数字系统设计实验--流水线MIPS微处理器设计(完整版)资料.doc
数字系统设计实验-流水线MIPS微处理器设计(完整版)资料(可以直接使用,可编辑 优秀版资料,欢迎下载)一、实验目的(1)了解提高CPU性能的方法。(2)理解数据冒险、控制冒险的概念以及流水线冲突的解决方法。(3)掌握流水线MIPS微处理器的工作原理。(4)掌握流水线MIPS微处理器的测试方法。二、实验任务设计一个32位流水线MIPS微处理器,具体要求如下设计要求:(1)至少执行下列MIPS32指令。 算数运算指令:ADD ADDU SUB SUBU ADDI ADDU 逻辑运算指令:AND OR NOR XOR ANDI ORI XORI SLT SLTI SLTU SLTIU 移位指令:SLL SLLV SRL SRLV SRA 条件分支指令:BEQ BNE BGEZ BGTZ BLEZ BLTZ 无条件跳转指令:J JR 数据传输指令:LW SW 空指令:NOP(2)在用5级流水线技术,对数据冒险实现转发或阻塞功能。(3)在XUP Vietex-II Pro开发系统中实现MIPS微处理器,要求CPU的运行速度大于25MHz.三、实验原理1.流水线MIPS CPU总体设计流水线是数字系统中一种提高系统稳定性和工作速度的方法,广泛应用在高档CPU的构建中。根据MIPS处理器指令的特点,将整体的处理过程分为取指令(IF)、指令译码、执行、存储器访问和寄存器写回五级,对应多周期CPU的五个处理阶段。如图1所示,一个指令的执行需要五个时钟周期,每个时钟周期上升沿来临时,此指令所代表的一系列数据和控制信息转移到下一级处理。图1 流水线流水作业示意图一条MIPS指令分为五个处理步骤,即五级流水线,的具体执行过程如图2所示。图2 五级流水线MIPS CPU初步原理框图流水线寄存器:为了在其它四级流水线中各条指令保持各自的值,从指令存储器中读出的指令必须保存在寄存器中。同样的方法应用到每个流水线步骤中,需要在上图中各级之间加入寄存器,如图3所示。图3.在各级分割线添加寄存器后的框图由于在流水线中,数据和控制信息将在时钟上升沿转移到下一级,所以规定流水线转移的变量命名遵守如下格式:名称_流水线级名称。例如,在ID级指令译码电路(DECODE)产生的寄存器写允许信号RegWrite在ID级、EX级、MEM级和WB级上的命名分别为RegWrite_id、RegWrite_ex、RegWrite_men和RegWrite_wb。在顶层文件中,类似的变量名称有近百个,这样的命名方式起到了很好的识别作用。1MIPS指令格式:R型指令格式 本实验需要实现的R型指令有:I)算术逻辑运算指令: ADD、ADDU、SUB、SUBU、AND、OR、NOR、 XOR 、SLT、SLTUII)移位指令:SLLV、SRLV、SRAV、SLL、SRL、SRAIII)寄存器跳转指令:JRI型指令格式本实验需要实现的I型指令有:I)存储器访问指令:LW、SWII)立即数算术逻辑运算指令:ADDI、ADDIU、ANDI、ORI、XORI、SLTI、SLTIUIII)分支指令:BEQ、BNE、BGEZ、BGTZ、BLEZ、BLTZ分支地址为:PC+4+(sign-extend(Imm)<<2)J型指令格式本实验需要实现的J型指令只有:无条件跳转指令:J跳转地址为:PC31:28,IR25:0,2b00特别注意:1、 寄存器跳转指令JR不是J型指令,而是R型指令,其指令格式为:跳转地址为:$ra,寄存器号为rs2、 移位指令SLL、SRL、SRA只有rt一个源操作数:3、取字指令的操作过程:rt <= Memrs+sign_extend(imm) 存字指令的操作过程: Memrs+sign_extend(imm) <= rt 4、I型指令中立即数算术逻辑运算指令对立即数(Imm)的处理应分为两类情况考虑: 当指令为ADDI、ADDIU、SLTI、SLTIU时,指令中的16位立即数(Imm)应做符 号扩展为32位。此符号扩展电路在ID级完成。 当指令为ANDI、ORI、XORI时,Imm应做“0”扩展为32位。考虑到资源的限制, 在执行ANDI、ORI、XORI指令时, “0”扩展功能放在ALU内部(即EX级)完成。2、 流水线中的控制信号 为保证CPU按照指令正常运行,分别设置各个级的控制信号:(1) IF级:取指令级。从ROM中读取指令,并在下一个时钟沿到来时把指令送到ID级的 指令缓冲器中。该级控制信号决定下一个指令指针的PCSource信号、阻塞流水线的PC_IFwrite信号、清空流水线的IF_flush信号。(2) ID级:指令译码器。对IF级来的指令进行译码,并产生相应的控制信号。整个CPU的控制信号基本都是在这级上产生。该级自身不需任何控制信号。流水线冒险检测也在该级进行,冒险检测电路需要上一条指令的MemRead,即在检测到冒险条件成立时,冒险检测电路产生stall信号清空ID/EX寄存器,插入一个流水线气泡。(3)EX级:执行级。该级进行算术或逻辑操作。此外LW、SW指令所用的RAM访问地址也是在本级上实现。控制信号有ALUCode、ALUSrcA、ALUScrB和RegDst,根据这些信号确定ALU操作、选择两个ALU操作数A、B,并确定目标寄存器。 另外,数据转发也在该级完成。数据转发控制电路产生ForwardA和ForwardB两组控制信号。(4)MEM级:存储器访问级。只有在执行LW、SW指令时才对存储器进行读写,对其他指令只起到一个周期的作用。该级只需存储器写操作允许信号MemWrite。(5)WB级:写回级。该级把指令执行的结果回写到寄存器文件中。该级设置信号MemtoReg和寄存器写操作允许信号RegWrite,其中MemtoReg决定写入寄存器的数据来自于MEM级上的缓冲值或来自于MEM级上的存储器。3、流水线冒险 在流水线CPU中,多条指令通知执行,由于各种各样的原因,在下一个时钟周期中下一条指令不能执行,这种情况称为冒险。冒险分为三类:结构冒险:硬件不支持多条指令在同一个时钟周期内执行。MIPS指令集专为流水线设计,因此在MIPS CPU中不存在此类冒险。数据冒险:在一个操作必须等待另一操作完成后才能进行时,流水线必须停顿,这种情况称为数据冒险。数据冒险分为两类:数据相关:流水线内部其中任何一条指令要用到任何其他指令的计算结果时,将导致数据冒险。通常可以用数据转发(数据定向)来解决此类冒险。数据冒险:此类冒险发生在当定向的目标阶段在时序上早于定向的源阶段时,数据转发无效。通常是引入流水线阻塞,即气泡(bubble)来解决。控制冒险:CPU需要根据分支指令的结果做出决策,而此时其他指令可能还在执行中,这时会出现控制冒险,也称为分支冒险。解决此类冒险的常用方法是延迟分支。3.1数据相关与转发下面通过具体例子来阐述数据相关。见图3.1图3.1 数据相关性后4条指令都依赖于第一条指令得到寄存器$2的结果,但sub指令要在第五周期才写回寄存器$2,但在第三、四、五个时钟周期$2分别要被and、or和add三个指令用到,所以这三个指令得到的是错误的未更新的数据,会引起错误的结果;而第六个时钟周期$2要被sw指令用到,此时得到的才是正确的已更新的数据。这种数据之间的互相关联引起的冒险就是数据相关。可以看出,当一条依赖关系的方向与时间轴的方向相反时,就会产生数据冒险。(1)一阶数据相关与转发(EX冒险)首先讨论指令sub与and之间的相关问题。sub指令在第五周期写回寄存器$2,而and指令在第四周期就对sub指令的结果$2提出申请,显然将得到错误的未更新的数据。像这类第I条指令的源操作寄存器与第I-1条指令(即上一条指令)的目标寄存器相重,导致的数据相关称为一阶数据相关。见图3.2中实线所示。 图3.2 一阶数据相关实例图可以发现,sub指令的结果其实在EX级结尾,即第三周期末就产生了;而and指令在第四时钟周期向sub指令结果发出请求,请求时间晚于结果产生时间,所以只需要sub指令结果产生之后直接将其转发给and指令就可以避免一阶数据相关。如图3.3虚线所示。转发数据为ALUResult_mem数据转发由Forwarding unit单元控制,判断转发条件是否成立。转发机制硬件实现见图3.3。图3.3 转发机制的硬件实现转发条件ForwardA、ForwardB作为数据选择器的地址信号,转发条件不成立时,ALU操作数从ID/EX流水线寄存器中读取;转发条件成立时,ALU操作数取自数据旁路。转发条件: MEM级指令是写操作,即RegWrite_mem=1; MEM级指令写回的目标寄存器不是$0,即RegWriteAddr_mem0; MEM级指令写回的目标寄存器与在EX级指令的源寄存器是同一寄存器,即RegWriteAddr_mem=RsAddr_ex 或 RegWriteAddr_mem=RtAddr_ex。(2)二阶数据相关与转发(MEM冒险)现在讨论sub指令与or指令之间的相关问题。sub指令在第5时钟周期写回寄存器,而or指令也在第5时钟周期对sub指令的结果提出了请求,很显然or指令读取的数据是未被更新的错误内容。这类数据相关称为二阶数据相关。见图3.4中实线所示。图3.4 二阶数据相关实例图如前所述,or指令在第五时钟周期向sub指令结果发出请求时,sub指令的结果已经产生。所以,我们同样采用“转发”,即通过MEM/WB流水线寄存器,将sub指令结果转发给or指令,而不需要先写回寄存器堆。如图3.4中虚线所示。转发数据为RegWriteData_wb转发条件: WB级指令是写操作,即RegWrite_wb=1; WB级指令写回的目标寄存器不是$0,即RegWriteAddr_wb0; WB级指令写回的目标寄存器与在EX级指令的源寄存器是同一寄存器,即RegWriteAddr_wb=RsAddr_ex 或 RegWriteAddr_wb=RtAddr_ex; EX冒险不成立,即RegWriteAddr_memRsAddr_ex 或 RegWriteAddr_mem=RtAddr_ex。(3)三阶数据相关与转发最后讨论sub指令与add指令之间的相关问题。sub指令与add指令在第五时钟周期内同时读写同一个寄存器。这类数据相关称之为三阶数据相关。如图3.5中实线所示。图3.5 三阶数据相关实例图假设寄存器的写操作发生在时钟周期的上升沿,而读操作发生在时钟周期的下降沿,那么读操作将读取到最新写入的内容。在这种假设条件下将不会发生数据冒险。这就要求流水线中的寄存器具有“先写后读(Read After Write)”的特性。这类“写操作发生在时钟周期的上升沿,读操作发生在时钟周期的下降沿”的寄存器虽然在理论上是可实现的,但是不适合应用于同步系统,因为它不但影响系统的运行速度,而且影响系统的稳定性,是不可取的。因此,我们采用“转发”机制来解决三阶数据相关冒险。该部分转发电路我们放在寄存器堆的设计中完成。如图3.5中虚线所示。转发数据为RegWriteData_wb。转发条件为: WB级指令是写操作,即RegWrite_wb=1; WB级指令写回的目标寄存器不是$0,即RegWriteAddr_wb0; WB级指令写回的目标寄存器与在ID级指令的源寄存器是同一寄存器,即RegWriteAddr_wb=RsAddr_id 或 RegWriteAddr_wb=RtAddr_id。3.2数据冒险与阻塞当一条指令试图读取一个寄存器,而它前一条指令是lw指令,并且该lw指令写入的是同一个寄存器时,定向转发的方法就无法解决问题。如图3.6所示这类冒险不同于数据相关冒险,需要单独一个“冒险检测单元(Hazard Detector)”,它在ID级完成。冒险成立的条件为: 上一条指令是lw指令,即MemRead_ex=1; 在EX级的lw指令与在ID级的指令读写的是同一个寄存器,即RegWriteAddr_ex=RsAddr_id 或 RegWriteAddr_ex=RtAddr_id。冒险的解决:引入流水线阻塞当Hazard Detector检测到冒险条件成立时,在lw指令和下一条指令之间插入阻塞,即流水线气泡(bubble),使后一条指令延迟一个时钟周期执行,这样就将该冒险转化为二阶数据相关,可用转发解决。如图3.7所示。图3.7 流水线气泡的引入需要注意的是,如果处于ID级的指令被阻塞,那么处于IF级的指令也必须阻塞,否则,处于ID级的指令就会丢失。防止这两条指令继续执行的方法是:保持PC寄存器和IF/ID流水线寄存器不变,同时插入一个流水线气泡。具体实现方法如下: 流水线气泡的插入:在ID级检测到冒险条件时, Hazard Detector输出一个信号:stall,将ID/EX流水线寄存器中的EX、MEM和WB级控制信号全部清零。这些信号传递到流水线后面的各级,由于控制信号均为零,所以不会对任何寄存器和存储器进行写操作。 保持PC寄存器和IF/ID流水线寄存器不变:在ID级检测到冒险条件时, Hazard Detector输出一个信号:PC_IFWrite,作为使能信号同时送给PC寄存器和IF/ID流水线寄存器。冒险成立时,该信号为低电平,禁止PC寄存器和IF/ID流水线寄存器接收新数据。3.3分支冒险还有一类冒险是包含分支的流水线冒险,下图。图3.8 分支冒险实例流水线每个时钟周期都得取指令才能维持运行,但分支指令必须等到MEM级才能确定是否执行分支。这种为了确定预取正确的指令而导致的延迟叫做控制冒险或分支冒险。一种比较普遍的提高分支阻塞速度的方法是假设分支不发生,并继续执行顺序的指令流。如果分支发生的话,就丢弃已经预取并译码的指令,指令的执行沿着分支目标继续。由于分支指令直到MEM级才能确定下一条指令的PC,这就意味着为了丢弃指令必须将流水线中的IF、ID和EX级的指令都清除掉(flush)。这种优化方法的代价较大,效率较低。如果我们能在流水线中提前分支指令的执行过程,那么就能减少需要清除的指令数。这是一种提高分支效率的方法,降低了执行分支的代价。因此我们采用提前分支指令的方法解决分支冒险。提前分支指令需要提前完成两个操作: 计算分支的目的地址:由于已经有了PC值和IF/ID流水线寄存器中的指令值,所以可以很方便地将EX级的分支地址计算电路移到ID级。我们针对所有指令都执行分支地址的计算过程,但只有在需要它的时候才会用到。 判断分支指令的跳转条件:我们将用于判断分支指令成立的Zero信号检测电路(Z test )从ALU中独立出来,并将它从EX级提前至ID级。具体的设计将在ID级设计中介绍。 在提前完成以上两个操作之外,我们还需丢弃IF级的指令。具体做法是:加入一个控制信号IF_flush,做为IF/ID流水线寄存器的清零信号。当分支冒险成立,即Z=1,则IF_flush=1,否则IF_flush=0,故IF_flush = Z。考虑到本系统还要实现的无条件跳转指令:J和JR,在执行这两个指令时也必须要对IF/ID流水线寄存器进行清空,因此, IF_flush的表达式应表示为:IF_flush = Z | J | JR。综合以上分析,最终的无冒险的流水线MIPS CPU原理框图如图3.9。图3.9 无冒险的流水线MIPS CPU总体原理框图 四、流水线MIPS微处理器的设计 根据流水线不同阶段,将系统划分为IF、ID、EX和MEM四大模块,WB部分功能电路非常简单,可直接在顶层文件中设计。另外,系统还包括IF/ID、ID/EX、EX/MEM、MEM/WB四个流水线寄存器。1、取指令级模块(IF)的设计IF模块由指令指针寄存器PC、指令存储器子模块Instruction ROM、指令指针选择器MUX和一个32位加法器组成,IF级模块接口信息如下表所示:引脚名称方向说 明clkInput系统时钟reset系统复位信号,高电平有效Z分支指令的条件判断结果J跳转指令JR寄存器跳转指令PC_IFWrite阻塞流水线的信号,低电平有效JumpAddr31:0J指令跳转地址JrAddr31:0JR指令跳转地址BranchAddr31:0条件分支地址Instruction_if31:0Output指令机器NextPC_if31:0下一个PC值(1) 指令存储器ROM用Xilinx CORE Generator实现产生的ROM无法满足流水线CPU的指令要求,我们需用Verilog HDL设计一个ROM阵列。考虑到FPGA的资源,指令存储器可设计为容量各为26×32bit的ROM。设计ROM时需将测试的机器码写入,课程提供一段简单测试程序的机器码,机器码存于PipelineDemo.coe文件中。课程已提供该ROM的代码,已设计好上述测试程序机器码的指令存储器,文件名为InstructionROM.v。(2) 指令指针选择器(PC)指令指针选择器为一8选1数据选择器,选择信号为PCSource=JR,J,Z,具体含义如下表:地址PC来源JR,J,Z= 100JR指令的跳转地址JR,J,Z= 010J指令的跳转地址JR,J,Z= 001Branch指令的分支地址JR,J,Z= 000下一条指令地址PC+4(3) PC寄存器当发生数据冒险时,需要保持PC寄存器不变,因此PC寄存器是一个带使能端的D型寄存器,使能信号为PC_IFWrite。2、指令译码模块(ID)的设计指令译码模块的主要作用是从机器码中解析出指令,并根据解析结果输出各种控制信号。ID模块主要有指令译码(Decode)、寄存器堆(Registers)、冒险监测、分支检测和加法器等组成。ID模块的接口信息如下表所示:引脚名称方向说 明clk Input系统时钟Instruction_id31:0 指令机器码NextPC_id31:0 指令指针RegWrite_wb 寄存器写允许信号,高电平有效RegWriteAddr_wb4:0 寄存器的写地址RegWriteData_wb31:0写入寄存器的数据MemRead_ex冒险检测的输入RegWriteAddr_ex4:0MemtoReg_idOutput决定回写的数据来源(0:ALU 1:存储器)RegWrite_id寄存器写允许信号,高电平有效MemWrite_id存储器写允许信号,高电平有效MemRead_id存储器读允许信号,高电平有效ALUCode_id4:0决定ALU采用何种运算ALUSrcA_id决定ALU的A操作数的来源(0:rs 1:Sa)ALUSrcB_id决定ALU的B操作数的来源(0:rt 1:Imm)RegDst_id决定Register回写是采用的地址(rt/rd)StallID/EX寄存器清空信号,高电平插入一个流水线气泡Z分支指令的条件判断结果J跳转指令JR寄存器跳转指令PC_IFWrite阻塞流水线的信号,低电平有效BranchAddr31:0条件分支地址JumpAddr31:0跳转地址Imm_id31:0符号扩展成32位的立即数Sa_id31:00扩展成32位的移位立即数RsData_id31:0Rs寄存器数据RtData_id31:0Rt寄存器数据RdAddr_id4:0Rd寄存器地址RsAddr_id4:0Rs寄存器地址RtAddr_id4:0Rt寄存器地址(1) 指令译码(Decode)子模块的设计Decode控制器的主要作用是根据指令确定各个控制信号的值,是一个组合电路。我们将指令分成八类:R_type1:ADD、ADDU、SUB、SUBU、AND、OR、NOR、XOR 、SLT、SLTU、SLLV、SRLV、SRAV R_type2:SLL、SRL、SRA JR_type:JRJ_type:J I_type:ADDI、ADDIU、ANDI、ORI、XORI、SLTI、SLTIUBranch:BEQ、BNE、BGEZ、BGTZ、BLEZ、BLTZ LW:LWSW:SWDecode输出的九组控制信号: RegWrite决定是否对寄存器(Registers)进行写操作。当RegWrite高电平有效时,将数据写入指定的寄存器中。需要写回寄存器的指令有:LW、R_type1、R_type2和I_type,则RegWrite_id= LW | R_type1 | R_type2 | I_type RegDst决定目标寄存器是rt还是rd。当RegDst=0时,rt为目标寄存器;当RegDst=1时,rd为目标寄存器。需要写回寄存器的指令类型有:LW、R_type1、R_type2和I_type。其中, R_type1和R_type2的目标寄存器是rd,而LW和I_type的目标寄存器是rt。所以:RegDst_id= R_type1 | R_type2 MemWrite决定是否对数据存储器进行写操作。当MemWrite有效时,将数据写入数据存储器指定的位置。需要对写存储器的指令只有SW,所以:MemWrite_id= SW MemRead决定是否对数据存储器进行读操作。当MemRead有效时,读取数据存储器指定位置的数据。需要对读存储器的指令只有LW,所以:MemRead_id= LW MemtoReg决定写入寄存器(registers)的数据来自ALU还是数据存储器。当MemtoReg=0时,数据来自ALU;当MemtoReg=1时,数据来自数据存储器。需要写回寄存器的指令类型有:LW、R_type1、R_type2和I_type。其中,只有LW写回寄存器的数据取自存储器,所以:MemtoReg_id= LW ALUSrcA决定ALU第一操作数来源。当ALUSrcA=0时,ALU第一操作数A(详见转发电路设计);当ALUSrcA=1时,ALU第一操作数来源于0扩展的用于移位指令的5位sa。八种指令类型中J_tpye、JR_tpye及Branch类型指令没有使用ALU;其他使用ALU的指令类型中LW、SW、R_type1和I_type均采用的rs作为ALU第一操作数,只有R_type2的第一操作数采用的是0扩展的sa,所以:ALUSrcA_id= R_type2 ALUSrcB决定ALU第二操作数来源。当ALUSrcB=0时,ALU第二操作数B。当ALUSrcB=1时,ALU第二操作数来源于符号扩展的16位Imm。八种指令类型中J_tpye、JR_tpye及Branch类型指令没有使用ALU。其他使用ALU的指令类型中R_type1和R_type2 采用rt作为ALU第二操作数,而LW、SW、I_type的第二操作数采用的是符号扩展的立即数Imm段,所以:ALUSrcB_id= LW | SW | I_type PCSource决定写入PC寄存器的来源。PCSource由JR_tpye 、J_tpye及Z决定:即:PCSource=JR, J, ZPCSource=000时, 写入值为下一条指令的地址PC+4;PCSource=001时, 写入值为Branch指令的分支地址;PCSource=010时,写入值为J指令的跳转地址;PCSource=100时,写入值为JR指令的跳转地址。 ALUCode决定ALU的功能,由指令中的op段、rt段和funct段决定。功能表如下:opfunctionrt运算ALUcodeBEQ_opxxxxxxxxxxZ=(A=B)5'd10BNE_opxxxxxxxxxxZ=(A=B)5'd11BGEZ_opxxxxx5'd1Z=(A>=0)5'd12BGTZ_opxxxxx5'd0Z=(A>0)5'd13BLEZ_opxxxxx5'd0Z=(A<=1)5'd14BLTZ_opxxxxx5'd0Z=(A<0)5'd15R_type_opADD_functxxxxx加5'd0ADDU_functxxxxxAND_functxxxxx与5'd1XOR_functxxxxx异或5'd2OR_functxxxxx或5'd3NOR_functxxxxx或非5'd4SUB_functxxxxx减5'd5SUBU_functxxxxxSLT_OP_functxxxxxA<B? 1:05'd19SLTU_OP_functxxxxxA<B? 1:0(无符号数)5'd20SLL_functxxxxxB>>A5'd16SLLV_funct5、TCP/IP协议参考模型共分了_4_层,其中3、4层是_传输层_、_运用层_。xxxxx6、电子邮件系统提供的是一种_存储转发式_服务,WWW服务模式为_B/S_。SRL_functxxxxxB<<A5'd17SRLV_funct*方法3xxxxxD. 类可以按所定义的属性、事件和方法进行实际的行为操作SRA_funct32. 视图不能单独存在,它必须依赖于_。xxxxxB>>>A主程序的输出结果:5'd18ARAV_funct32、SMTPxxxxxADDI_opxxxxxxxxxx加5'd0ADDIU_opxxxxxxxxxxANDI_opxxxxxxxxxx与5'd1XORI_opxxxxxxxxxx异或5'd2ORI_opxxxxxxxxxx或5'd3SLTI_opxxxxxxxxxxA<B? 1:05'd19SLTIU_opxxxxxxxxxxA<B? 1:0(无符号数)5'd20SW_opxxxxxxxxxx加(计算地址)5'd0LW_opxxxxxxxxxx(2) 分支检测(Branch Test)电路的设计Zero检测电路主要用于判断Branch指令的分支条件是否成立,其中BEQ、BNE两个操作数为RsData与RtData,而BGEZ、BGTZ、BLEZ和BLTZ指令则为RsData与常数0比较,所以输出信号Z的表达式为:RsData31 | (| RsData31: 0) ; ALUCode=alu _blezRsData31 ; ALUCode=alu _bltz RsData31 && (| RsData31: 0) ; ALUCode=alu _bgtzZ= RsData31; ALUCode=alu _bgez| ( RsData31: 0 RtData31: 0) ; ALUCode=alu_bne& ( RsData31: 0 RtData31: 0 ); ALUCode=alu_beq0; ALUCode=OTHER(3) 寄存器堆(Registers)子模块的设计寄存器堆由32个32位寄存器组成,这些寄存器通过寄存器号进行读写存取。寄存器堆的原理框图如下图所示。因为读取寄存器不会更改其内容,故只需提供寄存号即可读出该寄存器内容。读取端口采用数据选择器即可实现读取功能。应注意“0”号寄存器为常数0.对于往寄存器里写数据,需要目标寄存器号(WriteRegister)、待写入数据(WriteData)、写允许信号(RegWrite)三个变量。图3.13中5位二进制译码器完成地址译码,其输出控制目标寄存器的写使能信号EN,决定将数据WriteData写入哪个寄存器。在流水线CPU设计中,寄存器堆设计还应解决三阶数据相关的数据转发问题。当满足三阶数据相关条件时,寄存器具有Read after Write的特性。为实现该功能,在寄存器堆的基础上加一转发电路。如下图所示。图中转发检测电路的输出表达式为RsSel=RegWrite_wb&&(RegWriteAddr_wb=0)&&(RegWriteAddr_wb=RsAddr_id)RtSel=RegWrite_wb&&(RegWriteAddr_wb=0)&&(RegWriteAddr_wb=RtAddr_id)(4) 冒险检测功能电路(Hazard Deterctor)的设计冒险成立的条件为: 上一条指令是LW指令,即MemRead_ex=1; 在EX级的LW指令与在ID级的指令读写的是同一个寄存器,即RegWriteAddr_ex=RsAddr_id 或 RegWriteAddr_ex=RtAddr_id解决冒险的方法为: 插入一个流水线气泡Stall清空ID/EX寄存器并且阻塞流水线ID级、IF级流水线,有:Stall=(RegWriteAddr_ex=RsAddr_id)|(RegWriteAddr_ex=RtAddr_id)&&MemRead_ex 保持PC寄存器和IF/ID流水线寄存器不变,有:PC_IFWrite=Stall(5) 其它单元电路的设计 Branch指令分支地址的计算电路:BranchAddr=NextPC_id+(sign-extend(Imm_id)<<2) JR指令跳转地址的计算电路:JRAddr=RsData_id J指令跳转地址的计算电路:Jaddr=NextPC_id31:28,IR_id25:0,2b00 符号扩展的方法针对有符号数 如果最高位(即符号位)是0,则要扩展的高位用0补齐;如果最高位是1,则用1补齐。 例: 8位的+1,表示为二进制为,扩展成16 0扩展的方法针对无符号数 要扩展的高位用0补齐。 例:16位二进制0xFFFF, 0扩展成32位为0x0000FFFF。3、执行模块(EX)的设计执行模块主要有ALU子模块、转发电路Forwarding以及若干数据选择器组成。这行模块的接口信息如下表所示:引脚名称方向说 明RegDst_exInput决定Register回写时采用的地址(rt/rd)ALUCode_ex4:0决定ALU采用何种运算ALUSrcA_ex决定ALU的A操作数的来源(rs/Sa)ALUSrcB_ex决定ALU的B操作数的来源(rt/Imm)Imm_ex31:0立即数Sa_ex31:0移位位数RsAddr_ex4:0Rs寄存器地址,即Instruction_id25:21RtAddr_ex4:0Rt寄存器地址,即Instruction_id20:16RdAddr_ex4:0Rd寄存器地址,即Instruction_id15:11RsData_ex31:0Rs寄存器数据RtData_ex31:0Rt寄存器数据RegWriteData_wb31:0写入寄存器的数据ALUResult_mem31:0ALU输出数据RegWriteAddr_wb4:0寄存器的写地址RegWriteAddr_mem4:0RegWrite_wb寄存器写允许信号RegWrite_memRegWriteAddr_ex4:0Output寄存器的写地址ALUResult_ex31:0ALU运算结果MemWriteData_ex31:0寄存器的回写数据ALU_A31:0ALU操作数,测试时使用ALU_B31:0(1) ALU子模块的设计ALU是提供CPU基本运算能力的重要电路。ALU执行何种运算,由控制单元中的ALU控制器输出的ALUCode信号决定。ALU功能见下表:为了提高运算速度,可将各种运算同时执行,得到的运算结果由ALUCode信号进行挑选。ALU的基本结构如下图所示。 加、减电路的设计考虑减法、比较(SLT、SLTI)均可用加法器和必要的辅助电路来实现。上图中的Binvert信号控制加减运算:Binvert=(ALUCode=alu_add)对ALU来说,它的两个操作数输入时都已经是补码形式,当要完成两个操作数的 减法时,即A补-B补,可将减法转换为加法,利用加法器来实现:A补-B补= A补+(-B补)= A补+(B补)补= A补+(B补)反+1 加法器完成的功能为:sum=A+B32Binvert+Binvert当Binvert=0时,sum=A+B0+0= A+B;当Binvert=1时,sum=A+B32b1+1= A-B;(B32b1即对B按位取反)即可完成加减运算。由于32位加法器的运算速度