自己动手写处理器之第四阶段(1)——第一条指令ori的实现

前面几章介绍了很多预备知识,也描绘了即将要实现的OpenMIPS处理器的蓝图,各位读者是不是早已摩拳擦掌,迫切希望一展身手了,好吧,本章我们将实现OpenMIPS处理器的第一条指令ori,为什么选择这条指令作为我们实现的第一条指令呢?答案就两个字——简单,指令ori用来实现逻辑“或”运算,选择一条简单的指令有助于我们排除干扰,将注意力集中在流水线结构的实现上,当然也可以选择其它类似的指令,只要简单即可。通过这条简单指令的实现,本章在4.2节将初步建立OpenMIPS的五级流水线结构,当我们在后面章节中实现其
摘要由CSDN通过智能技术生成

将陆续上传本人写的新书《自己动手写处理器》(尚未出版),今天是第11篇,我尽量每周四篇

第4章 第一条指令ori的实现

      前面几章介绍了很多预备知识,也描绘了即将要实现的OpenMIPS处理器的蓝图,各位读者是不是早已摩拳擦掌,迫切希望一展身手了,好吧,本章我们将实现OpenMIPS处理器的第一条指令ori,为什么选择这条指令作为我们实现的第一条指令呢?答案就两个字——简单,指令ori用来实现逻辑“或”运算,选择一条简单的指令有助于我们排除干扰,将注意力集中在流水线结构的实现上,当然也可以选择其它类似的指令,只要简单即可。通过这条简单指令的实现,本章在4.2节将初步建立OpenMIPS的五级流水线结构,当我们在后面章节中实现其余指令的时候,都是在这个初步建立的流水线结构上进行扩充。

      在ori指令实现后,要验证其实现是否正确,所以在4.3节建立了最小SOPC,仅仅包含OpenMIPS、指令存储器,用于验证ori指令是否实现正确,后续章节验证其余指令的时候,都是在这个最小SOPC或者其改进模型上进行验证。

      本章最后介绍了MIPS编译环境的建立。

4.1 ori指令说明

      ori是进行逻辑“或”运算的指令,其指令格式如图4-1所示。


      从指令格式中可以知道,这是一个I类型的指令,ori指令的指令码是6'b001101,所以当处理器发现正在处理的指令的高6bit是6'b001101时,就知道当前正在处理的是ori指令。

      指令用法为:ori rs, rt, immediate,作用是将指令中的16位立即数immediate进行无符号扩展至32位,然后与索引为rs的通用寄存器的值进行逻辑“或”运算,运算结果保存到索引为rt的通用寄存器中。这里需要说明以下两点。

      (1)无符号扩展

      在MIPS32指令集架构中,经常会有指令需要将其中的立即数进行符号扩展,或者无符号扩展,一般都是将n位立即数扩展为32位,其中,符号扩展是将n位立即数的最高位复制到扩展后的32位数据的高(32-n)位,无符号扩展则是将扩展后的32位数据的高(32-n)位都置为0。以将指令中的16位立即数扩展为32位为例,表4-1给出了当16位立即数分别是0x8000、0x1000时的符号扩展、无符号扩展的结果。


      (2)通用寄存器

      在MIPS32指令集架构中定义了32个通用寄存器$0-$31,OpenMIPS实现了这32个通用寄存器,使用某一个通用寄存器只需要给出相应索引,这个索引占用5bit,ori指令中的rs、rt就是通用寄存器的索引,例如:当rs为5'b00011时,就表示通用寄存器$3。

4.2 流水线结构的建立

4.2.1 流水线的简单模型

      数字电路有组合逻辑、时序逻辑之分,其中时序逻辑最基本的器件是寄存器,此处的寄存器不是在4.1节中提到的MIPS架构规定的通用寄存器$0-$31,后者是一个更高层面的概念,前者是类似于D触发器这种数字电路的基本器件。寄存器按照给定时间脉冲来进行时序同步操作,其使得时序逻辑电路具有记忆功能。而组合逻辑电路则由逻辑门组成,提供电路的所有逻辑功能。实际的数字电路一般是组合逻辑与时序逻辑的结合。如果寄存器的输出端和输入端存在环路,这样的电路称为“状态机”。如图4-2所示。如果寄存器之间有连接,而没有上述环路,这样的电路结构称为“流水线”。如果4-3所示。


       在流水线结构中,信号在寄存器之间传递,每传递到一级都会引起相应的组合逻辑电路变化,对这种模型进行抽象描述就是寄存器传输级(RTL:Register Transfer Level)。本节接下来要实现的原始的OpenMIPS五级流水线结构就是图4-3的扩充。

4.2.2 原始的OpenMIPS五级流水线结构

      扩充图4-3,可以得到OpenMIPS的原始数据流图如图4-4所示,这个数据流图还很不完整,在后续章节中会随着实现指令的增加而丰富,但这个原始的数据流图已经可以表达本节要实现的ori指令在流水线中的处理过程了。


      图中深色部分对应的是图4-3中的D触发器,深色部分之间的部分对应的是图4-3中的组合逻辑。各个阶段完成的主要工作如下。

  •  取指:取出指令存储器中的指令,PC值递增,准备取下一条指令。
  •  译码:对指令进行译码,依据译码结果,从32个通用寄存器中取出源操作数,有的指令要求两个源操作数都是寄存器的值,比如or指令,有的指令要求其中一个源操作数是指令中立即数的扩展,比如ori指令,所以这里有两个复用器,用于依据指令要求,确定参与运算的操作数,最终确定的两个操作数会送到执行阶段。
  •  执行阶段:依据译码阶段送入的源操作数、操作码,进行运算,对于ori指令而言,就是进行逻辑“或”运算,运算结果传递到访存阶段。
  •  访存阶段:对于ori指令,在访存阶段没有任何操作,直接将运算结果向下传递到回写阶段。
  •  回写阶段:将运算结果保存到目的寄存器。

      图4-5是为实现上述数据流图而设计的OpenMIPS系统结构,图中显示了各个模块的接口、连接关系。每个模块上方是模块名,下方是对应的Verilog HDL程序文件名。本节接下来将分别实现图中各个模块。


4.2.3 一些宏定义

      在正式开始介绍流水线结构实现之前,需要给出一些宏定义,因为在OpenMIPS的实现过程中,为了提高代码的可读性和易懂性,使用了较多的宏,全部的宏都在文件defines.v中定义。此处列举在本章中会使用到的一部分宏,后面随着OpenMIPS功能的不断完善,会有更多的宏添加进来,届时会对新增加的宏进行说明。

//*******************         全局的宏定义        ***************************
`define RstEnable            1'b1               //复位信号有效
`define RstDisable           1'b0               //复位信号无效
`define ZeroWord             32'h00000000       //32位的数值0
`define WriteEnable          1'b1               //使能写
`define WriteDisable         1'b0               //禁止写
`define ReadEnable           1'b1               //使能读
`define ReadDisable          1'b0               //禁止读
`define AluOpBus             7:0                //译码阶段的输出aluop_o的宽度
`define AluSelBus            2:0                //译码阶段的输出alusel_o的宽度
`define InstValid            1'b0               //指令有效
`define InstInvalid          1'b1               //指令无效
`define True_v               1'b1               //逻辑“真”
`define False_v              1'b0               //逻辑“假”
`define ChipEnable           1'b1               //芯片使能
`define ChipDisable          1'b0               //芯片禁止


//*********************   与具体指令有关的宏定义  *****************************
`define EXE_ORI              6'b001101          //指令ori的指令码
`define EXE_NOP              6'b000000


//AluOp
`define EXE_OR_OP            8'b00100101
`define EXE_NOP_OP           8'b00000000

//AluSel
`define EXE_RES_LOGIC        3'b001

`define EXE_RES_NOP          3'b000


//*********************   与指令存储器ROM有关的宏定义   **********************
`define InstAddrBus          31:0               //ROM的地址总线宽度
`define InstBus              31:0               //ROM的数据总线宽度
`define InstMemNum           131071             //ROM的实际大小为128KB
`define InstMemNumLog2       17                 //ROM实际使用的地址线宽度


//*********************  与通用寄存器Regfile有关的宏定义   *******************
`define RegAddrBus           4:0                //Regfile模块的地址线宽度
`define RegBus               31:0               //Regfile模块的数据线宽度
`define RegWidth             32                 //通用寄存器的宽度
`define DoubleRegWidth       64                 //两倍的通用寄存器的宽度
`define DoubleRegBus         63:0               //两倍的通用寄存器的数据线宽度
`define RegNum               32                 //通用寄存器的数量
`define RegNumLog2           5              
  • 21
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值