4.6 CPU使用指南
前言
这个CPU大体上和理论课讲过的单周期CPU差不多,就多一些细节,相信大家看一眼就知道怎么用,多看几眼就看明白结构了。
注意使用本次实验提供的2.16版logisim来打开,据测试jdk8也是能跑的,助教本地的jdk15也可以,要是jdk17、18就更没问题了。用logisim2.7可能CPU不能正常运行。
CPU支持的指令与指导书同步,因此不要测试超出的指令,可能会导致CPU无法识别而出现问题。
对于syscall系统调用,CPU仅支持用其停止程序,不支持任何输入输出,因此为了在CPU里调试,需要对MIPS代码进行一些修改:
- 对于简单的数字输入,可以直接使用
li指令写入寄存器; - 对于数字输出,可以将其存储到RAM的某一地址,在CPU停机后进行观察。 如下所示:
.data
.text
main:
li $a0, 100200
li $a1, -209
jal add
sw $v0, 0($zero)
li $v0, 10
syscall
add:
add $v0, $a0, $a1
jr $ra
如果你的汇编链接器实现正确,那么导入机器码并运行CPU停机后,会在内存地址第0行看到0x00018697。
如何使用
使用CPU的操作可以概括为:
- 编写汇编程序,用MARS或者自己的汇编链接器生成机器码;
- 向CPU中的指令rom加载机器码;
- 用
ctrl+k连续运行,或者用ctrl+t单步运行; - 停机后,查看内存中的运行结果。
导入机器码
用MARS导出机器码
在MARS编写好代码并汇编完成之后,选择上方工具栏Dump功能,如下所示:

之后在Dump Format里选择Hexadecimal Text并导出,就可以得到与我们的汇编链接器输出的同样格式的十六进制机器码了。
将机器码导入ROM
为了使用CPU处理器,我们需要将机器码导入ROM,也就是指令存储器。
首先,在我们自己的汇编链接器生成的机器码文件或者MARS导出的机器码文件的开头,加上一行v2.0 raw,如下所示:
v2.0 raw
3c010000
34230000
2411000a
24120014
acff0000
acf1fffc
acf2fff8
0007e821
0c000c0d
8fbf0000
00024021
11000001
08000c0d
8fb5fffc
8fb6fff8
02b64021
00081021
03e00008
然后找到ROM,右键点击并选择’加载数据镜像’,最后选择刚刚的机器码文件即可。

停机
目前CPU可能由于4种原因停机,分别为:
- 正常停机:调用
syscall指令,不管$v0是多少; - 指令无法解析:可能你用了指导书之外的mips指令,或者汇编链接过程出了问题;
- ÷0:除法指令中除数为0;
- 步数超出限制:运行步数限制在4096步,你在本地可以解除这个限制。
主要部件
小标题与部件颜色一致。
控制器
负责解析指令,生成控制信号。
32位指令先被分析出指令类型,然后转化成alu选择信号、各存储元件的读写信号等。
寄存器堆
内部有32个寄存器,每周期可读2个值、写1个值。
配套部件为寄存器地址生成器。
ALU
大部分数值计算都在此进行。
内存
存数据的,地址位宽为10bit,数据位宽为32bit。
由于内存和指令存储器的存在,这已经是一台完整的计算机了,不过我们习惯上还是叫它CPU。
配套部件:
- store处理:处理
sb的1字节写入。 - load处理:处理
lb和lbu的1字节加载。
指令存储器
简言之,保存指令。
上方的是极其方便的mips反汇编探针,由华中科技大学的谭志虎老师开发,这里对他进行特别感谢~
注意,反汇编探针能解析的指令,控制器未必能解析。
简化区
为了同学们容易上手,在CPU主体的下方画了一个显示少量主要数据的框框。等你比较熟悉CPU结构之后,直接在上方的电路图加探针来调试会更方便。
调试技巧
- 这次我们用新版logisim进行实验,支持鼠标中键拖动、滚轮缩放;
- 界面中需要渲染的可变部分越少,则CPU模拟运行速度越快,程序步数很多的话建议缩放到画面中只包含四盏灯;
- 需要解析CPU结构的话,善用中键点击导线功能;
- 需要查看CPU运行到特定情况下各部件的内部情况时,右键此部件,然后
查看<部件名>。
最后
此CPU的搭建及该使用指南的初步完成由李宇衡助教于2022年完成。