使用 Verilog 语言完成的一个支持13条 MIPS 指令的单周期处理器。
Abstract
仅支持13条 MIPS 指令的单周期处理器,不支持溢出。
Instruction Set
指令说明。
Total: 13
Status |
Ins Type |
op |
func |
ALUctr |
Branch |
Jump |
RegDst |
ALUSrc |
MemtoReg |
RegWr |
MemWr |
ExtOp |
supported |
addu |
000000 |
100001 |
0000 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
x |
supported |
add |
000000 |
100000 |
0001 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
x |
supported |
subu |
000000 |
100011 |
1000 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
x |
supported |
sub |
000000 |
100010 |
1001 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
x |
supported |
and |
000000 |
100100 |
0010 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
x |
supported |
or |
000000 |
100101 |
0011 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
x |
supported |
sltu |
000000 |
101011 |
1010 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
x |
supported |
slt |
000000 |
101010 |
1011 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
x |
supported |
beq |
000100 |
x |
1001 |
1 |
0 |
x |
0 |
x |
0 |
0 |
x |
supported |
jump |
000010 |
x |
x |
0 |
1 |
x |
x |
x |
0 |
0 |
x |
supported |
lw |
100011 |
x |
0001 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
1 |
supported |
sw |
101011 |
x |
0001 |
0 |
0 |
x |
1 |
x |
0 |
1 |
1 |
supported |
ori |
001101 |
x |
0011 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
Modules
整个 CPU 分为 Datapath(数据通路) 和 Control(控制单元) 两大模块,其下共有9个子组件。
Datapath
数据通路。
PC
Program Counter – 指令计数器
信号名 |
方向 |
描述 |
clk |
I |
时钟信号 |
rst |
I |
复位信号 |
niaddr |
I |
下一条指令的地址 |
iaddr |
O |
当前需要执行的指令地址 |
序号 |
功能名称 |
功能描述 |
1 |
复位 |
当复位信号有效时,PC被设置成 0x0000_3000 |
2 |
保存 NPC 并退出 |
在每个时钟上升沿保存 NPC,并将其输出 |
NPC
Next PC – 下指令部件
信号名 |
方向 |
描述 |
iaddr |
I |
当前需要执行的指令地址 |
branch |
I |
分支信号 |
jump |
I |
跳转信号 |
zero |
I |
判零标志 |
imm16 |
I |
I-指令的16位立即数 |
imm26 |
I |
J-指令的26位立即数 |
niaddr |
O |
下一条指令的地址 |
序号 |
功能名称 |
功能描述 |
1 |
下一指令地址 |
将指令地址移至下一条指令 |
2 |
分支地址跳转 |
当分支信号和判零标志有效时,使用I-指令中的16位立即数做逻辑扩展,使其扩展成30位,再将地址乘4,得到需要跳转的分支地址并将其输出 |
3 |
绝对地址跳转 |
当跳转信号有效时,使用J-指令中的26位立即数,与当前指令的高四位进行拼接,再将地址乘4,得到需要跳转的绝对地址并将其输出 |
DM
Data Memory – 数据内存
信号名 |
方向 |
描述 |
addr |
I |
读/写数据地址 |
din |
I |
内存写入总线 |
wEn |
I |
写使能信号 |
clk |
I |
时钟信号 |
dout |
O |
数据输出总线 |
序号 |
功能名称 |
功能描述 |
1 |
写入数据 |
当写使能信号有效时,在每个时钟上升沿将写入总线的数据写进相应内存地址中 |
2 |
读出数据 |
将指定地址的数据通过数据输出总线进行输出 |
IM
Instruction Memory – 指令内存
信号名 |
方向 |
描述 |
iaddr |
I |
当前需要执行的指令地址 |
ins |
O |
指令输出 |
序号 |
功能名称 |
功能描述 |
1 |
写入指令 |
使用 $readmemh 函数将 code.txt 中的指令写入指令内存中 |
2 |
读出指令 |
根据得到的指令地址从指令内存中读出相应的指令数据 |
MUX
Multiplexer – 选择器
信号名 |
方向 |
描述 |
a |
I |
缺省输入信号 |
b |
I |
选择输入信号 |
ctrl_s |
I |
选通控制信号 |
dout |
O |
选择器输出 |
序号 |
功能名称 |
功能描述 |
1 |
缺省输出 |
当选通控制信号无效时,选择器输出缺省输入信号 |
2 |
选择输出 |
当选通控制信号有效时,选择器输出选择输入信号 |
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
Arithmetic Logic Unit – 算术逻辑单元
信号名 |
方向 |
描述 |
ALUop |
I |
算术逻辑单元操作控制信号 |
a |
I |
输入总线A |
b |
I |
输入总线B |
result |
O |
输出总线 |
zero |
O |
判零标志 |
序号 |
功能名称 |
功能描述 |
1 |
做加法 |
根据操作控制信号,通过输出总线输出输入两数之和 |
2 |
做减法 |
根据操作控制信号,通过输出总线输出输入两数之差 |
1 |
按位与 |
根据操作控制信号,通过输出总线输出输入两数的按位与结果 |
2 |
按位或 |
根据操作控制信号,通过输出总线输出输入两数的按位或结果 |
1 |
做比较 |
根据操作控制信号,若输入总线A的数值小于总线B的数值,则为真,否则为假 |
EXT
Extender – 扩展器
信号名 |
方向 |
描述 |
imm16 |
I |
I-指令的16位立即数 |
extOp |
I |
扩展器控制信号 |
dout |
O |
扩展器输出总线 |
序号 |
功能名称 |
功能描述 |
1 |
逻辑扩展 |
当控制信号无效时,对输入的16位立即数逻辑扩展为32位 |
2 |
算术扩展 |
当控制信号有效时,对输入的16位立即数算术扩展为32位 |
Control
控制单元。
CTRL
Controller – 控制器
信号名 |
方向 |
描述 |
ins |
I |
当前需要执行的指令 |
branch |
O |
分支信号 |
jump |
O |
跳转信号 |
regDst |
O |
寄存器写入地址控制信号 |
aluSrc |
O |
算数逻辑单元输入控制信号 |
aluCtr |
O |
算术逻辑单元操作控制信号 |
regWr |
O |
寄存器写入使能信号 |
memWr |
O |
内存写入使能信号 |
extOp |
O |
扩展器控制信号 |
memtoReg |
O |
寄存器写入总线控制信号 |
序号 |
功能名称 |
功能描述 |
1 |
由指令产生控制信号 |
通过输入的指令分析出需要执行的操作,输出相应的控制信号 |
Code Repository
代码仓库。
GitHub: COExperiment_Repo