0
点赞
收藏
分享

微信扫一扫

从流水线角度看MIPS处理器ISA的实现逻辑以及RTOS操作系统仿真


MIPS最终还是失败了,最可惜的是, 它既不是败给了对手,也不是败给了技术,而是败给了自己,败给了市场。MIPS的失败充分说明了,人美活儿好不一定能混好,MIPS作为一项处理器的设计技术是顶级的,但是它不识时务,忽视市场变化,几经贱卖,最终沦落到不得不放弃MIPS架构,转头火热的RISCV阵营.曾几何时,风光无两的MIPS是X86服务器的主要挑战者,也曾为RISC阵营扛起过大旗。但风云变幻,三十年河东,三是年河西,曾经的小弟ARM,RISCV,一个成为包括手机在内的移动电子设备的核心部件,另一个在IOT芯片领域做的风生水起.MIPS作为曾经的RISC老大哥的处境,让人唏嘘。

不过,从软件开发的角度,RISCV和MIPS还是很像的,个人感觉它们ISA的相似度至少有90%. RISCV继承了MIPS指令集设计的优雅,辨识度高,设计对称的特点,基本上你认识一半的指令,另一半仅靠猜测就可以识别了,  大大降低了汇编程序员的认知负担。现在写一点儿关于MIPS处理器应用的相关记录文章,一方面是为了小小纪念一下曾经使用了六年的MIPS,虽然学的并不好,另一方面,在RISCV的学习中,MIPS的设计思路也有非常好的借鉴意义。

MIPS架构一路走来,历经风雨,指令集总共经历了六版迭代,如下图所示:

从流水线角度看MIPS处理器ISA的实现逻辑以及RTOS操作系统仿真_人工智能

指令集ISA

MIPS属于精简指令集RISC,精简指令集是通过定义大量的寄存器和非常规则的指令流水线来简化设计,每条指令所需始终周期数(CPI)较少。RISC中的一大特点是广泛使用load/store架构,在load/store架构下,内存访问必须通过特定指令进行,而不是作为指令集中大部分指令的一部分。而在X86体系架构下,大部分的数据移动指令和算数指令也可以进行内存访问,比如:ADD/SUB/MOV/JMP指令等X86下的指令,均可以直接访问存储器。功能指令和访存之间的解耦是RISC指令集的一大特点。

MIPS的失败不是因为指令集不够好,实际上,曾经有位大佬指出,争论指令集是一个非常悲伤的事,无论那种架构,百分之八十的核心指令和只有六条,分别是加载(Load),存储(Store),加(Add),减(Subtract), 比较(Compare)和分支跳转(Branch).这是因为,要构成图灵完备的逻辑,执行流支持三种基本结构,分别是:

顺序结构:通过PC指针的顺序加减实现。

选择分支结构:通过逻辑比较指令和跳转指令实现。

循环结构:通过调准指令实现。

以上六条指令能够完全cover上面的三种执行流。

RISCV指令格式有六种,包括R-type, I-type, S-type, B-type, U-type, J-type. 而MIPS只有三种,分别是R-Type,J-Type,I-Type.

MIPS I-Type的五级流水线如下所示:

I-type指令,有三种类型比如:

运算指令: 例如ori rt, rs, imm16

load/store指令:例如lw rt, rs, imm16

条件分支指令:beq rs, rt, imm16

从流水线角度看MIPS处理器ISA的实现逻辑以及RTOS操作系统仿真_目标检测_02

蓝色的部分是时序逻辑,主要是触发器逻辑,用来保存每一级计算的中间结果,它受到时钟信号的驱动,逐级传递.中间是组合逻辑,它的输入来源于上一级的时序逻辑输出部分,经过组合逻辑计算后,将输出送到下一级的时序逻辑输入口.

对于I-type的指令,每一级流水线完成的功能如下:

fetch instruction:取出指令存储器中的指令,PC值递增,准备取下一条指令.

decode:对指令进行译码,根据译码结果,从32个通用寄存器中取出源操作数,有的指令要求两个源操作数都是寄存器的值,比如or指令,有的指令要求其中一个源操作数是指令中立即数的扩展,比如ori指令,所以decode阶段有两个muxer,用于依据指令要求,确定参与运算的操作数,最终确定的两个操作数会送到执行阶段.总结一下,对任意指令而言,译码工作的主要内容是,确定要读取的寄存器情况,要执行的运算,和要写的目的寄存器等三个方面的信息.

execute:依据译码阶段送入的源操作数,操作码,进行运算,这个阶段需要ALU单元的参与,对于ori指令而言,就是在ALU单元中进行逻辑"或"运算,运算结果传递到访存阶段,对于load/store,要进行地址的计算操作.

memory:对于ori指令,在访存阶段没有任何操作,运算结果在这里呆一个时钟周期,会传递到回写阶段,对于访存类指令,这里要进行访问存储器的操作.

writeback:将运算结果保存到目的寄存器.

为了解决指令中出现的RAW相关,将执行阶段的运算结果前递给译码阶段,访存阶段的前递是为了应对装载指令相关的RAW相关.

从流水线角度看MIPS处理器ISA的实现逻辑以及RTOS操作系统仿真_寄存器_03

加入了HI,LO寄存器和HI,LO寄存器访存,回写阶段数据前递的数据流图,HI,LO是寄存器,只是它们不能在MIPS指令的5位寄存器字段中编码。这些“已编号”的寄存器通过特殊的指令识别,属于特殊寄存器,用来存放乘除的结果.

在整个流水线中,除了regfile模块和HI.LO模块中由于写入操作引入了时钟信号外,其它阶段都是组合逻辑,不需要始终信号.尤其是ALU单元,进行的纯粹的组合逻辑数学计算.甚至指令ROM都不需要时钟驱动,因为它本身是只写的.在openmips流水线里面,ROM读操作是不需要时钟驱动的.

从流水线角度看MIPS处理器ISA的实现逻辑以及RTOS操作系统仿真_指令集_04

如同寄存器文件一样,HI,LO寄存器的读是组合逻辑,但是写是时序逻辑,需要一个使能位和时钟触发,所以也需要在回写阶段的写口前进行前递,这里的实现逻辑如下:

Regfile前递:

从流水线角度看MIPS处理器ISA的实现逻辑以及RTOS操作系统仿真_深度学习_05

从流水线角度看MIPS处理器ISA的实现逻辑以及RTOS操作系统仿真_人工智能_06

HI,LO数据前递.

从流水线角度看MIPS处理器ISA的实现逻辑以及RTOS操作系统仿真_深度学习_07

在decode instruction阶段,完整的4字节指令编码便会转换为各种控制信号和数据产生信号,后续流水线阶段不会在出现这条完整的指令编码,但由它产生的各种电信号,时时刻刻影响着整条流水线.所以,你可以看到,在id.v文件里面没有clk输入,但是在regfile.v和hilo.v中需要用时钟信号作为输入.

下一步,增加一个muxer,用来确定PC值,PC值在下一个时钟周期的值可以是PC+4,也可以保持当前值不变,后者对应的就是流水线暂停的情况.

从流水线角度看MIPS处理器ISA的实现逻辑以及RTOS操作系统仿真_深度学习_08

流水线暂停的情况发生在执行阶段需要多个时钟周期才能完成的情况下,比如MACs乘累加和除法操作,尤其是除法,需要较多的时钟周期才能完成,这个时候,需要发出freeze信号(也叫stall信号),冻结执行流水线阶段之前的阶段的推进,等执行阶段完成之后,在继续流水线.

下图是增加了跳转指令逻辑的流水线结构:

增加了跳转逻辑的支持后,PC muxer多了一条输入信号,它代表转移判断的结果,如果是转移指令,且满足转移条件,那么会通过这条路径将转移的目标地址赋给PC.

从流水线角度看MIPS处理器ISA的实现逻辑以及RTOS操作系统仿真_指令集_09

为了实现数据加载/存储指令,修改数据流图如下所示,主要是在访存阶段增加了对数据存储器SRAM的访问,同时,由于要写入目的寄存器的数据可能是执行阶段的结果,也可能是在访存阶段从数据存储器RAM加载得来的数据,所以在访存阶段增加了一个多路选择器,进行选择.

从流水线角度看MIPS处理器ISA的实现逻辑以及RTOS操作系统仿真_目标检测_10

增加LLBit寄存器的数据流,用来实现链接加载,存储指令(LL,SC)后的流水线:

注意,这里可能还有一些问题,由于sc判断发生在访存阶段,而LLBit的引入之值是基于LLBIt寄存器中的值,这两个中间相隔了两个时钟周期(访存->回写以及LLBIT的写时序),所以如果sc指令紧挨ll指令的情况下,会有一些问题.

从流水线角度看MIPS处理器ISA的实现逻辑以及RTOS操作系统仿真_目标检测_11

增加了协处理CP0的数据流图,在回写阶段增加了CP0模块,并且CP0模块的输出数据传递到执行阶段,用于确定最后参数运算的操作数,比如,mfc0指令在执行极端就会选择从CP0传递过来的数据,作为运算结果,写入目的寄存器.

从流水线角度看MIPS处理器ISA的实现逻辑以及RTOS操作系统仿真_人工智能_12

添加异常处理后的数据流图如下图所示:在访存阶段增加了异常判断模块,主要作用是依据从译码,执行阶段传递过来的信息,以及CP0中寄存器的值,判断是否要处理异常,如果要处理异常,那么按照异常类型给出新的指令地址送入PC.时钟和复位信号存在的目的是,更新PC,回写寄存器,以及访存都需要时钟,而上电复位则需要RST信号,让PC从一个ISA设定的地址开始执行。

从流水线角度看MIPS处理器ISA的实现逻辑以及RTOS操作系统仿真_寄存器_13

异常处理

异常产生的来源包括外部事件,指令执行中的错误,数据完整性(ECC),地址转换异常,系统调用和陷入,以及软中断辅助的浮点计算等等,在流水线处理中,这些不同类型的异常可能在流水线的不同阶段产生,例如访存地址错误异常发生在取址阶段和访存阶段,系统调用异常和非法指令异常发生在译码阶段,溢出异常发生在执行阶段,而中断由于是异步的,随时可能发生。

从流水线角度看MIPS处理器ISA的实现逻辑以及RTOS操作系统仿真_寄存器_14

为了实现MIPS精确异常,必须要求异常发生的顺序与指令顺序相同,在非流水线的处理器上,这一点是显然的,但是对于拥有流水线的处理器,就会有些复杂,在流水线处理器上,指令不同,异常会在流水线的不同阶段发生,带来潜在问题,比如,syscall指令在指令译码阶段便会产生异常信号,而装载指令在访存阶段才会发生地址不对齐的异常,如果代码顺序是:

lw  t0, 0x04(t1)

syscall

syscall位于lw指令后面第一条指令,如果按照产生异常信号产生的时间来处理异常,syscall处于译码阶段时,lw指令还没有进行访存处理,便会发生后面的指令(syscall)先于前面指令(lw)进行异常处理的情况,这是错误的.为了避免上述情况,先发生的异常并不立即处理,异常事件只是被标记,并继续运行流水线,在大多数处理器中,会设计一个特殊的流水线阶段,专门用于处理异常,如果能够保证任何阶段流水线中的异常在这个阶段之前都可以被发现了,那么就能够保证指令顺序和异常顺序保持一直的原则,最终可以保证,指令按照执行的顺序处理异常,而不是按异常发生的顺序处理异常.

一个RTOS系统仿真的实例,最下面的时钟中断信号周期发生, 仿真需要事先安装 iverilog, vvp,gtkwave三个工具(apt-get install iverilog,apt-get install gtkwave).

从流水线角度看MIPS处理器ISA的实现逻辑以及RTOS操作系统仿真_指令集_15

多发射

英文ISSUE在计算机体系结构中,被翻译为发射,或者流出,它是指这种阶段,指令译码后,并不一定有条件执行,当从执行停滞到执行这个过程发生的时候,就认为是指令发射(流出)。

上面的例子是单发射5级流水的设计,为了降低CPI(cycle per instruction),最直观的方法就是让处理器中每级流水线都可以同时处理更多的指令,这叫做多发射技术,例如双发射流水线意味着每一拍用PC从指令存储器中取两条指令,在译码级同时进行两条指令的译码,读源寄存器的操作,执行阶段同时执行两条指令的运算操作和访存操作,并同时回写两条指令的结果i,这样CPI就从1降为0.5.

要在处理器中支持多发射,首先就要将处理器中的各种资源翻倍,包括采用支持双端口的存储器,其次还要增加额外的阻塞判断逻辑,当同一个时钟周期执行的两条指令存在指令相关是,也需要进行阻塞,包括数据相关控制相关和结构相关在内的阻塞机制都要略微改动。

总结:

在处理器发展历史上,MIPS 公司的处理器曾经是唯一能覆盖从高性能计算(HPC) 到嵌入式领域的指令集架构,在市场上得到广泛应用。在 ARM 建立起移动互联网领域生态后,MIPS 指令集生态环境受到了极大冲击,即使在 MIPS 的传统优势领域也逐渐被 ARM 处理器取代.MIPS 架构处理器在大部分行业应用中的市场份额处于下降趋势, 即使在 MIPS 架构的传统优势领域,比如机顶盒、打印机控制器、WIFI 路由器、 网络处理器等,也已经逐步被 ARM 架构的处理器所取代。 从已有信息来看,自 2014 年 MIPS Release 6 发布以来,除 MIPS 公司自己 的 Warrior 产品系列之外,尚无第二个实现 MIPS Release 6 指令集的芯片,这说明IP也卖不动了。

从流水线角度看MIPS处理器ISA的实现逻辑以及RTOS操作系统仿真_深度学习_16

结束!

举报

相关推荐

0 条评论