将处理组织成阶段

为了实现流水线处理机制,要将指令组织成某个特殊的阶段序列,所有的指令遵循统一的序列,不同阶段放在不同硬件上进行处理。下面是对各阶段的简述。

取指(fetch):取指阶段从内存读取指令字节,地址为程序计数器(PC)的值。从指令中抽取出指令指示符字节的两个四位部分,称为icode(指令代码)和ifun(指令功能)。它可能取出一个寄存器指示符字节,指明一个或两个寄存器操作数指示符rA和rB。它还可能取出一个四字节常数字va1C。它按顺序方式计算当前指令的下一条指令的地址va1P。也就是说,valP等于PC的值加上已取出指令的长度。

译码(decode):译码阶段从寄存器文件读入最多两个操作数,得到值valA和/或valB。通常,它读入指令rA和rB字段指明的寄存器,不过有些指令是读寄存器rsp的。

执行(execute):在执行阶段,算术/逻辑单元(ALU)要么执行指令指明的操作(根据ifun的值),计算内存引用的有效地址,要么增加或减少栈指针。得到的值我们称为valE。在此,也可能设置条件码。对一条条件传送指令来说,这个阶段会检验条件码和传送条件(由ifun给出),如果条件成立,则更新目标寄存器。同样,对一条跳转指令来说,这个阶段会决定是不是应该选择分支。

访存(memory):访存阶段可以将数据写入内存,或者从内存读出数据。读出的值为valM。

写回(write back):写回阶段最多可以写两个结果到寄存器文件。

更新PC(PC update):将PC设置成下一条指令的地址。

SEQ硬件结构

取指:将程序计数器寄存器作为地址,指令内存读取指令的字节。PC增加器(PC incre-menter)计算valP,即增加了的程序计数器。

译码:寄存器文件有两个读端口A和B,从这两个端口同时读寄存器值valA和valB。

执行:执行阶段会根据指令的类型,将算术/逻辑单元(ALU)用于不同的目的。对整数操作,它要执行指令所指定的运算。对其他指令,它会作为一个加法器来计算增加或减少栈指针,或者计算有效地址,或者只是简单地加0,将一个输入传递到输出。条件码寄存器(CC)有三个条件码位。ALU负责计算条件码的新值。当执行条件传送指令时,根据条件码和传送条件来计算决定是否更新目标寄存器。同样,当执行一条跳转指令时,会根据条件码和跳转类型来计算分支信号Cnd。

访存:在执行访存操作时,数据内存读出或写入一个内存字。指令和数据内存访问的是相同的内存位置,但是用于不同的目的。

写回:寄存器文件有两个写端口。端口E用来写ALU计算出来的值,而端口M用来写从数据内存中读出的值。

PC更新:程序计数器的新值选择自:valP,下一条指令的地址;va1C,调用指令或跳转指令指定的目标地址;va1M,从内存读取的返回地址。

SEQ的时序

SEQ的实现包括组合逻辑和两种存储器设备:时钟寄存器(程序计数器和条件码寄存器),随机访问存储器(寄存器文件、指令内存和数据内存)。组合逻辑不需要任何时序或控制——只要输入变化了,值就通过逻辑门网络传播。正如提到过的那样,我们也将读随机访问存储器看成和组合逻辑一样的操作,根据地址输入产生输出字。对于较小的存储器来说(例如寄存器文件),这是一个合理的假设,而对于较大的电路来说,可以用特殊的时钟电路来模拟这个效果。由于指令内存只用来读指令,因此我们可以将这个单元看成是组合逻辑。

现在还剩四个硬件单元需要对它们的时序进行明确的控制——程序计数器、条件码寄存器、数据内存和寄存器文件。这些单元通过一个时钟信号来控制,它触发将新值装载到寄存器以及将值写到随机访问存储器。每个时钟周期,程序计数器都会装载新的指令地址。只有在执行整数运算指令时,才会装载条件码寄存器。只有在执行rmmovq、 pushq或cal1指令时,才会写数据内存。寄存器文件的两个写端口允许每个时钟周期更新两个程序寄存器,不过我们可以用特殊的寄存器IDOxF作为端口地址,来表明在此端口不应该执行写操作。

SEQ的实现

取指阶段:

取指阶段包括指令内存硬件单元。以PC作为第一个字节(字节0)的地址,这个单元一次从内存读出10个字节。第一个字节被解释成指令字节,(标号为“Split”的单元)分为两个4位的数。然后,标号为“icode”和“ifun”的控制逻辑块计算指令和功能码,或者使之等于从内存读出的值,或者当指令地址不合法时(由信号imem error指明),使这些值对应于nop指令。根据icode的值,我们可以计算三个一位的信号(用虚线表示)。从指令内存中读出的剩下9个字节是寄存器指示符字节和常数字的组合编码。标号为“Align”的硬件单元会处理这些字节,将它们放入寄存器字段和常数字中。当被计算出的信号need_regids为1时,字节1被分开装入寄存器指示符rA和rB中。否则,这两个字段会被设为OxF(RNONE),表明这条指令没有指明寄存器。任何只有一个寄存器操作数的指令,寄存器指示值字节的另一个字段都设为OxF(RNONE)。因此,可以将信号rA和rB看成,要么放着我们想要访问的寄存器,要么表明不需要访问任何寄存器。这个标号为“Align”的单元还产生常数字valC。根据信号need_regids的值,要么根据字节1~8来产生va1C,要么根据字节2~9来产生。

PC增加器硬件单元根据当前的PC以及两个信号need_regids和need_valc的值,产生信号valP。对于PC值p、need_regids值r以及need_va1c值i,增加器产生值p+1+r+8i。

译码和写回阶段:

寄存器文件有四个端口。它支持同时进行两个读(在端口AB上)和两个写(在端口E和M上)。每个端口都有一个地址连接和一个数据连接,地址连接是一个寄存器ID,而数据连接是一组64根线路,既可以作为寄存器文件的输出字(对读端口来说),也可以作为它的输入字(对写端口来说)。两个读端口的地址输入为srcA和srcB,而两个写端口的地址输入为dstE和dstM。如果某个地址端口上的值为特殊标识符OxF(RNONE),则表明不需要访问寄存器。

根据指令代码icode以及寄存器指示值rA和rB,可能还会根据执行阶段计算出的Cnd条件信号。

执行阶段:

执行阶段包括算术/逻辑单元(ALU)。这个单元根据alufun信号的设置,对输入aluA和aluB执行ADD、SUBTRACT、AND或EXCLUSIVE-OR运算。如图4-29所示,这些数据和控制信号是由三个控制块产生的。ALU的输出就是valE信号。执行阶段的第一步就是每条指令的ALU计算。列出的操作数 aluB在前面,后面是aluA,这样是为了保证subq指令是va1B减去valA。可以看到,根据指令的类型,alua的值可以是valA、valC,或者是一8或+8。

访存阶段:

访存阶段的任务就是读或者写程序数据。如图所示,两个控制块产生内存地址和内存输入数据(为写操作)的值。另外两个块产生表明应该执行读操作还是写操作的控制信号。当执行读操作时,数据内存产生值valM。

访存阶段最后的功能是根据取值阶段产生的icode、imem_error、instr_valid值以及数据内存产生的dmem error信号,从指令执行的结果来计算状态码Stat。

更新PC阶段:

SEQ中最后一个阶段会产生程序计数器的新值。如图 最后步骤所示,依据指令的类型和是否要选择分支,新的PC可能是valC、valM或valP。

3.3 Y86-64的顺序实现的更多相关文章

  1. Spring IOC 低级容器解析

    1.IOC是什么 IOC-Inversion of Control,即"控制反转",不是什么技术,而是一种设计思想.在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不 ...

  2. wamp安装失败原因大全

    wamp 是 Windos.Apache.Mysql.PHP集成安装环境 为了安装hdwiki 所以需要这个环境 1.下载wampserver_x86_3.0.6 64位  环境包,安装路径禁止有空格 ...

  3. 源码编译搭建LAMP

    环境版本信息: RHEL 5.3 Apache / 2.4.16 PHP / 5.4.45 mysql-5.5.45 源代码编译 安装方式 1: configure 配置 以及定制我们的软件包 2: ...

  4. MIT 操作系统实验 MIT JOS lab1

    JOS lab1 首先向MIT还有K&R致敬! 没有非常好的开源环境我不可能拿到这么好的东西. 向每个与我一起交流讨论的programmer致谢!没有道友一起死磕.我也可能会中途放弃. 跟丫死 ...

  5. 《Spring技术内幕》笔记-第二章 IoC容器的实现

    简单介绍 1,在Spring中,SpringIoC提供了一个主要的JavaBean容器.通过IoC模式管理依赖关系.并通过依赖注入和AOP切面增强了为JavaBean这样子的POJO提供事务管理,生命 ...

  6. Java内存模型深度解析:顺序一致性--转

    原文地址:http://www.codeceo.com/article/java-memory-3.html 数据竞争与顺序一致性保证 当程序未正确同步时,就会存在数据竞争.java内存模型规范对数据 ...

  7. sqlalchemy mark-deleted 和 python 多继承下的方法解析顺序 MRO

    sqlalchemy mark-deleted 和 python 多继承下的方法解析顺序 MRO 今天在弄一个 sqlalchemy 的数据库基类的时候,遇到了跟多继承相关的一个小问题,因此顺便看了一 ...

  8. 64位windows 7下成功配置TortoiseGit使用Github服务器

    最近感觉自己电脑上的代码太乱了,东一块.西一块……于是决定使用正规的源代码管理软件来管理自己以后写的代码.以前做小项目的时候用过TortoiseSVN,感觉不错,但是速度上有点慢,于是决定尝试一下新东 ...

  9. java内存模型-顺序一致性

    数据竞争与顺序一致性保证 当程序未正确同步时,就会存在数据竞争.java 内存模型规范对数据竞争的定义如下: 在一个线程中写一个变量, 在另一个线程读同一个变量, 而且写和读没有通过同步来排序. 当代 ...

  10. MDX函数(官方顺序,带示例)

    MDX函数(官方顺序) 1.  AddCalculatedMembers (MDX) 返回通过将计算成员添加到指定集而生成的集. 语法: AddCalculatedMembers(Set_Expres ...

随机推荐

  1. IPv6 — 网际协议第 6 版

    目录 文章目录 目录 IPv6 IPv6 的发展 IPv6 网络基本概念 IPv6 的特性 IPv4 与 IPv6 的比较 IPv6 IPv6(Internet Protocol version 6, ...

  2. 导入使用es

    from django.shortcuts import render, HttpResponsefrom elasticsearch import Elasticsearchfrom elastic ...

  3. 如何模拟HTTP请求并验证功能

    要模拟HTTP请求并验证功能,你可以使用Spring Boot提供的MockMvc工具,它允许我们在没有实际启动HTTP服务器的情况下测试Spring MVC控制器.以下是一个使用MockMvc进行H ...

  4. Django——admin后台上传文件

    from django.db import models class Mytb(models.Model): file = models.FileField(upload_to='uploads/') ...

  5. 【分享】FFmpeg桌面神器,集多种功能于一身,超级好用,不用命令行!

    在媒体处理上,市面上有很多软件可以选择,在众多软件里面 FFmpeg 是比较独特的一款,直接选择 FFmpeg 硬核命令行工具的朋友相对较少,大多时候只是被集成在各样的软件里,如果单独拿出来使用,不少 ...

  6. c# 32位程序突破2G内存限制

    起因在开发过程中,由于某些COM组件只能在32位程序下运行,程序不得不在X86平台下生成.而X86的32位程序默认内存大小被限制在2G.由于程序中可能存在大数量处理,期间对象若没有及时释放或则回收,内 ...

  7. 视图结构 wxml 列表渲染 for

    WXML是框架设计的一套标签语言,结合基础组件.事件系统,可以构建出页面的结构. wxml是一个严格的标记性语言,有开始就必须有结束,单标签就一个有结束符 5.1.数据绑定 在js逻辑层中定义数据源, ...

  8. springboot项目中一些小技巧

    一.使用命令创建maven工程 1.例如我们想在IDEA的工作空间目录下E:\Gitee\springboot,创建maven项目,首先先进入该目录下 2.去掉原来的目录,输入cmd,然后回车,进入命 ...

  9. C++中 符号的优先级

    符号 运算顺序 :: 从左至右 a++ a-- type() type{} a() a[] . -> 从左至右 ! ~ ++a --a +a -a (type) sizeof &a *a ...

  10. EF INNER JOIN WHERE ORDER BY

    同时使用 join,where,order by. UpdaterDbContext db = new UpdaterDbContext(); // 按 t_server 表的 seq ASC 排序, ...