Skip to content

多周期数据通路

2026 大纲 五(三)数据通路的功能和基本结构

把一条指令拆开做,代价是要多几个寄存器

单周期有两个明摆着的毛病:时钟周期被最慢的指令绑架(beq 只走到 ALU 就结束,却要空等到周期末尾)、部件利用率极低(R 型执行期间数据存储器全闲,beq 执行期间寄存器堆的写端口全闲)。多周期的思路就是把一条指令拆成若干阶段,每阶段占一个时钟周期,且最多完成一次访存、或一次寄存器读写、或一次 ALU 操作;时钟周期以最复杂的那个单阶段为准,通常取一次存储器读写的时间。

但拆开做立刻带来一个新问题,它是本篇最本质的一处改动:

🔴 跨周期的数据必须存进状态元件。 单周期里中间结果全程挂在组合逻辑的导线上,根本不用保存;一旦拆成多周期,下一个周期同一个部件就被别的操作占用了,导线上的值立刻被冲掉。

于是多出五个寄存器(下一节逐个说)。其中 IR 是部件复用付出的代价:单周期里指令存储器的输出在整个周期内保持不变、不必锁存;多周期里存储器被复用(IF 取指令、MEM 读写数据),指令信息会被数据覆盖,所以必须在 IF 阶段就锁进 IR。

还有一个不那么显眼、但很值得知道的毛病:

单周期的第三个毛病:实际存储器的写时序竞争(想弄清"为什么教科书的单周期通路用真存储器搭不出来"时展开)

实际存储器的写不是边沿触发,而是一个组合逻辑过程:写使能有效、且地址与数据已经稳定之后,再经过一个写操作时间才真正写入——也就是说它要求地址和数据先于写使能稳定

单周期里这三者在同一个周期内同时变化,谁先稳定无法控制,所以用实际存储器搭的单周期数据通路并不能可靠工作。多周期先在第 n 周期确认地址与数据稳定、再让写使能在第 n+1 周期有效——把一件事拆到两个周期去做,先后顺序就被时钟钉死了

交互可视化

加载可视化中...

一、为什么必须新增中间寄存器

这是多周期设计中最本质的一处改动。跨周期的数据必须存进状态元件,于是多出五个寄存器:

寄存器存放内容不存会怎样
IR从内存取出的指令MEM 阶段存储器要读数据,指令输出被覆盖
MDR从内存读出/待写入的数据同上
A寄存器堆读出的第一个操作数EX 阶段寄存器堆输出已不保证有效
B寄存器堆读出的第二个操作数同上
ALUOutALU 的运算结果下周期 ALU 要算别的,结果被冲掉

🔴 这五个里 A、B 无须写使能。 判断一个寄存器要不要写使能,看它的值是否需要跨越多个周期保持:PC、IR、寄存器堆只在需要时才写入,必须有写使能;A、B 是纯临时寄存器,每来一个时钟都可以改,改错了下一个用到它们的阶段会重新装载。

⚠️ 这五个寄存器对程序员全部不可见——它们是实现细节,指令集里没有指令能触碰;换成单周期实现它们就不存在了。同时它们也是流水线段间寄存器的前身,下一章会看到同一个思路被推到底。

二、五个执行阶段

阶段 1 取指(IF)IRM[PC]PCPC+4。其中 PC+4 复用 ALU 计算——单周期需要一个专门的加法器,多周期不用了。

阶段 2 译码 / 读寄存器(ID):读出 rs、rt 对应的寄存器值到 A、B,同时提前计算分支目标地址。

AReg[IR25:21],BReg[IR20:16]ALUOutPC+(SEXT(IR15:0)2)

阶段 3 执行 / 地址计算(EX)

指令类型ALU 操作结果送入
R 型A op B(由 funct 决定)ALUOut
lw / swA + SEXT(imm)ALUOut(有效地址)
beqA B,检查 Zero若相等则直接更新 PC

阶段 4 访存 / R 型完成(MEM):lw 做 MDRM[ALUOut];sw 做 M[ALUOut]B;R 型做 Reg[IR15:11]ALUOut(R 型在此阶段结束)。

阶段 5 写回(WB,仅 lw 需要)Reg[IR20:16]MDR

三、各指令所需周期数

指令类型周期数阶段
lw5IF → ID → EX → MEM → WB
R 型4IF → ID → EX → MEM(在此写回)
sw4IF → ID → EX → MEM
beq3IF → ID → EX
无条件跳转 j3IF → ID → EX

lw 比 R 型多一个周期:R 型的结果已经在 ALUOut 里,MEM 阶段可以直接写回寄存器堆;而 lw 的数据在 MEM 阶段才刚从内存读进 MDR,还需要再花一个周期才能写进寄存器。

图 5.26 指令执行状态转换图
图 5.26 指令执行状态转换图
(袁春风《计算机组成与系统结构》第 3 版,见文末教材出处)

图里不同指令走不同的分支路径,路径的长度就是该指令占用的时钟周期数。这也解释了控制器为什么只能做成状态机:

🔴 同一条指令在不同周期要发出不同的控制信号,而"现在是这条指令的第几步"这个信息不在指令里,只能由控制器自己记住——能记住状态的电路就是时序逻辑。每个状态对应一个时钟周期、发一组信号,再按操作码决定下一个状态;路径有多长,这条指令就占几个时钟周期。对照单周期的纯组合逻辑控制器,这是两者最根本的差别。

⚠️ 周期数由"最后一个有实际动作的阶段"决定,不是由"看起来简不简单"决定。 beq 只用 3 个周期是因为它既不访存也不写寄存器——EX 算完减法、判完 Zero,PC 就可以更新了;sw 同样不写寄存器却要访存,所以是 4 个周期。

⚠️ 时钟周期也不一定等于存取周期。 它由最复杂的单个阶段决定,多数设计里最慢的一步是访存,所以教材常直接取存取周期;若某设计中 ALU 比访存还慢,就以 ALU 延迟为准。

顺带说一处设计上的巧思:ID 阶段提前计算分支目标地址是零成本的投机。那个周期 ALU 本来就闲着(操作数刚读出来还没送到它那儿),顺手算一个地址不花额外时间;不算的话,等确认是分支指令之后再算就要多占一个周期。之所以能这么做,是因为指令被译码之前,所有指令做的操作完全一样——这正是 IF、ID 能设计成公共阶段的前提。

四、单周期与多周期对比

对比项单周期多周期
时钟周期最慢指令决定最慢单步决定
CPI恒为 13~5(视指令类型)
控制信号一条指令内不变逐周期变化
硬件利用率低(大量部件闲置)高(部件跨阶段复用)
存储器必须分开(哈佛结构)可用单一存储器
加法器需要多个复用 ALU 即可
中间寄存器不需要必需(IR/MDR/A/B/ALUOut)
控制逻辑组合逻辑时序逻辑(状态机)
把"必须看乘积"落到数字上:一段指令构成下多周期与单周期哪个更快(想弄清 CPI 涨了为什么反而更快时展开)

设某程序的指令构成为 R 型 40%、lw 30%、sw 15%、beq 10%、j 5%。按上表的周期数加权平均:

CPI=0.40×4+0.30×5+0.15×4+0.10×3+0.05×3=4.15

若该多周期 CPU 的时钟周期为 2 ns,则平均每条指令耗时 4.15×2=8.3 ns。作为对比,同样的通路做成单周期时,时钟周期要按 lw 的全程延迟取(设为 10 ns),每条指令耗时 10 ns——多周期更快

CPI 从 1 涨到 4.15 看起来是退步,但时钟周期从 10 ns 降到 2 ns,乘积才是结论。

考点速记

  1. 多周期是为治单周期的三个毛病而来:时钟周期被最慢指令绑架部件利用率极低,以及实际存储器写操作的时序竞争;它把时钟周期从"最慢指令的全程"缩短到"最慢的一步",不同指令占用不同数目的周期。
  2. 跨周期的数据必须存进状态元件,因此新增 IR、MDR、A、B、ALUOutIR 的存在正是部件复用的代价,A、B 因不需跨周期保持而无须写使能;五者对程序员全部不可见。
  3. 控制器必须是状态机——同一条指令在不同周期要发不同信号,所以多周期的控制信号逐周期变化(单周期则一条指令内不变);多周期 CPI 涨到 4 左右但时钟周期大幅缩短,必须看乘积才能比较性能

这一节在真题里被考过的形式(下方「真题练习」里属于本篇的那几道):

  • 问哪几类处理器理想情况下 CPI 为 1 / 判断数据通路结构与 CPI 的关系多周期 CPI >1(每条指令要走 3~5 个阶段),这一项本身就是判断题的一个选项。单周期与基本流水线为 1、超标量 <1,完整对照见 单周期数据通路
  • 挑关于数据通路 / 控制器的错误叙述里涉及多周期的那一项:常出现的是"单周期 CPU 的控制器比多周期 CPU 的更简单"——这句是对的,单周期控制器是纯组合逻辑,多周期的是状态机。

易错:认为 CPI 变大就是性能变差。执行时间 = 指令数 × CPI × 时钟周期,多周期把时钟周期压下去了,要看乘积。

易错:把"控制信号逐周期变化"安到单周期头上。那是多周期的特征。

易错:以为 beq 只要 3 个周期是因为它"简单"。是因为它不访存也不写寄存器。

教材出处
  • 多周期处理器的设计思想、每阶段的操作约束:袁春风《计算机组成与系统结构》第 3 版 §5.3.1 多周期处理器设计思想,印刷页 p150
  • 实际存储器写操作的竞争问题及其在多周期中的解决方式:同上,印刷页 p150–p151
  • 多周期数据通路与写使能信号的配置(图 5.25)、指令执行状态转换图(图 5.26):同上,§5.3.2 多周期数据通路设计,印刷页 p151、p154

相关知识

单周期数据通路硬布线控制器微程序控制器

真题练习