数据通路的组成

上一节说清了数据通路要提供什么功能。这一节把提供这些功能的零件逐个拆开。

零件一共就六类,但其中两类——多路选择器和译码器——是整个 5.3 里最容易读过去又最要命的地方。它们看着像数字电路的边角料,实际上是**“数据线和控制线”这条主线在硬件上的具体化身**:一个的输出是数据,另一个的输出是控制信号。分不清它们,寄存器堆的读写端口、单总线的多源选择、主存的地址译码,三处都会跟着含糊。

机制

六类零件

零件干什么输出是
ALU算术逻辑运算,置标志位数据
移位器左移 / 右移 / 直送数据
寄存器(GPRs、暂存器、PC、IR、MAR、MDR)跨拍存住值数据
多路选择器 MUX多选一数据
译码器 Decoder一变多、只中一根控制信号
三态门 / 总线让多个源共用一条线数据

多路选择器与译码器:方向相反的一对

疑问点:地址译码器和多路选择器分别是什么?各用在哪些地方?

两者的形状正好相反,而”相反”这件事就是它们的分工判据。

译码器 Decoder多路选择器 MUX
形状 根输入 → 根输出 路数据输入 + 位选择 → 1 路输出
信息流向一进多出(展开)多进一出(收缩)
输入的含义一个编号一堆候选值
输出的含义 根线里只有一根有效 → 这是控制信号被选中的那个值 → 这是数据
一句话把”编号”翻译成”选中谁”把”多个值”收成”一个值”

判据:译码器输出控制信号,MUX 输出数据。 这正是 5.3.1 那条主线判据的硬件形态——所以图上凡是从译码器出来的线,画成虚线(控制);凡是从 MUX 出来的线,画成实线(数据)。

各自的用武之地:

场景用译码器用 MUX
寄存器堆写端口(rd)✅ 把编号译成”哪个寄存器的写使能有效”❌
寄存器堆读端口(rs)❌✅ 从 16 个寄存器的输出里挑一个送出去
主存地址译码(选中哪个存储单元 / 哪个芯片)✅ 见 3.3.3❌
指令译码(操作码 → 哪条指令)✅ 条指令 根线,见 5.4.2❌
ALU 输入端选数据来源❌✅ 选”寄存器的值”还是”立即数”还是”常数 2”
微程序控制器取微指令✅ 微地址译码❌

反过来记最快:凡是”我要给谁发信号”用译码器,凡是”我要从谁那里取值”用 MUX。

所以那道真题问 rd 该接哪个,答案是地址译码器——rd 是写端口的编号,写的动作是”把总线上的值送进第 号寄存器”,需要的是第 号寄存器的写使能信号,那正是译码器的输出。而 rs 是读端口编号,读的动作是”把第 号寄存器的值取出来”,需要从一堆值里挑一个,用 MUX。

顺带答了同一题的另一问:rs 和 rd 来自 IR——它们是指令里的寄存器编号字段(4.1.2)。寄存器最多有多少个,由 rs / rd 字段的位数决定: 位编号 → 最多 个寄存器。

疑问点:MUX 的输入是不是非常多?比如 16 个寄存器就是 寄存器位宽

完全正确,而且这个数量正是寄存器堆不能无限做大的硬件理由。

要点在于 MUX 沿两个方向扩展,而这两个方向的代价完全不同:

方向怎么扩代价
路数(选几个里的一个)16 选 1 需要 4 位选择信号选择信号只要 位,增长很慢;但延迟随 增长
位宽(每个值多少位)32 位就并排放 32 个 1 位 MUX数据线数量线性翻倍;但共用同一组选择信号,延迟不变

所以一个”16 选 1 的 32 位 MUX” = 32 个 16 选 1 的 1 位 MUX 并排,共用那 4 根选择线,数据输入线共 根。你估的数量级是对的。

由此得到两条真实约束:

  1. 面积:数据线数 读端口数。双读端口的 32×32 寄存器堆,光 MUX 部分就是 2048 根输入线。
  2. 延迟:MUX 通常做成树形,延迟约 ——它直接算在 的关键路径里(5.3.1 末尾那个式子)。寄存器越多,主频上限越低。

这是”寄存器数量不能太多”的第二个理由。 4.1.2 已经给了第一个:寄存器编号要占指令的位数,寄存器多则指令长。一个来自指令编码,一个来自硬件成本,两条互相独立却指向同一个结论——这就是为什么主流 RISC 定在 32 个通用寄存器而不是 256 个。

补一句实现层面的实话:真实的大寄存器堆很少用纯 MUX 树,而是用位线 + 三态门/传输门——每个寄存器把自己的输出挂到共享位线上,由译码器选中的那一个才驱动位线。这在逻辑上仍是”多选一”,但面积从 根线变成 根共享线。408 考试按 MUX 的逻辑模型答即可,但知道这一层能解释”为什么图上寄存器堆的读端口有时画成 MUX、有时画成一条竖线”。

寄存器堆:读用选择,写用选中

把上面两条合起来,寄存器堆的完整结构就确定了:

flowchart LR
    IRf["IR 的寄存器编号字段"]
    rs["rs(读编号)"]
    rd["rd(写编号)"]
    MUXb["MUX<br/>多选一"]
    DEC["译码器<br/>一变多"]
    REGS["R0 R1 … Rk-1"]
    OUT["读出的数据 → 总线 / ALU"]
    IN["待写入的数据(来自总线)"]

    IRf --> rs
    IRf --> rd
    REGS -->|各寄存器输出| MUXb
    rs -->|选择信号| MUXb
    MUXb --> OUT
    rd --> DEC
    DEC -->|写使能,只中一根| REGS
    IN --> REGS

    classDef data fill:#dbeafe,stroke:#2563eb,stroke-width:2px
    classDef ctrl fill:#fde68a,stroke:#d97706,stroke-width:2px
    class REGS,MUXb,OUT,IN data
    class DEC,rs,rd ctrl

两条端口数的规则:

  • 一个读端口需要一整套 MUX。 要支持 ADD R1, R2, R3 这样同时读两个源操作数,就需要两个读端口 = 两套 MUX。
  • 一个写端口只需要一个译码器(外加写使能)。所以典型的寄存器堆是”两读一写”。

这解释了 4.4.2 说的”RISC 的三地址指令为什么可行”:三地址需要两读一写,而两读一写正是寄存器堆的标准配置。二地址指令要覆盖一个源操作数,恰恰是因为早期机器省掉了第二个读端口或那条回写通路(4.1.2)。

三态门与内部总线

一条总线上可以挂很多个输出源,但同一时刻只能有一个在驱动它。 实现这件事的零件是三态门:它有三种输出状态——0、1、高阻。高阻态相当于”把自己从线上摘下去”。

寄存器的输出三态门内部总线

控制信号 Riout 就是这个三态门的使能。 所以数据通路图上写的 R1out、MDRout、PCout,指的都是”打开这个寄存器到总线的三态门”。

由此得到单总线结构最硬的一条约束:

同一拍内,Xout 类控制信号只能有一个有效。

两个三态门同时驱动同一根线会造成总线冲突(电气上是短路),这是排拍题里判断”这两个微操作能不能并行”的第一条规则,见 5.3.4。

相反,Xin 类信号可以同时有多个有效——多个寄存器同时从总线接收同一个值是完全合法的(比如 PC → MAR 的同时也可以 PC → Y)。这个不对称是排拍题最常考的一处。

ALU 与移位器

ALU 在数据通路里只有三个接口值得关心:

  • 两个数据输入端——它们的来源决定了数据通路的结构类型(5.3.3)
  • ALUop 控制端——位数 功能个数
  • 输出端 + 标志位输出——输出通常先进暂存器,标志位进 PSW

移位器(SR)可能独立存在,也可能并入 ALU。 独立时有自己的 SRop,位数同样按功能个数取对数。判断题目属于哪种,看图上有没有单独画出移位器方框。移位的三种类型见 2.2.2。

注意一个反直觉的事实:ALU 的功能表里常有一项”直送 A(mova)“,看起来毫无用处——把 A 原样输出,何必经过 ALU?它的用处在 5.3.3 揭晓:某些结构下,寄存器之间的传送必须穿过 ALU,mova 就是为此存在的。

主存接口:MAR 与 MDR

MARMDR
位数主存地址位数存储字长
方向单向(CPU → 主存)双向
控制信号MARinMDRin、MDRout、以及主存的 Read / Write

MDR 的双向性是它比 MAR 复杂的地方:读主存时数据从外面进来,写主存时数据从里面出去。所以 MDR 实际上有两组进出——对内总线的 MDRin/MDRout,对外总线的读写。数据通路图上有时会把这两侧分开画。

访存不是一拍完成的。 题目通常假设”主存读写各需若干个时钟周期”,期间 CPU 要等待 Ready 信号——这个等待就是 3.1.2 那个速度差距在 CPU 内部的直接表现,也是 Cache 存在的理由。

边界

层次辨析:译码器 / 多路选择器

  • 译码器: 进 出,输出是控制信号(只有一根有效),用于**“发给谁”**——寄存器写使能、主存地址译码、指令译码
  • MUX: 进 1 出,输出是数据,用于**“从谁取”**——寄存器读端口、ALU 输入选择

寄存器堆里两个都有:rd 接译码器(写),rs 接 MUX(读)。

边界辨析: Xout 可否并行 / Xin 可否并行

  • Xout 同一拍只能有一个——多个三态门同时驱动总线会冲突
  • Xin 同一拍可以有多个——多个寄存器接收同一个值合法

这条不对称是排拍题的第一判据。只在单总线结构下成立;多总线结构下每条总线各自遵守这条规则。

边界辨析:MAR 位数 / MDR 位数

  • MAR = 主存地址位数(由地址空间大小定)
  • MDR = 存储字长(由主存一次存取多少位定)

二者没有必然关系。“按字节编址、 个单元、存取单位 32 位” → MAR 20 位、MDR 32 位。

对照速查

部件输出是数据还是控制典型控制信号位数
ALU数据 + 标志ALUop功能数
移位器 SR数据SRop、SRout功能数
MUX数据选择端(来自控制器或 IR)选择端 路数
译码器控制输入是编号 进 出
三态门数据Xout1 位使能
寄存器数据Xin(写使能)1 位使能
题目问什么怎么算
ALUop 至少几位数 ALU 的功能个数,取
SRop 至少几位数移位器功能个数(含直送),取对数
最多有多少个通用寄存器看 rs/rd 字段位数 ,答
rs/rd 来自哪IR
rd 接译码器还是 MUX译码器(写要使能)

考点

  • rd 接译码器、rs 接 MUX:2010 年真题原问,判据是”写要使能、读要选择”。
  • ALUop / SRop 位数:数功能个数取对数。别忘了把”直送”也算作一种功能。
  • 通用寄存器最多几个:由 rs/rd 字段位数决定。
  • 总线冲突判断:同一拍两个 Xout → 不可并行。这是排拍题的第一步筛查。
  • MAR / MDR 位数:分别对应地址位数与存储字长,见 5.1.3。

链接