【计算机体系结构】流水线实现

流水线实现

MIPS(子集)数据通路(非流水线)
在该数据通路,一条指令的操作(至多)包含5个时钟周期:取值、指令译码/读寄存器、执行/有效地计算、存储器访问/分支完成、写回。

PC(程序计数器):存放当前指令的地址
NPC(下一条程序计数器):存放下一条指令的地址
IR(指令寄存器):存放当前正在处理的指令
A(第一操作数寄存器):存放从通用寄存器组读出来的操作数
B(第二操作数寄存器):存放从通用寄存器组读出来的另一个操作数
Imm:存放符号扩展后的立即数操作数
Cond :用来存放条件判断的结果,其值为 “ 真 ” 表示分支成功
ALUo(Output):存放ALU的运算结构
LMD:存放load指令从存储器读出的数据

取指令周期(IF)
操作
IR <— Mem[PC]
NPC <— PC+4

指令译码 / 读寄存器周期(ID)
主要操作
A <— Regs[rs]
B <— Regs[rt]
指令译码
Imm <— ((IR16)16##IR16…31)
(注意:指令的译码操作和读寄存器操作是并行进行的:在MIPS指令格式中,操作码字以及rs、rt字段都是固定的位置。这种技术称为固定字段译码技术)

执行 / 有效地址计算周期(EX)
不同指令进行的操作不同
load指令和store指令
ALUo <— A + Imm
寄存器 — 寄存器ALU指令
ALUo <— A funct B
寄存器 — 立即值ALU指令
ALUo <— op Imm
分支指令
ALUo <— NPC+(Imm<<2)
cond <—(A == 0)
(注意:将有效地址计算周期和执行周期合并为一个时钟周期,这是因为MIPS指令集采用load/store结构,没有任何指令需要同时进行数据有效地址的计算、专一目标地址的计算和对数据进行运算。)

存储器访问 / 分支完成周期(MEM)
不同指令进行的操作不同
所有指令都要在该周期对PC进行更新
非分支指令:PC <— NPC
分支指令:
if (cond)
PC <— ALUo else PC <— NPC
(该周期内需要处理的MIPS指令仅包含load、store和分支三种)

写回周期(WB)
不同指令进行的操作不同
寄存器 — 寄存器ALU指令
Regs[rd] <— ALUo
寄存器 — 立即数ALU指令
Regs[rt] <— ALUo
load指令
Regs[rd] <— LMD

MIPS的流水化

基本原则:每一个时钟周期完成的工作看做是流水线的一段,每个时钟周期启动一条新的指令。

流水寄存器的位置与作用
位置:段与段之间设置流水线寄存器
作用:① 将各段的工作隔开,使得它们不会互相干扰 ② 保存相应的处理结果 ③ 向后传递后面将要用到的数据或者控制信息

流水寄存器命名规则
三个部分:流水寄存器.子寄存器名[字段名]

  • 流水寄存器名:用其相邻的两个段的名称拼合而成。例如:ID段与EX段之间的流水寄存器用ID / EX表示。(每个流水寄存器是由若干个子寄存器构成的)
  • 子寄存器名:基本寄存器(如:IR)
  • 字段名:基本寄存器的某字段
    实例:ID / EX.IR[op]:流水寄存器ID / EX中的子寄存器IR的op字段(即操作码字段)

其他数据通路改动

  1. 增加了向后传递IR和从MEM / WB.IR送回通用寄存器组的连接。
  2. 将对PC的修改移到了IF段,以便PC能及时地加4,为取下一条指令做好准备。

数据冲突

  1. 所有的数据冲突均可在ID段检测到  * 如何存在数据冲突,就在相应的指令流出ID段之前将之暂停。  * 完成该工作的硬件成为流水线的互锁机制。
  2. 在ID段确定需要什么样的定向,并设置相应的控制  * 降低流水线的硬件复杂度。(不必挂起已经改变了机器状态的指令)
  3. 在使用操作数的那个时钟中期的开始检测冲突和确定必需的定向
  4. 检测冲突是通过比较寄存器地址是否相等来实现的

控制冲突

  1. 分支指令的条件测试和分支目标地址计算是在EX段完成,对PC的修改是在MEM段完成。
  2. 它所带来的分支延迟是3个时钟周期。
  3. 减少分支延迟
发布了46 篇原创文章 · 获赞 30 · 访问量 1814

猜你喜欢

转载自blog.csdn.net/qq_43263647/article/details/105672120