控制单元
概述
- 用途:控制单元是 DigiSim 8位计算机架构的协调组件。它生成必要的控制信号,以协调程序计数器、内存(RAM)、指令寄存器、ALU、标志寄存器和其他组件来执行完整的指令集。
- 符号:控制单元由矩形方块表示,包含多个输入和输出引脚,用于与各种CPU组件接口。
- DigiSim.io 角色:控制单元通过取指-解码-执行-存储周期正确排序和控制所有系统组件,实现创建完整的功能性8位计算机。

功能描述
状态机操作
控制单元作为4状态有限状态机运行,循环通过:
- FETCH(取指):从内存检索下一条指令
- DECODE(解码):解码指令并递增程序计数器
- EXECUTE(执行):执行指令指定的操作
- STORE(存储):存储结果并根据需要更新标志
输入和输出
输入(7个引脚):
| 引脚 | 引脚名称 | 类型 | 描述 |
|---|---|---|---|
| 0 | CLK | 输入 | 同步操作的系统时钟 |
| 1 | RST | 输入 | 初始化控制单元的复位信号 |
| 2 | OP0 | 输入 | 来自指令寄存器的操作码位 0 |
| 3 | OP1 | 输入 | 来自指令寄存器的操作码位 1 |
| 4 | OP2 | 输入 | 来自指令寄存器的操作码位 2 |
| 5 | OP3 | 输入 | 来自指令寄存器的操作码位 3 |
| 6 | Z_FLAG | 输入 | 来自标志寄存器的零标志,用于条件跳转 |
输出(18个引脚):
| 引脚 | 引脚名称 | 类型 | 描述 |
|---|---|---|---|
| 0 | PC_INC | 输出 | 递增程序计数器 |
| 1 | PC_LD | 输出 | 加载程序计数器(用于跳转) |
| 2 | PC_OE | 输出 | 程序计数器输出使能(到地址总线) |
| 3 | MEM_RD | 输出 | 内存读使能 |
| 4 | MEM_WR | 输出 | 内存写使能 |
| 5 | RAM_OE | 输出 | RAM输出使能(到数据总线) |
| 6 | IR_LD | 输出 | 指令寄存器加载 |
| 7 | IR_ADDR_OE | 输出 | IR地址输出使能(到地址总线) |
| 8 | ALU_OP0 | 输出 | ALU操作码位 0 |
| 9 | ALU_OP1 | 输出 | ALU操作码位 1 |
| 10 | ALU_OP2 | 输出 | ALU操作码位 2 |
| 11 | ALU_OE | 输出 | ALU输出使能(到数据总线) |
| 12 | ACC_LD | 输出 | 累加器加载 |
| 13 | ACC_OE | 输出 | 累加器输出使能(到数据总线) |
| 14 | FLG_LD | 输出 | 标志寄存器加载 |
| 15 | HALT | 输出 | 系统停机指示 |
| 16 | STATE0 | 输出 | 状态位 0(2位状态编码的LSB) |
| 17 | STATE1 | 输出 | 状态位 1(2位状态编码的MSB) |
状态编码(STATE1:STATE0):
00→ FETCH(取指)01→ DECODE(解码)10→ EXECUTE(执行)11→ STORE(存储)
指令集架构
控制单元支持16条指令集,使用4位操作码:
| 操作码 | 十六进制 | 助记符 | 描述 | 操作 |
|---|---|---|---|---|
| 0000 | 0x0 | NOP | 空操作 | PC ← PC + 1 |
| 0001 | 0x1 | LDA addr | 加载累加器 | ACC ← M[addr] |
| 0010 | 0x2 | STA addr | 存储累加器 | M[addr] ← ACC |
| 0011 | 0x3 | ADD addr | 加到累加器 | ACC ← ACC + M[addr] |
| 0100 | 0x4 | SUB addr | 从累加器减 | ACC ← ACC - M[addr] |
| 0101 | 0x5 | AND addr | 逻辑与 | ACC ← ACC & M[addr] |
| 0110 | 0x6 | OR addr | 逻辑或 | ACC ← ACC | M[addr] |
| 0111 | 0x7 | XOR addr | 逻辑异或 | ACC ← ACC ^ M[addr] |
| 1000 | 0x8 | NOT | 逻辑非 | ACC ← ~ACC |
| 1001 | 0x9 | SHL | 左移 | ACC ← ACC << 1 |
| 1010 | 0xA | SHR | 右移 | ACC ← ACC >> 1 |
| 1011 | 0xB | JMP addr | 无条件跳转 | PC ← addr |
| 1100 | 0xC | JZ addr | 为零则跳转 | if (Z=1) PC ← addr |
| 1101 | 0xD | JNZ addr | 非零则跳转 | if (Z=0) PC ← addr |
| 1110 | 0xE | LDI | 立即加载 | 保留供将来使用 |
| 1111 | 0xF | HLT | 停机 | 停止执行 |
指令格式
| 位位置 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| 字段 | 操作码(4位) | 操作数(4位) | ||||||
| 描述 | 要执行的操作 | 内存地址/值 |
微代码架构
控制信号生成
控制单元使用微代码ROM方法,每条指令被分解为跨四个状态的微操作。操作码和状态的每种组合产生一组特定的控制信号。
示例:LDA(加载累加器)指令
FETCH状态:
- PC_OE = 1(PC驱动地址总线)
- MEM_RD = 1(从内存读取指令)
- IR_LD = 1(将指令加载到IR)
DECODE状态:
- PC_INC = 1(递增PC到下一条指令)
EXECUTE状态:
- IR_ADDR_OE = 1(IR地址驱动地址总线)
- MEM_RD = 1(从内存地址读取数据)
STORE状态:
- RAM_OE = 1(RAM驱动数据总线)
- ACC_LD = 1(将数据加载到累加器)
- FLG_LD = 1(更新标志)
总线控制和三态管理
控制单元通过确保任何时候只有一个组件驱动每条总线来小心管理总线竞争:
- 地址总线:由 PC_OE 或 IR_ADDR_OE 控制
- 数据总线:由 RAM_OE、ALU_OE 或 ACC_OE 控制
与其他组件的集成
组件兼容性
控制单元设计为与 DigiSim 现有组件无缝协作:
- 8位ALU:接收操作码(ALU_OP0-2)并提供带标志的结果
- 程序计数器:通过 PC_INC、PC_LD 和 PC_OE 信号控制
- RAM(256×8):通过 MEM_RD、MEM_WR 和 RAM_OE 信号管理
- 指令寄存器:通过 IR_LD 加载,提供操作码/地址分离
- 标志寄存器:通过 FLG_LD 更新,为条件跳转读取(Z_FLAG)
- 累加器:通过 ACC_LD 和 ACC_OE 信号控制
信号时序
控制单元确保所有组件的正确建立和保持时间:
- 地址建立:地址信号在内存操作之前稳定
- 数据有效:加载信号有效时数据有效
- 时钟同步:所有状态变化在时钟上升沿发生
- 复位行为:立即异步复位到已知状态
使用示例
简单程序:两数相加
; 将存储在内存中的两个数相加
0x0: LDA 0x8 ; 从地址 0x8 加载第一个数
0x1: ADD 0x9 ; 加上地址 0x9 的第二个数
0x2: STA 0xA ; 将结果存储到地址 0xA
0x3: HLT ; 停机
...
0x8: 0x05 ; 第一个数(5)
0x9: 0x03 ; 第二个数(3)
0xA: 0x00 ; 结果位置
循环示例:从1计数到10
; 从0计数到10
0x0: LDA 0x8 ; 加载计数器
0x1: ADD 0x9 ; 加1
0x2: STA 0x8 ; 存储计数器
0x3: SUB 0xA ; 减10
0x4: JNZ 0x0 ; 非零则跳回
0x5: HLT ; 完成后停机
...
0x8: 0x00 ; 计数器
0x9: 0x01 ; 常量 1
0xA: 0x0A ; 常量 10
技术说明
时钟要求
- 最低频率:1 Hz,用于教学观察
- 最高频率:受组件传播延迟限制
- 占空比:建议50%,以获得最佳时序裕量
复位行为
- 异步复位:立即将状态设为FETCH
- 信号清除:所有控制信号复位到无效状态
- 停机恢复:需要复位才能恢复执行
性能
- 所有指令:4个时钟周期(取指-解码-执行-存储)
- 每秒指令数:时钟频率 ÷ 4
- 内存带宽:每个指令周期一次读或写