CPU Datapath
CPU 可以看成两大部分:
| 部分 | 作用 |
|---|---|
| 数据通路 | 保存数据、传送数据、加工数据,决定数据能从哪里流到哪里 |
| 控制部件 | 根据指令、状态和时序产生控制信号,决定数据通路在某一时刻怎样工作 |
数据通路是指令执行过程中数据经过的路径,以及路径上涉及的硬件。
数据通路的基本组成
数据通路中的部件可以分成两类。
| 类型 | 也叫 | 是否保存状态 | 典型部件 | 理解重点 |
|---|---|---|---|---|
| 组合逻辑单元 | 操作元件 | 不保存 | ALU、加法器、多路选择器、三态门、译码逻辑 | 输入变化后,经过组合逻辑延迟得到输出 |
| 时序逻辑单元 | 状态元件 | 保存 | PC、IR、MAR、MDR、通用寄存器、暂存寄存器、流水线寄存器 | 在时钟边沿写入新状态,并把状态保持到下一次写入 |
一条典型的数据通路可以抽象为:
1 | 状态元件 -> 组合逻辑 -> 状态元件 |
例如一次寄存器加法可以理解为:
1 | R1, R2 -> ALU -> R3 |
其中 R1/R2/R3 是状态元件,ALU 是组合逻辑单元。若这个操作安排在一个时钟周期内,那么从 R1/R2 输出开始,经过 ALU 运算,到 R3 能在时钟边沿写入为止,整条路径都必须在该周期内完成。
对数据通路来说,一个时钟周期内完成的是从一个状态元件出发,经过若干组合逻辑,再写入另一个状态元件的一段路径。完整指令是否一个周期完成,取决于采用单周期、多周期还是流水线数据通路。
数据通路可以从两个维度分类:内部连接方式和时序组织方式。
| 分类维度 | 关心的问题 | 类型 |
|---|---|---|
| 内部连接方式 | 部件之间怎样连线,线路是否共享 | 总线式数据通路、专用数据通路 |
| 时序组织方式 | 一条指令怎样占用时钟周期 | 单周期数据通路、多周期数据通路、流水线数据通路 |
- 内部连接方式影响一个周期内能同时发生多少数据传送。
- 时序组织方式决定一条指令需要几个周期、哪些寄存器必须保存中间状态。
按内部连接方式分类
总线式数据通路
总线式数据通路用公共通路连接多个部件。总线可以是一条,也可以是多条。
| 类型 | 连接方式 | 线路占用 | 特点 |
|---|---|---|---|
| 单总线结构 | 多个寄存器、ALU、MAR、MDR 等共享一条 CPU 内部总线 | 同一时刻通常只能有一个源部件向总线输出 | 结构简单、硬件量少,但容易产生总线占用冲突,很多操作要拆成多个节拍 |
| 多总线结构 | 使用两条或多条内部总线 | 可支持多个源操作数同时送往 ALU,或同时进行更多传送 | 并行性更好,减少暂存和节拍数,但硬件更复杂 |
单总线结构同一时刻只允许一个部件向总线输出。如果 R0out 和 R1out 同时有效,两个寄存器都试图驱动同一条总线,就会产生冲突。因此单总线的控制信号通常遵守:
1 | 一个时刻:一个 out 信号 + 一个或多个兼容的 in 信号 |
专用数据通路
专用数据通路按常用的数据和地址流动方向设置专门连线。它不依赖一条公共总线反复搬运数据,而是让常用路径直接连接。这些存在的多条路径可以在同一周期内并行工作。
| 对比点 | 总线式数据通路 | 专用数据通路 |
|---|---|---|
| 线路 | 多个部件共享总线 | 常用路径有专门连线 |
| 数据流向 | 要看当前总线由谁驱动、谁接收 | 要沿图中已有箭头判断 |
| 硬件代价 | 较低 | 较高 |
| 性能 | 单总线并行性低,多总线较好 | 通常更高 |
| 控制重点 | out/in 信号和总线冲突 |
多路选择、控制线和路径选择 |
专用结构中常省略多路选择器,只用箭头表示数据可以沿哪个方向传送。若多个来源可能进入同一个部件,实际硬件中会有 MUX 或三态门,控制信号负责选择其中一路。
按时序组织方式分类
时序组织方式回答的是:一条指令怎样占用时钟周期。
| 类型 | 一条指令耗时 | 数据通路特点 | 寄存器使用特点 |
|---|---|---|---|
| 单周期数据通路 | 每条指令都在一个时钟周期内完成 | 一个周期内要完成取指、译码、执行、访存、写回中该指令需要的全部工作;周期长度按最慢指令设置 | 中间结果通常不跨周期保存;典型单周期数据通路常不设置跨周期保存指令的 IR |
| 多周期数据通路 | 一条指令拆成多个时钟周期完成 | 每个周期只完成部分工作;同一硬件可在不同周期复用 | 必须用 IR、MDR、A/B、ALUOut 等寄存器保存跨周期信息 |
| 流水线数据通路 | 一条指令跨多个流水段,多条指令重叠执行 | 每个阶段之间加入流水线寄存器;理想情况下每个周期完成一条指令 | 需要 IF/ID、ID/EX、EX/MEM、MEM/WB 等流水线寄存器保存阶段间信息 |
单周期数据通路
单周期数据通路要求一条指令的所有必要工作都放在一个时钟周期内完成。典型路径可能是:
1 | PC -> 指令存储器 -> 控制逻辑/寄存器堆 -> ALU -> 数据存储器 -> 寄存器堆 |
这条路径很长,所以时钟周期必须足够长,以保证最慢指令也能在一个周期内完成。短指令虽然不需要完整路径,也必须等待这个长周期结束。
典型单周期数据通路通常不使用跨周期保存指令的 IR。原因是指令在同一个周期内被取出、译码并驱动后续控制,不需要保存到下一个周期继续使用。
多周期和流水线数据通路则不同,它们需要保存阶段之间的信息,因此通常需要 IR 或流水线寄存器。
多周期数据通路
多周期数据通路把一条指令拆成多个时钟周期。每个周期只完成一段数据传送或运算,例如:
1 | 第 1 周期:取指 |
不是所有指令都要经历全部周期。寄存器-寄存器运算可能不需要访存周期,分支指令可能不需要写回周期。
多周期数据通路的关键是硬件复用。同一个 ALU 既可以在取指阶段计算 PC + 1,也可以在执行阶段做算术逻辑运算,还可以在访存前计算有效地址。为了复用硬件,必须用额外寄存器保存中间状态。
| 寄存器 | 保存内容 | 为什么需要 |
|---|---|---|
| IR | 当前指令 | 取指结束后,后续周期仍要使用操作码、寄存器号、地址字段 |
| MDR | 主存读出的数据 | 访存结果可能要到后续周期才写回 |
| A/B | 从寄存器堆读出的两个操作数 | 后续周期 ALU 才使用 |
| ALUOut | ALU 输出 | 运算结果或有效地址可能要在下一周期继续使用 |
多周期数据通路常与总线式结构联系在一起,尤其是单总线或较少总线结构。因为每个周期只做一部分工作,硬件可以分时复用。
流水线数据通路
流水线数据通路把指令执行分成若干阶段。常见五段为:
1 | IF -> ID -> EX -> MEM -> WB |
| 阶段 | 主要工作 | 阶段间需要保存什么 |
|---|---|---|
| IF | 取指,更新 PC | 取出的指令、下一条 PC |
| ID | 译码,读寄存器 | 操作数、控制信号、立即数、寄存器号 |
| EX | ALU 运算或计算地址 | ALU 结果、分支判断、目的寄存器信息 |
| MEM | 访问数据存储器 | 读出的数据或待写回的 ALU 结果 |
| WB | 写回寄存器 | 写回数据和目的寄存器号 |
流水线数据通路的特点是:单条指令仍然跨多个阶段,但不同指令可以同时处在不同阶段。为了让各阶段互不混乱,阶段之间必须有流水线寄存器:
1 | IF/ID, ID/EX, EX/MEM, MEM/WB |
流水线数据通路通常是在专用数据通路基础上加入流水线寄存器。它追求吞吐率,而不是让单条指令的执行时间变短。
两种分类维度的联系
| 常见搭配 | 原因 |
|---|---|
| 单周期数据通路常使用专用结构数据通路 | 一条指令必须在一个周期内完成,需要尽量让必要路径同时可用 |
| 多周期数据通路常使用总线式或共享硬件结构 | 指令拆成多个周期后,可以用时间换硬件,复用总线和 ALU |
| 流水线数据通路常使用专用通路并加入流水线寄存器 | 多个阶段要并行工作,需要各阶段有相对独立的数据路径和阶段寄存器 |
- 若问“完整指令是否一定一个时钟周期完成”,只对单周期数据通路成立。
- 若问“某个寄存器传送或 ALU 运算是否能在一个时钟周期内完成”,要看这是不是一个状态元件到状态元件的组合路径。
- 若问“为什么单周期数据通路通常不使用 IR”,核心是指令不需要跨周期保存。
- 若问“为什么多周期数据通路需要 IR/MDR/ALUOut”,核心是信息要跨周期保存。
每一个节拍中:
- 哪个部件把数据送上总线;
- 哪个部件从总线接收数据;
- ALU 是否需要输入暂存;
- 主存访问是否需要 MAR/MDR;
- 当前节拍是否会发生总线冲突。
基本传送
| 操作 | 数据流向 | 控制信号 | 线路占用 |
|---|---|---|---|
| PC 送 MAR | (PC) -> Bus -> MAR |
PCout, MARin |
PC 驱动总线,MAR 接收 |
| MDR 送 IR | (MDR) -> Bus -> IR |
MDRout, IRin |
MDR 驱动总线,IR 接收 |
| R1 送 Y | (R1) -> Bus -> Y |
R1out, Yin |
R1 驱动总线,Y 接收 |
| Z 送 ACC | (Z) -> Bus -> ACC |
Zout, ACCin |
Z 驱动总线,ACC 接收 |
如果一个操作要两个源操作数同时进入 ALU,单总线不能让两个寄存器同时输出到总线。常见做法是先把一个操作数送入暂存寄存器 Y,再让另一个操作数通过总线送到 ALU 输入端。
1 | R1 -> Bus -> Y |
这里 Y 和 Z 的作用就是解决单总线下 ALU 输入、输出的暂存问题。
例:ADD (R0), R1
设指令为:
1 | ADD (R0), R1 |
其功能为:
1 | ((R0)) + (R1) -> (R0) |
含义是:R0 中保存一个主存地址,被加数在该主存单元中;R1 保存另一个加数;运算结果写回 R0 指向的主存单元。
这条指令在单总线结构下要关注三点:
- 主存地址要进入
MAR。 - 主存读出的操作数要暂存在
MDR,再送到Y。 - ALU 运算结果要先进入
Z或MDR,最后写回主存。
取指周期
| 时序 | 微操作 | 有效控制信号 | 说明 |
|---|---|---|---|
| 1 | (PC) -> Bus -> MAR |
PCout, MARin |
用 PC 给出当前指令地址 |
| 2 | 1 -> R,M(MAR) -> MDR |
MemR, MDRinE |
主存读,指令进入 MDR |
| 3 | (MDR) -> Bus -> IR |
MDRout, IRin |
指令送入 IR |
| 4 | (PC) + 1 -> PC |
PCadd, PCin |
形成下一条指令地址 |
有些数据通路会把 (PC)+1 -> PC 与主存读安排在同一节拍,这取决于是否有独立加法器和相应路径。分析题目时,应以给定数据通路为准。
间址或取数周期
这里 (R0) 已经是操作数所在主存单元的地址,因此要用 R0 访问主存并取出被加数。
| 时序 | 微操作 | 有效控制信号 | 说明 |
|---|---|---|---|
| 1 | (R0) -> Bus -> MAR |
R0out, MARin |
把操作数地址送入 MAR |
| 2 | 1 -> R,M(MAR) -> MDR |
MemR, MDRinE |
从主存读出被加数 |
| 3 | (MDR) -> Bus -> Y |
MDRout, Yin |
被加数进入 ALU 暂存输入 |
Y 的作用是保存一个 ALU 输入。否则下一步 R1 输出到总线时,主存读出的被加数就没有稳定位置可用。
执行与写回
| 时序 | 微操作 | 有效控制信号 | 说明 |
|---|---|---|---|
| 1 | (R1) -> Bus,(Y) + Bus -> Z |
R1out, Add, Zin |
R1 通过总线作为另一个 ALU 输入,结果进入 Z |
| 2 | (Z) -> Bus -> MDR |
Zout, MDRin |
结果送入 MDR,准备写主存 |
| 3 | 1 -> W,(MDR) -> M(MAR) |
MemW, MDRoutE |
按 MAR 中保存的地址写回结果 |
注意:执行与写回阶段仍然需要前面保存在 MAR 中的地址。如果中间又用 MAR 做了别的访存,写回地址就会丢失;这也是分析寄存器使用情况时必须检查的点。
专用结构的数据通路分析
专用结构的数据通路分析,第一步先看图中箭头。箭头说明某条数据通路是否存在,控制信号说明这条通路什么时候接通。
| 分析对象 | 要问的问题 |
|---|---|
| 线路占用 | 这条专用路径当前是否被使用?若多条路径进入同一部件,MUX 选择哪一路? |
| 数据流向 | 数据沿图中哪几条箭头流动?有没有反向箭头? |
| 寄存器使用 | 哪些寄存器保存地址、指令、数据或运算结果?是否需要跨周期保存? |
| 耗时 | 这些路径能否在同一节拍并行?是否涉及主存访问而需要等待存储周期? |
控制信号
在专用结构图中,C0、C1、C2 这类符号只是特定某图中某条路径或某个动作的编号。因此不能说C0 一定代表什么,必须看图标注。
以取指周期为例,可以写成:
| 微操作 | 控制信号含义 | 数据流向 |
|---|---|---|
(PC) -> MAR |
C0 有效 |
PC 中的指令地址送入 MAR |
M(MAR) -> 主存读路径 |
C1 有效 |
MAR 给出主存地址 |
1 -> R |
读控制有效 | CU 向主存发出读命令 |
M(MAR) -> MDR |
C2 有效 |
主存读出的指令进入 MDR |
(MDR) -> IR |
C3 有效 |
指令进入 IR |
(PC) + 1 -> PC |
独立加法路径或对应控制线有效 | PC 形成下一条指令地址 |
Op(IR) -> CU |
C4 有效 |
操作码送控制部件译码 |
某张图中 C0 可以表示 (PC)->MAR,另一张图中 C0 可能表示别的路径。编号只在当前图中有效。
| 项目 | 单总线结构 | 专用结构 |
|---|---|---|
| 写法重点 | 源部件 -> Bus -> 目的部件 |
源部件 -> 目的部件,必要时写经过 ALU、MUX、主存 |
| 控制信号 | 常写成 PCout, MARin |
常写成 C0, C1, ... 或题图给出的控制线 |
| 冲突来源 | 多个部件同时驱动同一总线 | 多个来源竞争同一个 MUX 输入、同一部件同一端口或同一存储器端口 |
| 并行性 | 单总线并行性较低 | 图上不同独立路径可在同一节拍并行 |
| 判断依据 | 谁输出到总线,谁从总线接收 | 图中是否有箭头,控制信号是否接通该路径 |
例如 MDR -> IR 在单总线结构中常写为:
1 | (MDR) -> Bus -> IR |
在专用结构中,如果图上有 MDR -> IR 的直接箭头,则写为:
1 | (MDR) -> IR |
这不是省略了总线,而是两种数据通路结构不同。
存取主存的数据通路
主存访问一般离不开 MAR 和 MDR:
| 操作 | 数据通路 | 说明 |
|---|---|---|
| 读主存 | 地址 -> MAR,M(MAR) -> MDR |
MAR 给地址,MDR 接收主存数据 |
| 写主存 | 地址 -> MAR,数据 -> MDR,(MDR) -> M(MAR) |
MAR 给地址,MDR 给待写数据 |
如果题图中运算器和主存之间通过 MDR、ALU、ACC 相连,则常见路径为:
1 | 取数:M(MAR) -> MDR -> ALU -> ACC |
这里 ALU 可能只是作为数据通过的组合通路,也可能执行加法、逻辑运算等具体操作。是否需要 ALU,取决于图中 MDR 到 ACC 是否必须经过 ALU。
例:LDA X、ADD Y、STA Z
设 X/Y/Z 都是主存地址,且图中存在 MDR -> ALU -> ACC、ACC -> MDR 等路径。
| 指令 | 功能 | 数据通路 |
|---|---|---|
LDA X |
(X) -> ACC |
X -> MAR,M(MAR) -> MDR,(MDR) -> ALU -> ACC |
ADD Y |
(ACC) + (Y) -> ACC |
Y -> MAR,M(MAR) -> MDR,(MDR) -> ALU,(ACC) -> ALU,ALU -> ACC |
STA Z |
(ACC) -> Z |
Z -> MAR,(ACC) -> MDR,(MDR) -> M(MAR) |
先确定地址怎么到 MAR,再确定数据怎么经过 MDR,最后看是否经过 ALU/ACC。不要因为熟悉单总线写法,就在专用结构中凭空加 Bus。
小结
数据通路题可以按下面顺序分析:
1 | 明确指令功能 |
最容易混淆的是两个维度:
| 不要混淆 | 正确理解 |
|---|---|
| 单总线、专用数据通路 | 这是内部连接方式 |
| 单周期、多周期、流水线数据通路 | 这是时序组织方式 |
| “一条指令一个周期” | 只对应单周期数据通路 |
| “一个微操作一个周期内完成” | 要看这一步是否能构成状态元件到状态元件的有效路径 |