数据通路的组成
上一节说清了数据通路要提供什么功能。这一节把提供这些功能的零件逐个拆开。
零件一共就六类,但其中两类——多路选择器和译码器——是整个 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 根选择线,数据输入线共
根。你估的数量级是对的。 由此得到两条真实约束:
- 面积:数据线数
。双读端口的 32×32 寄存器堆,光 MUX 部分就是 2048 根输入线。 - 延迟: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
| MAR | MDR | |
|---|---|---|
| 位数 | 主存地址位数 | 存储字长 |
| 方向 | 单向(CPU → 主存) | 双向 |
| 控制信号 | MARin | MDRin、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) | 选择端 |
| 译码器 | 控制 | 输入是编号 | |
| 三态门 | 数据 | Xout | 1 位使能 |
| 寄存器 | 数据 | 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。
链接
- 🏠 返回总览:计算机组成原理第 5 章:中央处理器总览
- ⬅️ 上一节:5.3.1 数据通路的功能
- ➡️ 下一节:5.3.3 数据通路的基本结构
- 🔗 主存地址译码:3.3.3 存储器的地址译码
- 🔗 寄存器编号占指令位数:4.1.2 指令的基本格式
- 🔗 移位的三种类型:2.2.2 定点数的移位运算
- 🖼️ 配图:寄存器堆读写、MUX 与译码器图
- 📖 名词库:第 5 章名词库