第四章 处理器
4.1 引言
指令数目 + 时钟周期长度 + 每条指令所需时钟周期数(CPI) ⟹ \Longrightarrow ⟹ 计算机性能
-
实现指令的过程:
- ⨀ \color{red}\bigodot ⨀ 1. 程序计数器(PC)指向指令所在储存单元,提取指令
- ⨀ \color{red}\bigodot ⨀ 2. 根据指令字段内容,选择读取寄存器数量(取字指令读一个,其他大部分读两个)
-
⨀
\color{red}\bigodot
⨀ 3. 除跳转指令外,都要使用算术逻辑单元(ALU)计算
- 储存访问指令(内存操作):计算地址
- 算术逻辑指令(运算操作):执行运算
- 分支指令(跳转操作):进行比较
-
⨀
\color{red}\bigodot
⨀ 4.此处因指令类型而异:
- 储存访问指令:访问内存为读取或储存数据
- 算术逻辑指:将ALU或储存器的数据写入寄存器
- 分支指令:根据比较结果决定下一条指令地址
抽象简化MIPS子集实现视图:
-
待填充细节:
-
数据选择器/多选器 Multiplexor:从不同数据来源中选择合适数据送到目标单元
三大多选器和控制单元
-
不同执行指令的类型决定单元的控制流向
-
4.2 逻辑设计一般方法
-
数据通路功能部件:
- 组合单元 Combinational element:处理数据值的操作单元。如与门,ALU
- 输出只由输入决定,没有内部存储功能
- 状态单元 State element:存储状态的单元。如指令存储器,数据存储器,寄存器,触发器
- 输出由输入和内部状态共同决定,内部存储了计算机的状态
- 至少包含两个输入(写入单元的数据值 + 何时写入的时钟信号)和一个输出
- MIPS实现常见状态单元:触发器,存储器,寄存器
- 状态单元随时可读,时钟决定何时被写入
- 组合单元 Combinational element:处理数据值的操作单元。如与门,ALU
-
时钟方法:规定信号读写的时间(避免从一个信号被同时读写而出现错误)。
假设采用边沿触发时钟 edge-triggered clocking(只在时钟跳变边沿改变储存值)
- 时钟信号决定数值何时写入状态单元
- 状态单元的输入信号先达到稳定,才能在有效的时钟边沿导致状态变化
- 一个时钟周期完成:所有信号从状态单元1 ⟶ 组 合 逻 辑 \stackrel{\color{red}组合逻辑}{\longrightarrow} ⟶组合逻辑 状态单元2
- 写信号:
- 若每个有效时钟边沿都进行写入操作,则可忽略写控制信号 control signal
- 否则需要一个写控制信号(输入信号:写控制信号,时钟信号),故只有一个时钟边沿到来且写控制信号有效时,状态单元才改变状态。
有效 asserted(无效 deasserted):表示信号为逻辑高(低)
控制信号 VS 数据信号
- 控制信号:决定多选器选择或指示功能单元操作的信号。
- 数据信号:由功能单元操作的信息。
4.3 建立数据通路
分析执行每类MIPS指令所需要的部件,不同指令需要不同的数据通路部件 datapath element
-
数据通路部件 Datapath Element:
- 程序计数器 Program Counter(PC):用于储存程序的指令,提供给定地址的指令
- 加法器 Add:计算 PC 的值以指向下一条指令的地址
- 指令存储器 Instruction Memory:只提供读指令访问,可视为逻辑单元,不需读控制信号
-
寄存器堆 Register File:四入两出
- 读操作:
- 两个输入:提供要读的寄存器号 register number(5位)
- 两个输出:提供从寄存器堆读出的输出数据(32位)
- 写操作:
- 两个输入:提供要写的寄存器号(5位)和要写的数据 data(32位)
- 读操作:
-
ALU:两入两出
- 两个输入:32位
- 两个输出:一个32位,另一个1位指示输出结果是否为0(零检测输出型号实现分支指令)
-
数据存储器 Data Memory:需要读控制信号(因为防止读到无效地址)
-
符号扩展 Sign-Extend:16位输入,32位输出
-
主控制单元 Control:
- 一个输入:6位,即操作码 opcode [31-26]
- 九个输出:10位
-
指令举例:
- 存取指令:
- 分支指令:
- 计算分支目标地址 branch target address:
- 确定分支条件:比较操作数
- 分支条件发生 branch taken:分支条件为真,PC 换为新的目标地址
- 分支条件发生 branch not taken:分支条件为加,PC 换为自增后的 PC
- 跳转指令:PC 的低 28 28 28 位换为26位偏移地址左移两位(变为28位)
4.4 单周期(Single-Cycle implementation)实现机制
由于不同类型指令都使用同一个数据同路,所以这条路一定是对于不同指令有不同的走法,于是要使用多选器MUX和控制信号Control来从多个输入中选择
- 三大多选器:
- ALU 第二个输入前:
- 寄存器堆写数据输入:
- 分支指令选择下一指令地址:
-
ALU控制:2位ALUop 与 6位funct功能码 生成 4位ALU控制信号 来表示六种功能
-
当 ALUop=00 时:无论 funct,ALU控制信号均为 0010 0010 0010
-
当 ALUop=01 时:无论 funct,ALU控制信号均为 0110 0110 0110,且表示 beq 指令中的计算
-
当 ALUop=10 时:ALU控制信号根据 funct 决定
-
当 ALUop=11 时:此情况不应发生
-
-
主控制单元 Control:九大十位控制信号(ALUop占两位)
控制信号名 功能 无效时(0)含义 有效时(1)含义 RegDst 写寄存器来自 rt 字段(20:16) rd 字段(15:11) RegWrite / / 写寄存器堆 ALUSrc 第二个ALU操作数来自 寄存器堆第二个输出 rt 指令低16位的符号扩展 PCSrc PC下一个地址来自 PC+4 分支目标地址 MemRead / / 读数据存储器 MemWrite / / 写数据到地址指定的存储器单元 MemtoReg 写入寄存器的数据来自 ALU 数据存储器 - Branch:分支指令表示可以分支,需查看ALU零输出
- PCSrc:由Branch和ALU的zero相与得到,不直接来自主控制单元
- Jump:跳转指令选择PC值的来源(在PC+4,分支目标PC,跳转目标 PC)
-
不同类型指令的数据通路操作:
-
R-型指令:例
add $t1 $t2 $t3
. 一个时钟周期内可分为 4 4 4 大步骤- ⨀ \color{red}\bigodot ⨀ 1. 从指令存储器取指令,PC自增
-
⨀
\color{red}\bigodot
⨀ 2. 从寄存器堆读寄存器
$t2
和$t3
。同时主控制单元计算出各控制信号状态 - ⨀ \color{red}\bigodot ⨀ 3. ALU根据funct字段确定功能,操作从寄存器堆读出的数据
-
⨀
\color{red}\bigodot
⨀ 4. 将ALU结果写入寄存器堆,根据指令选择目标寄存器
$t1
-
取数指令:例
lw $t1 offset($t2)
. 一个时钟周期内可分为 5 5 5 大步骤- ⨀ \color{red}\bigodot ⨀ 1. 从指令存储器取指令,PC自增
-
⨀
\color{red}\bigodot
⨀ 2. 从寄存器堆读寄存器
$t2
- ⨀ \color{red}\bigodot ⨀ 3. ALU将从寄存器堆读出的值和符合扩展后的指令低 16 16 16 位相加
- ⨀ \color{red}\bigodot ⨀ 4. 将ALU结果作为数据存储器的地址
-
⨀
\color{red}\bigodot
⨀ 5. 存储单元的数据写入寄存器堆,根据指令选择目标寄存器
$t1
-
分支指令:例
beq $t1 $t2 offset
. 一个时钟周期内可分为 4 4 4 大步骤- ⨀ \color{red}\bigodot ⨀ 1. 从指令存储器取指令,PC自增
-
⨀
\color{red}\bigodot
⨀ 2. 从寄存器堆读寄存器
$t1
和$t2
- ⨀ \color{red}\bigodot ⨀ 3. ALU将从寄存器堆读出两数相减。PC+4 的值与符号扩展并左移两位后的孩子零低 16 16 16 位相加,结果即分支目标地址
- ⨀ \color{red}\bigodot ⨀ 4. 根据ALU的零输出决定哪个加法器的结果存入PC中
-
-
跳转指令:opcode = 2
- 拼接32位跳转地址:当前 PC+4 的高 4 4 4 位 + + + 跳转指令的 26 26 26 位立即数字段 + + + 低位 0 0 2 00_2 002
- 加入控制信号 Jump
-
单周期缺点:周期需要根据最慢的指令(
lw
)花费时间规定
4.5 多周期
分成:访存通路,取操作数通路,运算通路
控制器加入CLK(有时序)