控制器:把指令变成控制信号¶
数据通路像道路与加工站,控制器像每个岔路口的信号系统。没有控制信号,ALU 不知道做加法还是比较,存储器不知道读还是写,寄存器堆也不知道何时提交结果。
控制信号的来源¶
控制器主要读取操作码、功能字段、比较结果和当前控制状态,产生:
RegWrite:是否写寄存器;MemRead/MemWrite:数据存储器动作;ALUSrc:ALU 输入来自寄存器还是立即数;ALUOp:ALU 执行哪类操作;ResultSrc:写回值来自 ALU、内存或 PC;PCSrc:下一 PC 选择哪条路径。
一个简化控制表如下:
| 指令 | RegWrite | MemWrite | ALUSrc | ResultSrc | ALU 功能 |
|---|---|---|---|---|---|
add |
1 | 0 | 0 | ALU | 加法 |
addi |
1 | 0 | 1 | ALU | 加法 |
lw |
1 | 0 | 1 | 内存 | 地址加法 |
sw |
0 | 1 | 1 | 无 | 地址加法 |
beq |
0 | 0 | 0 | 无 | 比较 |
表格中最危险的不是“少做一次写入”,而是错误开启写使能,因为状态一旦提交就会污染后续执行。
两级译码¶
主译码器先根据 opcode 判定指令大类,给出数据通路选择和粗粒度 ALUOp;ALU 控制器再结合功能字段决定加、减、与、或、移位等具体操作。分层能减少一张巨型真值表的复杂度,也让相同地址加法被 load/store 共享。
硬布线控制¶
硬布线控制直接用组合逻辑或状态机从输入生成控制信号。它延迟低、适合规则 RISC 指令,但指令集复杂后逻辑设计与修改成本上升。
单周期控制主要是组合逻辑;多周期控制还要保存“当前处于取指、译码还是访存”的状态:
微程序控制¶
微程序控制把一条复杂指令展开为若干微指令,微指令存于控制存储器,每条给出一组底层控制动作。它像处理器内部的小解释器:易于实现复杂操作和修正某些缺陷,代价是多一层取微指令与调度开销。
现代处理器常混合使用:常见简单指令走硬布线快速路径,复杂或少见行为由微码序列完成。
最小例子:lw 的控制序列¶
多周期实现中,lw x5, 12(x10) 可分为:
- 用 PC 取指,PC 更新;
- 读
x10,符号扩展立即数; - ALU 计算有效地址并存入内部寄存器;
- 读取数据存储器;
- 开启
RegWrite,选择内存数据写入x5。
每一步只开启必要的写使能。若第 4 步触发异常,第 5 步必须被取消,体现“先确认、后提交”。
精确异常与控制边界¶
软件希望异常看起来发生在明确的指令边界:更早指令已完成,出错指令及更晚指令未改变架构状态。这叫精确异常。简单顺序 CPU 天然接近这个模型;乱序 CPU 则需要按程序顺序提交结果。
这和流水线控制直接相关:清空错误路径、冻结部分阶段、保存异常 PC 都是控制器的职责。
权衡与验证¶
控制逻辑本身不一定占最大面积,却决定状态能否正确更新。验证必须覆盖:所有操作码、非法编码、分支条件、异常与同时到来的外部事件。优化控制延迟可以提高频率,但过度复杂的控制也可能成为关键路径。
自测¶
RegWrite对 store 必须为何值?若错误置 1,可能破坏什么?- 硬布线与微程序控制分别适合什么场景?
- 为什么精确异常要求错误指令不能先写回再“补救”?