Appearance
多周期数据通路
2026 大纲 五(三)数据通路的功能和基本结构。
把一条指令拆开做,代价是要多几个寄存器
单周期有两个明摆着的毛病:时钟周期被最慢的指令绑架(beq 只走到 ALU 就结束,却要空等到周期末尾)、部件利用率极低(R 型执行期间数据存储器全闲,beq 执行期间寄存器堆的写端口全闲)。多周期的思路就是把一条指令拆成若干阶段,每阶段占一个时钟周期,且最多完成一次访存、或一次寄存器读写、或一次 ALU 操作;时钟周期以最复杂的那个单阶段为准,通常取一次存储器读写的时间。
但拆开做立刻带来一个新问题,它是本篇最本质的一处改动:
🔴 跨周期的数据必须存进状态元件。 单周期里中间结果全程挂在组合逻辑的导线上,根本不用保存;一旦拆成多周期,下一个周期同一个部件就被别的操作占用了,导线上的值立刻被冲掉。
于是多出五个寄存器(下一节逐个说)。其中 IR 是部件复用付出的代价:单周期里指令存储器的输出在整个周期内保持不变、不必锁存;多周期里存储器被复用(IF 取指令、MEM 读写数据),指令信息会被数据覆盖,所以必须在 IF 阶段就锁进 IR。
还有一个不那么显眼、但很值得知道的毛病:
单周期的第三个毛病:实际存储器的写时序竞争(想弄清"为什么教科书的单周期通路用真存储器搭不出来"时展开)
实际存储器的写不是边沿触发,而是一个组合逻辑过程:写使能有效、且地址与数据已经稳定之后,再经过一个写操作时间才真正写入——也就是说它要求地址和数据先于写使能稳定。
单周期里这三者在同一个周期内同时变化,谁先稳定无法控制,所以用实际存储器搭的单周期数据通路并不能可靠工作。多周期先在第
交互可视化
一、为什么必须新增中间寄存器
这是多周期设计中最本质的一处改动。跨周期的数据必须存进状态元件,于是多出五个寄存器:
| 寄存器 | 存放内容 | 不存会怎样 |
|---|---|---|
| IR | 从内存取出的指令 | MEM 阶段存储器要读数据,指令输出被覆盖 |
| MDR | 从内存读出/待写入的数据 | 同上 |
| A | 寄存器堆读出的第一个操作数 | EX 阶段寄存器堆输出已不保证有效 |
| B | 寄存器堆读出的第二个操作数 | 同上 |
| ALUOut | ALU 的运算结果 | 下周期 ALU 要算别的,结果被冲掉 |
🔴 这五个里 A、B 无须写使能。 判断一个寄存器要不要写使能,看它的值是否需要跨越多个周期保持:PC、IR、寄存器堆只在需要时才写入,必须有写使能;A、B 是纯临时寄存器,每来一个时钟都可以改,改错了下一个用到它们的阶段会重新装载。
⚠️ 这五个寄存器对程序员全部不可见——它们是实现细节,指令集里没有指令能触碰;换成单周期实现它们就不存在了。同时它们也是流水线段间寄存器的前身,下一章会看到同一个思路被推到底。
二、五个执行阶段
阶段 1 取指(IF):
阶段 2 译码 / 读寄存器(ID):读出 rs、rt 对应的寄存器值到 A、B,同时提前计算分支目标地址。
阶段 3 执行 / 地址计算(EX):
| 指令类型 | ALU 操作 | 结果送入 |
|---|---|---|
| R 型 | A op B(由 funct 决定) | ALUOut |
| lw / sw | A + SEXT(imm) | ALUOut(有效地址) |
| beq | A | 若相等则直接更新 PC |
阶段 4 访存 / R 型完成(MEM):lw 做
阶段 5 写回(WB,仅 lw 需要):
三、各指令所需周期数
| 指令类型 | 周期数 | 阶段 |
|---|---|---|
| lw | 5 | IF → ID → EX → MEM → WB |
| R 型 | 4 | IF → ID → EX → MEM(在此写回) |
| sw | 4 | IF → ID → EX → MEM |
| beq | 3 | IF → ID → EX |
| 无条件跳转 j | 3 | IF → ID → EX |
lw 比 R 型多一个周期:R 型的结果已经在 ALUOut 里,MEM 阶段可以直接写回寄存器堆;而 lw 的数据在 MEM 阶段才刚从内存读进 MDR,还需要再花一个周期才能写进寄存器。

(袁春风《计算机组成与系统结构》第 3 版,见文末教材出处)
图里不同指令走不同的分支路径,路径的长度就是该指令占用的时钟周期数。这也解释了控制器为什么只能做成状态机:
🔴 同一条指令在不同周期要发出不同的控制信号,而"现在是这条指令的第几步"这个信息不在指令里,只能由控制器自己记住——能记住状态的电路就是时序逻辑。每个状态对应一个时钟周期、发一组信号,再按操作码决定下一个状态;路径有多长,这条指令就占几个时钟周期。对照单周期的纯组合逻辑控制器,这是两者最根本的差别。
⚠️ 周期数由"最后一个有实际动作的阶段"决定,不是由"看起来简不简单"决定。 beq 只用 3 个周期是因为它既不访存也不写寄存器——EX 算完减法、判完 Zero,PC 就可以更新了;sw 同样不写寄存器却要访存,所以是 4 个周期。
⚠️ 时钟周期也不一定等于存取周期。 它由最复杂的单个阶段决定,多数设计里最慢的一步是访存,所以教材常直接取存取周期;若某设计中 ALU 比访存还慢,就以 ALU 延迟为准。
顺带说一处设计上的巧思:ID 阶段提前计算分支目标地址是零成本的投机。那个周期 ALU 本来就闲着(操作数刚读出来还没送到它那儿),顺手算一个地址不花额外时间;不算的话,等确认是分支指令之后再算就要多占一个周期。之所以能这么做,是因为指令被译码之前,所有指令做的操作完全一样——这正是 IF、ID 能设计成公共阶段的前提。
四、单周期与多周期对比
| 对比项 | 单周期 | 多周期 |
|---|---|---|
| 时钟周期 | 最慢指令决定 | 最慢单步决定 |
| CPI | 恒为 1 | 3~5(视指令类型) |
| 控制信号 | 一条指令内不变 | 逐周期变化 |
| 硬件利用率 | 低(大量部件闲置) | 高(部件跨阶段复用) |
| 存储器 | 必须分开(哈佛结构) | 可用单一存储器 |
| 加法器 | 需要多个 | 复用 ALU 即可 |
| 中间寄存器 | 不需要 | 必需(IR/MDR/A/B/ALUOut) |
| 控制逻辑 | 组合逻辑 | 时序逻辑(状态机) |
把"必须看乘积"落到数字上:一段指令构成下多周期与单周期哪个更快(想弄清 CPI 涨了为什么反而更快时展开)
设某程序的指令构成为 R 型 40%、lw 30%、sw 15%、beq 10%、j 5%。按上表的周期数加权平均:
若该多周期 CPU 的时钟周期为 2 ns,则平均每条指令耗时
CPI 从 1 涨到 4.15 看起来是退步,但时钟周期从 10 ns 降到 2 ns,乘积才是结论。
考点速记
- 多周期是为治单周期的三个毛病而来:时钟周期被最慢指令绑架、部件利用率极低,以及实际存储器写操作的时序竞争;它把时钟周期从"最慢指令的全程"缩短到"最慢的一步",不同指令占用不同数目的周期。
- 跨周期的数据必须存进状态元件,因此新增 IR、MDR、A、B、ALUOut;IR 的存在正是部件复用的代价,A、B 因不需跨周期保持而无须写使能;五者对程序员全部不可见。
- 控制器必须是状态机——同一条指令在不同周期要发不同信号,所以多周期的控制信号逐周期变化(单周期则一条指令内不变);多周期 CPI 涨到 4 左右但时钟周期大幅缩短,必须看乘积才能比较性能。
这一节在真题里被考过的形式(下方「真题练习」里属于本篇的那几道):
- 问哪几类处理器理想情况下 CPI 为 1 / 判断数据通路结构与 CPI 的关系:多周期 CPI
(每条指令要走 3~5 个阶段),这一项本身就是判断题的一个选项。单周期与基本流水线为 1、超标量 ,完整对照见 单周期数据通路。 - 挑关于数据通路 / 控制器的错误叙述里涉及多周期的那一项:常出现的是"单周期 CPU 的控制器比多周期 CPU 的更简单"——这句是对的,单周期控制器是纯组合逻辑,多周期的是状态机。
易错:认为 CPI 变大就是性能变差。执行时间
指令数 CPI 时钟周期,多周期把时钟周期压下去了,要看乘积。
易错:把"控制信号逐周期变化"安到单周期头上。那是多周期的特征。
易错:以为 beq 只要 3 个周期是因为它"简单"。是因为它不访存也不写寄存器。
教材出处
- 多周期处理器的设计思想、每阶段的操作约束:袁春风《计算机组成与系统结构》第 3 版 §5.3.1 多周期处理器设计思想,印刷页 p150
- 实际存储器写操作的竞争问题及其在多周期中的解决方式:同上,印刷页 p150–p151
- 多周期数据通路与写使能信号的配置(图 5.25)、指令执行状态转换图(图 5.26):同上,§5.3.2 多周期数据通路设计,印刷页 p151、p154