这是一个基于Java的TD-4 CPU行为级仿真器。该项目旨在通过软件模拟由74系列数字逻辑芯片构成的4位CPU,其设计灵感来源于日本工程师渡波郁(Iku Watanami)的著作《用10个IC轻松介绍CPU设计》以及eraser2333/td4cpu仓库中的复刻版本。
本仿真器完整实现了CPU的核心组件、指令集和交互式运行环境,是学习计算机体系结构和数字逻辑设计的绝佳工具。
- 组件级仿真: 对构成CPU的所有核心74系列芯片(如
SN74HC161,SN74HC283,SN74HC154等)进行了行为级模拟。 - 完整的指令集: 实现了TD4 CPU的全部12条指令,包括算术、数据转移和跳转指令。
- 可编程ROM: 模拟了一个16x8位的只读存储器(ROM),支持从不同格式加载程序。
- 汇编器支持: 内置一个简单的程序加载器 (
ProgramLoader),能够解析从简单汇编.asm文件编写的程序。 - 交互式运行环境: 提供一个基于命令行的主程序 (
Main.java),允许用户:- 单步执行程序。
- 在手动和自动时钟模式之间切换。
- 在运行时设置4位输入端口的值。
- 复位CPU到初始状态。
- 实时查看所有寄存器(PC, A, B, OUT)、进位标志和时钟的状态。
- 单元测试: 为每个芯片模拟器提供了独立的JUnit 4测试,以确保其逻辑的正确性。
项目代码遵循清晰的包结构,将不同功能的模块分离:
td4cpu_simulator/
└── src/
└── com/example/td4/
├── chip/ // 74xx系列IC的行为级实现
├── cpu/ // CPU核心组件 (CPU, ALU, Register, ControlUnit, Clock)
├── rom/ // ROM及程序加载器 (ROM, ProgramLoader)
├── utils/ // 辅助工具类 (BitUtils)
└── Main.java // 仿真器主程序入口和用户交互界面
- Java 开发工具包 (JDK) 8 或更高版本。
- JUnit 4 (用于运行测试)。
在项目的根目录下,使用 javac 命令编译所有源文件。请确保将类文件输出到正确的目录结构中。
# 在 src 目录的上一级运行
javac -d out src/com/example/td4/chip/*.java src/com/example/td4/cpu/*.java src/com/example/td4/rom/*.java src/com/example/td4/utils/*.java src/com/example/td4/*.java使用 java 命令运行主程序。
# 在 src 目录的上一级运行
java -cp out com.example.td4.Main程序启动后,将加载一个示例程序并显示CPU的初始状态。您可以输入以下命令与仿真器交互:
s: 步进 (Step)。在手动模式下,执行一个完整的时钟脉冲(上升沿+下降沿);在自动模式下,推进一次内部振荡器。r: 复位 (Reset)。将CPU和所有组件恢复到初始状态。i <value>: 输入 (Input)。设置4位输入端口的值,<value>是一个0-15之间的数字。例如:i 5。m: 模式 (Mode)。在手动和自动时钟模式之间切换。a <N>: 自动 (Auto)。在自动模式下,连续执行 N 步。f <T>: 频率 (Frequency)。设置自动时钟的速度。<T>表示自动时钟振荡器每翻转一次需要advanceAutoClockTick被调用的次数(数字越大,时钟越慢)。q: 退出 (Quit)。结束仿真。
您可以通过创建一个简单的 .asm 文件来为TD4 CPU编写程序。
- 每行一条指令,格式为
MNEMONIC或MNEMONIC OPERAND。 - 注释以
;,#, 或//开头。 - 操作数可以是十进制 (
5)、十六进制 (0xA) 或二进制 (0b1010)。 - 助记符不区分大小写。
- 当前版本不支持标签,跳转地址必须是数字。
示例 program.asm 文件:
; 一个简单的计数和输出程序
MOV A, 0 ; A = 0
LOOP: ; 标签在当前版本中仅作为注释
OUT A ; 输出 A 的当前值
ADD A, 1 ; A = A + 1
JMP 1 ; 跳转回地址 1 (模拟LOOP)加载并运行:
- 将上述代码保存为
program.asm文件。 - 修改
Main.java以加载此文件:ProgramLoader.loadFromAsmFile("program.asm"); - 重新编译并运行仿真器。
TD4是一个4位CPU,每条指令由4位操作码(Opcode)和4位操作数(Operand)组成,共8位。
| 助记符 | 指令 | 解释 |
|---|---|---|
MOV A,B |
0001 0000 |
将 B 寄存器传送到寄存器A。不受C标志影响,执行后C标志置0。 |
MOV B,A |
0100 0000 |
将 A 寄存器转移到寄存器B。不受C标志影响,执行后C标志置0。 |
MOV A,Im |
0011 XXXX |
将立即数XXXX传送到寄存器A。不受C标志影响,执行后C标志置0。 |
MOV B,Im |
0111 XXXX |
将立即数XXXX传送到寄存器B。不受C标志影响,执行后C标志置0。 |
ADD A,Im |
0000 XXXX |
将立即数XXXX累加到寄存器A。不受C标志影响,执行后发生进位C标志置1。 |
ADD B,Im |
0101 XXXX |
将立即数XXXX累加到寄存器B。不受C标志影响,执行后发生进位C标志置1。 |
IN A |
0010 0000 |
将输入端口数据传输到寄存器A。不受C标志影响,执行后C标志置0。 |
IN B |
0110 0000 |
将输入端口数据传输到寄存器B。不受C标志影响,执行后C标志置0。 |
OUT Im |
1011 XXXX |
将立即数XXXX传输到输出端口。不受C标志影响,执行后C标志置0。 |
OUT B |
1001 0000 |
将寄存器B传输到输出端口。不受C标志影响,执行后C标志置0。 |
JMP Im |
1111 XXXX |
程序跳转到立即数指示的地址XXXX。不受C标志影响,执行后C标志置0。 |
JNC Im |
1110 XXXX |
当C标志为0时,程序跳转到立即数所指示的地址。反之什么都不做。执行后C标志置0。 |
本仿真器实现了以下构成TD4 CPU的74系列芯片:
SN74HC10(三路3输入与非门)SN74HC14(六路施密特反相器)SN74HC32(四路2输入或门)SN74HC74(双D触发器)SN74HC153(2路4选1多路选择器)SN74HC154(4-16线译码器)SN74HC161(4位同步二进制计数器)SN74HC283(4位二进制全加器)SN74HC540(八路反相缓冲器)