第五章逻辑、移位操作与空指令的实现

上一章建立了原始的OpenMIPS五级流水线结构,但是只实现了一条ori指令,从本章开始,将逐步完善。本章首先讨论了流水线数据相关问题,然后修改OpenMIPS以解决问题。接着对逻辑、移位操作和空指令的指令格式、用法进行了一一说明。

5.1流水线数据相关问题

流水线中经常有一些被称为“相关”的情况发生,它使得指令序列中下一条指令无法按照设计周期执行,这些“相关”会降低流水线的性能,流水线中的相关分为以下三种类型。
  • 结构相关:在指令执行过程中,由于硬件资源满足不了指令执行的要求,发生硬件资源冲突而产生的相关。比如:指令和数据都共享一个存储器,,在某个时钟周期,流水线既要完成某条指令对存储器的数据的访问操作,又要完成后续的取指令操作,这样就会发生存储器访问冲突,产生结构相关。
  • 数据相关:指的是在流水线中执行的几条指令中,一条指令依赖于前面的指令的执行结果
  • 控制相关:流水线中的分支指令或者其他需要改写PC的指令造成的相关。
本章重点讨论数据相关的问题。流水线数据相关又分为三种情况:RAW、WAR、WAW.
  • RAW:即Read After Write,假设指令j是在指令i后面执行的指令,RAW表示指令i将数据写入寄存器后,指令j才能从这个寄存器读取数据。如果指令j在指令i写入寄存器前尝试读出该寄存器的内容,得到不正确的数据。
  • WAR:即Write After Read,假设指令j是在指令i后面指令的指令,WAR表示指令i读出数据后,指令j才能写这个寄存器。如果指令j在指令i读取数据前就写入该寄存器,将使得指令i读出的数据不正确。
  • WAW:即Write After Write,假设指令j是在指令i后面执行的指令,WAW表示指令i将数据写入寄存器后,指令j才能将数据写入这个寄存器。如果指令j在治疗i之前写入该寄存器,将使得该寄存器的值不是最新值。

从ori指令的实现过程可以知道,只有在流水线的回写阶段才会写寄存器(实际上,其他指令也是一样的,在后面实现其余指令时,会更清楚),因此不存在WAW相关,又因为只能在流水线译码阶段读寄存器、回写阶段写寄存器,不存在WAR相关,所以在OpenMIPS流水线只存在RAW相关。RAW相关有三种情况。

  • 相邻指令间存在数据相关
    考虑如下代码
    在这里插入图片描述奥,对啦还记得ori(上面的图片上是啥意思吗),是把$0和0x1100(零扩展后)执行逻辑“或”运算。存在寄存器$1内哦,要记得温故而知新~~

第一条ori指令将会写寄存器$1,随后的第2条ori指令需要读出$1的数据,但是第1条ori指令在回写阶段才会将其运算结果写入$1,而第二条ori指令在译码阶段就要读取$1的值,此时第一条ori指令还处于执行阶段,所以得到的必然不是第一条ori指令计算得出的结果,这种被称为相邻指令间存在数据相关,也可称为流水线译码、执行阶段存在数据相关。
在这里插入图片描述

  • 相隔1条指令间存在数据相关
    考虑如下代码
    在这里插入图片描述
    第一条ori指令将写寄存器$1,第三条ori指令在译码阶段需要读取寄存器$1,此时第一条ori指令还在访存阶段,所以得到的必然也不是正确的值。这种情况可以称为相隔1条指令的指令间存在数据相关,针对OpenMIPS的具体情况,也可以称为流水线译码、访存阶段存在数据相关。
    在这里插入图片描述

  • 相隔2条指令的指令间存在数据相关

考虑如下代码
在这里插入图片描述第一条ori指令将写寄存器$1,第四条ori指令在译码阶段需要读取寄存器$1,此时第一条指令处在回写阶段,在回写阶段最后的时钟上升沿才会将运算结果写入$1,所以第四条ori指令得到的不是正确的寄存器$1的值,这种情况可以称为相隔2条指令间存在数据相关,针对OpenMIPS的具体情况,也可称为流水线译码、回写阶段存在数据相关。
在这里插入图片描述

其中相隔2条指令存在数据相关(即流水线译码、回写阶段存在数据相关)这种情况,在第四章设计的Regfile模块中得到了解决。代码如下:在这里插入图片描述

在读操作中有一个判断,如果要读取的寄存器是在下一个时钟上升沿要写入的寄存器,那么就要将写入的数据直接作为结果输出,如此解决了相隔2条存在数据相关的情况。

对于相邻指令间存在数据相关、相隔1条指令存在数据相关这两种情况,有三种解决方案

  1. 插入暂停周期:当检测到相关时,在流水线中插入一些暂停周期。
    在这里插入图片描述

  2. 编译器调度:编译器检测到相关后,可以改变部分指令的执行顺序。
    在这里插入图片描述

  3. 数据前推:将计算结果从其产生处直接送到需要处或所有需要的功能单元处,避免流水线暂停。如图所示,新的$1的值实际上在第一条ori指令的执行阶段已经算出来了,可以直接将其值从第一条ori指令的执行阶段送到第二条ori指令的译码阶段,从而使得第2条ori指令在译码阶段得到$1的新值,也可以将该值从第一条ori指令的访存阶段送入到第3条指令的译码阶段,从而使得第三条ori指令在译码阶段也可以得到新的$1的新值。
    在这里插入图片描述
    此方法的前提是新的寄存器的值可以在执行阶段计算出来,如果是加载指令,就不满足,因为加载指令在访存阶段才能获得最终结果,这是一种load相关,后面会考虑到,本章不考虑。

5.2 OpenMIPS对数据相关问题的解决措施

OpenMIPS处理器采用数据前推的方法来解决流水线数据相关问题,通过补充原始数据流图,添加部分信号可以完成数据前推的工作,如图所示,主要是将执行阶段的结果、访存阶段的结果前推到译码阶段,参与译码阶段选择运算源操作数的过程。在这里插入图片描述
为实现数据前推而对OpenMIPS系统结构所作的修改,具体有两个方面。

在这里插入图片描述在这里插入图片描述
为此,译码阶段的ID模块要增加如表所示的接口。
在这里插入图片描述除了修改译码阶段ID模块的代码,还要修改顶层模块OpenMIPS对应的代码,增加逻辑关系。

(书上的代码是一半一半那种,为了保持整齐度,我把代码最后全部整理出来给各位下载)

5.3测试数据相关问题的解决效果

在这里插入图片描述在这里插入图片描述

5.4逻辑、移位操作与空指令说明

MIPS32指令集架构中定义的逻辑操作指令有8条:and、andi、or、ori、xor、xori、nor、lui,其中ori指令已经实现了本章要实现其余的7条指令。
MIPS32指令集架构中定义符任移位操作指令有6条:sll,sllv,sra,srav,srl,srlv.
MIPS32指令集架构中定义的空指令有2条:nop、ssnop,其中ssnop是一种特殊类型的空操作,在每个周期发射多条指令的CPU中,使用ssnop指令可以确保单独占用一个发射周期。OpenMIPS设计为标量处理器,也就是每个周期发射一条指令,所以ssnop的作用与nop相同,可以按照nop的指令的处理方式来处理ssnop指令。
另外,MIPS32指令集架构中还定义了sync、pref这两条指令,其中sync指令用于保证加载、存储操作的顺序,对于OpenMIPS而言,是严格按照指令顺序执行的,加载、存储操作也是按照顺序进行的,所以可以将sync指令当作nop指令处理,在这里归纳其为空指令。pref指令用于缓存预取,OpenMIPS没有实现存储,所以也可以将pref指令当作nop指令处理,此处也可以归纳为空指令。
  • and、or、xor、nor
    这四条指令的格式如图所示,这四条指令都是R类型指令,并且指令码都是6’b000000,也就是MIPS32指令集架构中定义的SPECIAL类,此外,第6-10bit都为0,需要依据指令中第0-5bit功能码的值进一步判断是哪一种指令。
    在这里插入图片描述

  • 当功能码是6’b100100时,表示and指令,逻辑“与”运算。
    指令用法为: and rd,rs,rt。
    指令作用为:rd<-rs AND rt,将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值进行逻辑“与”运算,运算结果保存到地址为rd的通用寄存器中。

  • 当功能码是6’b100101时,表示or指令,逻辑“或”运算。
    指令用法为: or rd,rs,rt。
    指令作用为:rd<-rs OR rt,将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值进行逻辑“或”运算,运算结果保存到地址为rd的通用寄存器中。

  • 当功能码是6’b100110时,表示xor指令,异或运算。
    指令用法为: xor rd,rs,rt。
    指令作用为:rd<-rsXOR rt,将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值进行逻辑“异或”运算,运算结果保存到地址为rd的通用寄存器中。

  • 当功能码是6’b100111时,表示是nor指令,或非运算。
    指令用法为: nor rd,rs,rt。
    指令作用为:rd<-rs NOR rt,将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值进行逻辑“或非”运算,运算结果保存到地址为rd的通用寄存器中。
    2.andi、xori指令
    这两条指令格式如图所示,都是I类型指令,可以依据指令集中第26-31bit指令码的值判断是哪一种指令。
    在这里插入图片描述

  • 当指令码是6’b001100,表示是andi指令,逻辑“与”运算。
    指令用法为:andi rt,rs,immediate。
    指令作用为:rt<-rs AND zero_extended(immediate),将地址为rs的通用寄存器的值与指令中立即数进行零扩展后的值进行逻辑“与”运算,运算结果保存到地址为rt的通用寄存器中。

  • 当指令码是6’b001110,表示是xori指令,异或运算。

指令用法为:xori rt,rs,immediate。
指令作用为:rt<-rs XOR zero_extended(immediate),将地址为rs的通用寄存器的值与指令中立即数进行零扩展后的值进行逻辑“异或”运算,运算结果保存到地址为rt的通用寄存器中。

3.lui指令
lui指令的格式如图所示,从中可以发现luI指令是1类型指令,可以依据指令中第26-31bit指令码的值是否为6’b001111,从而判断是否是lui指令。
在这里插入图片描述指令用法为:lui rt,immediate。
指令作用为:rt<-immediate || 0的16次方,将16bit立即数保存到地址为rt的通用寄存器的高16位。另外,地址为rt的通用寄存器的低16位使用0填充。

4.sll、sllv、sra、srav、srl、srlv指令
这六条指令的格式如图所示,从图中可以发现这六条指令都是R类型指令,并且指令码都是6’b000000,也就是说,都是SPECIAL类,需要依据指令中第0-5bit功能码的值进一步判断是哪种指令。
在这里插入图片描述

  • 当功能码是6’b000000,表示是sll指令,逻辑左移。
    指令用法为:sll rd,rt sa.
    指令作用为:rd<-rt<<sa(logic),将地址为rt的通用寄存器的值向左移sa位,空出来的位置使用0填充,结果保存到地址为rd的通用寄存器中。
  • 当功能码是6’b000010,表示是srl指令,逻辑右移。
    指令用法为:srl rd,rt sa.
    指令作用为:rd<- rt >>sa(logic),将地址为rt的通用寄存器的值向右移sa位,空出来的位置使用0填充,结果保存到地址为rd的通用寄存器中。
  • 当功能码是6’b000011,表示是sra指令,算术右移。
    指令用法为:sra rd,rt sa.
    指令作用为:rd<- rt >>sa(arithmetic),将地址为rt的通用寄存器的值向右移sa位,空出来的位置使用rt[31]填充,结果保存到地址为rd的通用寄存器中。
  • 当功能码是6’b000100,表示是sllv指令,逻辑左移。
    指令用法为:sllv rd,rt sa.
    指令作用为:rd<- rt <<rs[4:0] (logic),将地址为rt的通用寄存器的值向左移位位,空出来的位置使用0填充,结果保存到地址为rd的通用寄存器中。移位位数由地址为rs的寄存器的值第0-4bit确定。
  • 当功能码是6’b000110,表示是srlv指令,逻辑右移。
    指令用法为:srlv rd,rt sa.
    指令作用为:rd<- rt >>rs[4:0] (logic),将地址为rt的通用寄存器的值向右移位位,空出来的位置使用0填充,结果保存到地址为rd的通用寄存器中。移位位数由地址为rs的寄存器的值第0-4bit确定。
  • 当功能码是6’b000111,表示是srav指令,算数右移。
    指令用法为:srav rd,rt sa.
    指令作用为:rd<- rt >>rs[4:0] (arithmetic),将地址为rt的通用寄存器的值向右移位位,空出来的位置使用rt[31]填充,结果保存到地址为rd的通用寄存器中。移位位数由地址为rs的寄存器的值第0-4bit确定。

5.nop、ssnop、sync、pref指令
这四条指令的格式如zhiling三条指令都是R类型指令,并且指令码都是6’b000000,也就是说,都是SPECIAL类。
在这里插入图片描述nop,ssnop两条指令的功能码都是6’b000000,与之前介绍的逻辑左移指令sll的功能码相同,这样在译码的时候会不会有冲突:nop指令的二进制码与sll $0,$0,0的二进制码一样,如何处理译码?ssnop指令的二进制码与sll $0,$0,1的二进制码一样,处理器如何译码?
在这里插入图片描述

其实两者是等价的,sll指令向$0寄存器保存移位结果,实际不会有任何效果,因为无论向$0写任何数,其值始终为0,所以效果等同于什么都不做,这也正是空指令nop、ssnop的效果。所以nop、ssnop指令不用特意实现,完全可以当作特殊的逻辑左移指令sll。

剩下的都是代码啦,我休息下看看怎么写,代码不写,其他的注意事项要么截图,要么打字喽~并且上面的内容很难理解多看几遍!!!因为我刚开始也看不懂,好好理解下就好了!光看书或者只看我写的内容不一定学会,要动手自己写一写或者做笔记!!!我们最后都会称为芯片、计算机等等领域的大佬!
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值