Abstract
支持 45 条 MIPS 指令的单周期处理器,不支持溢出。
ADDU, SUBU, AND, OR, XOR, NOR, SLT, SLTU; ADDIU, SLTI, ALTIU, ANDI, ORI, XORI, LUI; SLL, SRL, SRA, SLLV, SRLV, SRAV; LW, SW, LB, LBU, SB; BEQ, BNE, BGEZ, BGTZ, BLEZ, BLTZ; J, JR, JALR, JAL; MULT; MFHI, MFLO, MTHI, MTLO; MFC0, MTC0; SYSCALL, ERET.
Instruction Set
Total: 36 + 9
Status |
Ins Type |
op |
func |
ALUctr |
Compare |
Jump |
RegDst |
ALUSrcB |
ALUSrcA |
MemtoReg |
RegWr |
MemWr |
ImmExt |
CopWr |
ByteExt |
iaddrtoNPC |
ManInput_raddr |
ManInput_shf |
supported |
addu |
000000 |
100001 |
0000 |
0 |
0 |
01 |
00 |
00 |
00 |
01 |
00 |
x |
00 |
x |
00 |
|
|
supported |
subu |
000000 |
100011 |
0001 |
0 |
0 |
01 |
00 |
00 |
00 |
01 |
00 |
x |
00 |
x |
00 |
|
|
supported |
and |
000000 |
100100 |
0010 |
0 |
0 |
01 |
00 |
00 |
00 |
01 |
00 |
x |
00 |
x |
00 |
|
|
supported |
or |
000000 |
100101 |
0011 |
0 |
0 |
01 |
00 |
00 |
00 |
01 |
00 |
x |
00 |
x |
00 |
|
|
supported |
xor |
000000 |
100110 |
0101 |
0 |
0 |
01 |
00 |
00 |
00 |
01 |
00 |
x |
00 |
x |
00 |
|
|
supported |
nor |
000000 |
100111 |
0100 |
0 |
0 |
01 |
00 |
00 |
00 |
01 |
00 |
x |
00 |
x |
00 |
|
|
supported |
slt |
000000 |
101010 |
1011 |
0 |
0 |
01 |
00 |
00 |
00 |
01 |
00 |
x |
00 |
x |
00 |
|
|
supported |
sltu |
000000 |
101011 |
1010 |
0 |
0 |
01 |
00 |
00 |
00 |
01 |
00 |
x |
00 |
x |
00 |
|
|
supported |
addiu |
001001 |
x |
0000 |
0 |
0 |
00 |
01 |
00 |
00 |
01 |
00 |
00 |
00 |
x |
00 |
|
|
supported |
slti |
001010 |
x |
1011 |
0 |
0 |
00 |
01 |
00 |
00 |
01 |
00 |
01 |
00 |
x |
00 |
|
|
supported |
sltiu |
001011 |
x |
1010 |
0 |
0 |
00 |
01 |
00 |
00 |
01 |
00 |
00 |
00 |
x |
00 |
|
|
supported |
andi |
001100 |
x |
0010 |
0 |
0 |
00 |
01 |
00 |
00 |
01 |
00 |
00 |
00 |
x |
00 |
|
|
supported |
ori |
001101 |
x |
0011 |
0 |
0 |
00 |
01 |
00 |
00 |
01 |
00 |
00 |
00 |
x |
00 |
|
|
supported |
xori |
001110 |
x |
0101 |
0 |
0 |
00 |
01 |
00 |
00 |
01 |
00 |
00 |
00 |
x |
00 |
|
|
supported |
lui |
001111 |
x |
0110 |
0 |
0 |
00 |
01 |
10 |
00 |
01 |
00 |
00 |
00 |
x |
00 |
x |
0x00000010 |
supported |
sll |
000000 |
000000 |
0110 |
0 |
0 |
01 |
00 |
01 |
00 |
01 |
00 |
x |
00 |
x |
00 |
|
|
supported |
srl |
000000 |
000010 |
0111 |
0 |
0 |
01 |
00 |
01 |
00 |
01 |
00 |
x |
00 |
x |
00 |
|
|
supported |
sra |
000000 |
000011 |
1000 |
0 |
0 |
01 |
00 |
01 |
00 |
01 |
00 |
x |
00 |
x |
00 |
|
|
supported |
sllv |
000000 |
000100 |
0110 |
0 |
0 |
01 |
00 |
00 |
00 |
01 |
00 |
x |
00 |
x |
00 |
|
|
supported |
srlv |
000000 |
000110 |
0111 |
0 |
0 |
01 |
00 |
00 |
00 |
01 |
00 |
x |
00 |
x |
00 |
|
|
supported |
srav |
000000 |
000111 |
1000 |
0 |
0 |
01 |
00 |
00 |
00 |
01 |
00 |
x |
00 |
x |
00 |
|
|
supported |
lw |
100011 |
x |
0000 |
0 |
0 |
00 |
01 |
00 |
01 |
01 |
00 |
01 |
00 |
11 |
00 |
|
|
supported |
sw |
101011 |
x |
0000 |
0 |
0 |
x |
01 |
00 |
x |
00 |
01 |
01 |
00 |
11 |
00 |
|
|
supported |
lb |
100000 |
x |
0000 |
0 |
0 |
00 |
01 |
00 |
01 |
01 |
00 |
01 |
00 |
01 |
00 |
|
|
supported |
lbu |
100100 |
x |
0000 |
0 |
0 |
00 |
01 |
00 |
01 |
01 |
00 |
01 |
00 |
00 |
00 |
|
|
supported |
sb |
101000 |
x |
0000 |
0 |
0 |
00 |
01 |
00 |
x |
00 |
01 |
01 |
00 |
10 |
00 |
|
|
supported |
beq |
000100 |
x |
x |
1 |
0 |
x |
00 |
00 |
x |
00 |
00 |
x |
00 |
x |
00 |
|
|
supported |
bne |
000101 |
x |
x |
1 |
0 |
x |
00 |
00 |
x |
00 |
00 |
x |
00 |
x |
00 |
|
|
supported |
bgez |
000001 |
x |
x |
1 |
0 |
x |
00 |
00 |
x |
00 |
00 |
x |
00 |
x |
00 |
|
|
supported |
bgtz |
000111 |
x |
x |
1 |
0 |
x |
00 |
00 |
x |
00 |
00 |
x |
00 |
x |
00 |
|
|
supported |
blez |
000110 |
x |
x |
1 |
0 |
x |
00 |
00 |
x |
00 |
00 |
x |
00 |
x |
00 |
|
|
supported |
bltz |
000001 |
x |
x |
1 |
0 |
x |
00 |
00 |
x |
00 |
00 |
x |
00 |
x |
00 |
|
|
supported |
j |
000010 |
x |
x |
0 |
1 |
x |
x |
x |
x |
00 |
00 |
x |
00 |
x |
00 |
|
|
supported |
jr |
000000 |
001000 |
x |
0 |
1 |
x |
x |
00 |
00 |
00 |
00 |
x |
00 |
x |
00 |
|
|
supported |
jalr |
000000 |
001001 |
x |
0 |
1 |
01 |
x |
00 |
11 |
01 |
00 |
x |
00 |
x |
00 |
|
|
supported |
jal |
000011 |
x |
x |
0 |
1 |
10 |
x |
x |
11 |
01 |
00 |
00 |
00 |
x |
00 |
11111 |
|
Status |
Ins Type |
op |
func |
ALUctr |
Compare |
Jump |
RegDst |
ALUSrcB |
ALUSrcA |
MemtoReg |
RegWr |
MemWr |
ImmExt |
CopWr |
ByteExt |
iaddrtoNPC |
supported |
mult |
000000 |
011000 |
1001 |
0 |
0 |
x |
00 |
00 |
x |
00 |
00 |
x |
00 |
x |
00 |
supported |
mfhi |
000000 |
010000 |
1101 |
0 |
0 |
01 |
00 |
00 |
00 |
01 |
00 |
x |
00 |
x |
00 |
supported |
mthi |
000000 |
010001 |
1110 |
0 |
0 |
x |
x |
00 |
x |
00 |
00 |
x |
00 |
x |
00 |
supported |
mflo |
000000 |
010010 |
1100 |
0 |
0 |
01 |
00 |
00 |
00 |
01 |
00 |
x |
00 |
x |
00 |
supported |
mtlo |
000000 |
010011 |
1111 |
0 |
0 |
x |
x |
00 |
x |
00 |
00 |
x |
00 |
x |
00 |
supported |
mfc0 |
010000 |
x |
x |
0 |
0 |
00 |
x |
x |
10 |
01 |
00 |
x |
00 |
x |
00 |
supported |
mtc0 |
010000 |
x |
x |
0 |
0 |
00 |
00 |
x |
00 |
00 |
00 |
x |
01 |
x |
00 |
supported |
syscall |
000000 |
001100 |
x |
0 |
1 |
x |
x |
x |
00 |
00 |
00 |
x |
01 |
x |
01 |
supported |
eret |
010000 |
011000 |
x |
0 |
1 |
x |
x |
x |
00 |
00 |
00 |
x |
01 |
x |
01 |
Modules
整个 CPU 分为 Datapath(数据通路) 和 Control(控制单元) 两大模块,其下共有 11 个子组件。
Datapath
PC
PC (Program Counter) – 指令计数器
PC 的主要功能是输出当前指令地址并保存下一条指令的地址,复位后,PC指向 0x0000_3000,这是第一条指令所在地址。
信号名 |
方向 |
描述 |
clk |
I |
时钟信号 |
rst |
I |
复位信号 |
niaddr |
I |
下一条指令的地址 |
iaddr |
O |
当前需要执行的指令地址 |
序号 |
功能名称 |
功能描述 |
1 |
复位 |
当复位信号有效时,PC被设置成0x0000_3000(ModelSim) / 0x0000_0000(On board) |
2 |
保存 NPC 并退出 |
在每个时钟上升沿保存 NPC,并将其输出 |
NPC
NPC (Next PC) – 下指令部件
根据当前指令地址以及判断信号来计算下一指令地址。
信号名 |
方向 |
描述 |
iaddr |
I |
当前需要执行的指令地址 |
branch |
I |
分支信号 |
jump |
I |
跳转信号 |
ins |
I |
指令信号 |
jiaddr |
I |
跳转地址 |
imm16 |
I |
I-指令的16位立即数 |
imm26 |
I |
J-指令的26位立即数 |
riaddr |
I |
返回的当前指令地址 |
niaddr |
O |
下一条指令的地址 |
序号 |
功能名称 |
功能描述 |
1 |
下一指令地址 |
将指令地址移至下一条指令 |
2 |
分支地址跳转 |
当分支信号和判零标志有效时,使用I-指令中的16位立即数做逻辑扩展,使其扩展成30位,再将地址乘4,得到需要跳转的分支地址并将其输出 |
3 |
绝对地址跳转 |
当跳转信号有效时,使用J-指令中的26位立即数,根据跳转指令类型将其进行不同种的拼接并将其输出 |
4 |
返回指令地址 |
将当前指令地址进行输出 |
DM
DM (Data Memeory)– 数据内存
数据内存,在程序运行中提供数据交换空间。
信号名 |
方向 |
描述 |
addr |
I |
读/写数据地址 |
din |
I |
内存写入总线 |
byteExt |
I |
字节控制信号 |
wEn |
I |
写使能信号 |
clk |
I |
时钟信号 |
dout |
O |
数据输出总线 |
序号 |
功能名称 |
功能描述 |
1 |
写入数据 |
当写使能信号有效时,在每个时钟上升沿将写入总线的数据写进相应内存地址中 |
2 |
读出数据 |
将指定地址的数据通过数据输出总线进行输出 |
3 |
读/写字节数据 |
当字节控制信号有效时,根据输入的数据地址来寻找相应的字节进行读/写操作 |
IM
IM (Instruction Memory) – 指令内存
指令内存,用于存储程序运行指令。
信号名 |
方向 |
描述 |
iaddr |
I |
当前需要执行的指令地址 |
ins |
O |
指令输出 |
序号 |
功能名称 |
功能描述 |
1 |
写入指令 |
使用 $readmemh 函数将 code.txt 中的指令写入指令内存中 |
2 |
读出指令 |
根据得到的指令地址从指令内存中读出相应的指令数据 |
MUX
MUX (Multiplexer) – 选择器
选择器,根据选通信号输出选定的输入值。
信号名 |
方向 |
描述 |
a |
I |
选择输入信号 A(00) |
b |
I |
选择输入信号 B(01) |
c |
I |
选择输入信号 C(10) |
d |
I |
选择输入信号 D(11) |
ctrl_s |
I |
选通控制信号 |
dout |
O |
选择器输出 |
序号 |
功能名称 |
功能描述 |
1 |
选择输出 A |
当选通控制信号为00时,选择器输出输入信号 A |
2 |
选择输出 B |
当选通控制信号为01时,选择器输出输入信号 B |
3 |
选择输出 C |
当选通控制信号为10时,选择器输出输入信号 C |
4 |
选择输出 D |
当选通控制信号为11时,选择器输出输入信号 D |
RF
RF (Register File) – 寄存器堆
寄存器单元,用于存储程序临时数据。
信号名 |
方向 |
描述 |
busW |
I |
寄存器写入总线 |
clk |
I |
时钟信号 |
wE |
I |
写使能信号 |
rW |
I |
寄存器写入地址 |
rA |
I |
输出总线A读出的数据地址 |
rB |
I |
输出总线B读出的数据地址 |
busA |
O |
寄存器输出总线A |
busB |
O |
寄存器输出总线B |
序号 |
功能名称 |
功能描述 |
1 |
写入数据 |
当写使能信号有效时,在每个时钟上升沿根据写入地址写入寄存器数据 |
2 |
读出数据 |
根据 A / B 数据地址读出相应的寄存器数据并通过输出总线 A / B 输出 |
ALU
ALU (Arithmetic Logic Unit) – 算术逻辑单元
算术逻辑单元,可完成加减与或比较等操作。
信号名 |
方向 |
描述 |
ALUop |
I |
算术逻辑单元操作控制信号 |
a |
I |
输入总线A |
b |
I |
输入总线B |
clk |
I |
时钟信号 |
result |
O |
输出总线 |
序号 |
功能名称 |
功能描述 |
1 |
做加法 |
根据操作控制信号,通过输出总线输出输入两数之和 |
2 |
做减法 |
根据操作控制信号,通过输出总线输出输入两数之差 |
3 |
按位与 |
根据操作控制信号,通过输出总线输出输入两数的按位与结果 |
4 |
按位或 |
根据操作控制信号,通过输出总线输出输入两数的按位或结果 |
5 |
按位或非 |
根据操作控制信号,通过输出总线输出输入两数的按位或非结果 |
6 |
按位异或 |
根据操作控制信号,通过输出总线输出输入两数的按位异或结果 |
7 |
逻辑左移 |
根据操作控制信号,通过输出总线输出输入 B 数逻辑左移 A 位的结果 |
8 |
逻辑右移 |
根据操作控制信号,通过输出总线输出输入 B 数逻辑右移 A 位的结果 |
9 |
算术右移 |
根据操作控制信号,通过输出总线输出输入 B 数算术右移 A 位的结果 |
10 |
做乘法 |
根据操作控制信号,将输入两数的相乘结果保存至 HI 和 LO 寄存器中 |
11 |
无符号比较 |
根据操作控制信号,若输入总线 A 的数值小于总线 B 的数值,则为真,否则为假 |
12 |
带符号比较 |
根据操作控制信号,若输入总线 A 的带符号数值小于总线 B 带符号的数值,则为真,否则为假 |
13 |
读取 LO 值 |
根据操作控制信号,通过输出总线输出 LO 寄存器的数值 |
14 |
读取 HI 值 |
根据操作控制信号,通过输出总线输出 HI 寄存器的数值 |
15 |
写入 HI 值 |
根据操作控制信号,在时钟上升沿来临时将输入总线 A 的数值 写入 HI 寄存器中 |
16 |
写入 LO 值 |
根据操作控制信号,在时钟上升沿来临时将输入总线 A 的数值 写入 LO 寄存器中 |
EXT
EXT (Extender) – 扩展器
扩展器,可将 X 位立即数扩展成为 32 位数。
信号名 |
方向 |
描述 |
din |
I |
X 位立即数 |
extOp |
I |
扩展器控制信号 |
dout |
O |
扩展器输出总线 |
序号 |
功能名称 |
功能描述 |
1 |
逻辑扩展 |
当控制信号无效时,对输入的立即数逻辑扩展为 32 位 |
2 |
算术扩展 |
当控制信号有效时,对输入的立即数算术扩展为 32 位 |
COMP
COMP (Compare) – 比较器
比较器,判断是否需要条件转移。
信号名 |
方向 |
描述 |
dinA |
I |
输入总线 A |
dinB |
I |
输入总线 B |
ins |
I |
指令信号 |
compare |
I |
比较信号 |
branch |
O |
分支信号 |
序号 |
功能名称 |
功能描述 |
1 |
条件跳转 |
根据当前指令信号,判断是否需要进行条件跳转,并通过分支信号输出 |
Coprocessor0RF
CoP0 (CoProcessor0) – 协处理器 0 寄存器堆
协处理器 0 寄存器堆, 用于存储 CPU 状态信息。
信号名 |
方向 |
描述 |
clk |
I |
时钟信号 |
din |
I |
输入总线 |
wEn |
I |
写使能信号 |
regNum |
I |
读写地址 |
sel |
I |
地址子号 |
npc_out |
I |
下地址指令地址输入总线 |
ins |
I |
指令信号 |
dout |
O |
输出总线 |
expiaddr |
O |
EPC输出总线 |
序号 |
功能名称 |
功能描述 |
1 |
写入数据 |
当写使能信号有效时,在每个时钟上升沿根据写入地址写入寄存器数据 |
2 |
读出数据 |
根据读数据地址读出相应的寄存器数据并通过输出总线输出 |
3 |
系统调用 |
将当前指令地址值写入EPC寄存器中,更改 Status 寄存器并使指令地址跳转到例外入口地址 |
4 |
异常返回 |
将EPC寄存器的数值输出至下地址逻辑,并更改Status寄存器 |
Control
CTRL
CTRL (Controller) – 控制单元
控制模块,通过解析指令信息来产生相应的控制信号执行指令。
信号名 |
方向 |
描述 |
ins |
I |
当前需要执行的指令 |
compare |
I |
比较信号 |
branch |
O |
分支信号 |
jump |
O |
跳转信号 |
regDst |
O |
寄存器写入地址控制信号 |
aluSrcA |
O |
算数逻辑单元输入控制信号 A |
aluSrcB |
O |
算数逻辑单元输入控制信号 B |
aluCtr |
O |
算术逻辑单元操作控制信号 |
regWr |
O |
寄存器写入使能信号 |
memWr |
O |
内存写入使能信号 |
immExt |
O |
扩展器控制信号 |
memtoReg |
O |
寄存器写入总线控制信号 |
copWr |
O |
协处理器 0 写入使能信号 |
byteExt |
O |
字节扩展信号 |
manInput_raddr |
O |
寄存器地址输入 |
manInput_shf |
O |
偏移量输入 |
iaddrtoNPC |
O |
指令地址选择信号 |
序号 |
功能名称 |
功能描述 |
1 |
由指令产生控制信号 |
通过输入的指令分析出需要执行的操作,输出相应的控制信号 |
Code Repository
代码仓库。
Github: COExperiment_Repo