CO_P7
CPU 设计文档
一、指令类型
- 解读:将指令按类型分类,并对指令按照功能划分
R类型指令
R类型指令 | Op(31~26) | Rs(25~21) | Rt(20~16) | Rd(15~11) | Shamt(10~6) | Func(5~0) |
---|---|---|---|---|---|---|
Add | 000000 | Rs | Rt | Rd | XXXXX | 100000 |
Sub | 000000 | Rs | Rt | Rd | XXXXX | 100010 |
And | 000000 | Rs | Rt | Rd | 00000 | 100100 |
Or | 000000 | Rs | Rt | Rd | 00000 | 100101 |
Mult | 000000 | Rs | Rt | 00000 | 00000 | 011000 |
Multu | 000000 | Rs | Rt | 00000 | 00000 | 011001 |
Div | 000000 | Rs | Rt | 00000 | 00000 | 011010 |
Divu | 000000 | Rs | Rt | 00000 | 00000 | 011011 |
Mfhi | 000000 | 00000 | 00000 | Rd | 00000 | 010000 |
Mflo | 000000 | 00000 | 00000 | Rd | 00000 | 010010 |
Mthi | 000000 | Rs | 00000 | 00000 | 00000 | 010001 |
Mtlo | 000000 | Rs | 00000 | 00000 | 00000 | 010011 |
Slt | 000000 | 00000 | Rt | Rd | 00000 | 101010 |
Sltu | 000000 | 00000 | Rt | Rd | 00000 | 101011 |
Jr | 000000 | Rs | 00000 | 00000 | 00000 | 001000 |
Syscall | 000000 | ///// | ///// | ///// | ///// | 001100 |
Eret | 010000 | 10000 | 00000 | 00000 | 00000 | 011000 |
Mfco | 010000 | 00000 | Rt | Rd | 00000000000 | |
Mtco | 010000 | 00100 | Rt | Rd | 00000000000 |
add:
sub:
and:
or:
mult:有符号数
multu:无符号数
div:
divu:
mfhi:
mflo:
mthi:
mtlo:
slt:
sltu:
jr:
syscall:
eret:
mfco:
mtco:
I类型指令
I类型指令 | Op(31~26) | Rs(25~21) | Rt(20~16) | immediate or address |
---|---|---|---|---|
Ori | 001101 | Rs | Rt | imm16 |
Lui | 001111 | 00000 | Rt | imm16 |
Addi | 001000 | Rs | Rt | imm16 |
Andi | 001100 | Rs | Rt | imm16 |
Lb | 100000 | Base | Rt | offset_16 |
Lh | 100001 | Base | Rt | offset_16 |
Lw | 100011 | Rs | Rt | imm16 |
Sb | 101000 | Base | Rt | offset_16 |
Sh | 101001 | Base | Rt | offset_16 |
Sw | 101011 | Rs | Rt | imm16 |
Beq | 000100 | Rs | Rt | imm16 |
Bne | 000101 | Rs | Rt | offset_16 |
ori:
lui:
addi:
andi:
lb:
lh:
lw:
sb:
sh:
sw:
beq:
bne:
J类型指令
J类型指令 | Op(31~26) | 26 address |
---|---|---|
j | 000010 | target |
jal | 000011 | target |
jal:
二、主要模块
1. mips(顶层模块)
端口 | 方向 | 描述 |
---|---|---|
clk | I | 时钟信号,控制所有需clk信号输入的模块 |
reset | I | 同步复位信号,控制所有需reset信号输入的模块 |
2. CPU(可视为单周期处理器)
3. CP0(异常与中断处理器)
4. TC(Time Counter —— 时钟中断)
5. Bridge(系统桥)
Conroller(控制器)
控制信号类型及含义
Branch
>
- `Branch_normal : 0,PC输入选择加法器Add输出(PC+4)
- `Branch_Beq 1: 若Zero=1,PC输入选择加法器Nadd
- `Branch_Jal 2: PC输入选择Jal_Adr
`Branch_Jr 3: PC输入选择Rdata1
RegDst`RegDst_Rd: 选择Rd
- `RegDst_Rt: 选择Rt
- `RegDst_31:选择31(jal指令)
RegWirte1: 表示寄存器堆可写入
MemtoReg
>
- `MemtoReg_ALU: 选择 ALU 输出
- `MemtoReg_shift: 选择shift输出
- `MemtoReg_DM: 选择数据存储器DM输出
- `MemtoReg_Adder:选择Adder(地址加法器)输出
ALUSrc
>
- `ALUSrc_ReadData2: 选择寄存器堆的 Read data2 输出
- `ALUSrc_SiExt: 选择Signext输入
- `ALUSrc_ZeExt:选择zero_ext输入
ALUOper
>
- `ALU_add: ALU运算类型 —— +
- `ALU_sub: ALU运算类型 —— -
- `ALU_or: ALU运算类型 —— |
MemRead
>
- 0:表示DM不可写入
- 1:表示DM可写入
MemWrite
>
- 0:表示DM不可写入
- 1:表示DM可写入
shiftSrc
>
- `shiftSrc_shamt: shamt(shift)选择shamt输入
- `shiftSrc_0x10:shamt(shift) 选择0x10输入
- `shiftSrc_0:shamt(shift) 选择0输入
(in.shift根据ALUSrc决定)
Tnew,rs_Tuse,rt_Tuse:根据指令输出
>
- Tnew: 表示位于E级寄存器的指令经过Tnew个时钟周期可以算出结果并且存储到下一级流水级寄存器中。
- rs_Tuse,rt_Tuse:表示该指令位于 D 级的时候,再经过多少个时钟周期就必须要使用Rs,Rt地址对应的数据。
Controller (指令实现控制信号的转换)
- x表示指令实现与该输入无关
指令 | Opcode | Branch | RegDst | RegWrite | MemtoReg | ALUSrc | ALUOp | MemWrite | MemCate | shiftSrc | Tnew | rs_Tuse | rt_Tuse |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Add/Sub | 000000 | 0 | 0 | 1 | 0 | 0 | 2 | 0 | x | x | 1 | 1 | 1 |
Lw | 100011 | 0 | 1 | 1 | 2 | 2 | 0 | 0 | x | x | 2 | 1 | 5 |
Sw | 101011 | 0 | x | 0 | x | 2 | 0 | 1 | 0 | x | 0 | 1 | 2 |
Beq | 000100 | 1 | x | 0 | x | 0 | 1 | 0 | x | x | 0 | 0 | 0 |
Ori | 001101 | 0 | 1 | 1 | 0 | 1 | 3 | 0 | x | x | 1 | 1 | 5 |
Lui | 001111 | 0 | 1 | 1 | 1 | x | x | 0 | x | 1 | 0 | 5 | 5 |
Nop | 000000 | 0 | x | 0 | x | x | x | 0 | x | 0 | 0 | 5 | 5 |
Jal | 000011 | 2 | 2 | 1 | 3 | x | x | 0 | x | x | 0 | 5 | 5 |
Jr | 000000 | 3 | x | 0 | x | x | x | 0 | x | x | 0 | 0 | 5 |
IFU (取指令单元)
端口 | 方向 | 描述 |
---|---|---|
Clk | I | 时钟信号 |
Reset | I | 指令存储器(im_reg)所有地址的存储值清零 1: 复位 0:无效 |
enable_PC | I | 写使能信号, 1: 可写入数据 0: 不可写入数据(不可更改) |
Branch | I | PC值分支跳转指令判断(4位) |
Zero | I | beq指令判断PC是否跳转条件(1位) |
index | I | 跳转指令的target中间值(26位) |
immSiExt | I | 16位立即数有符号扩展输入(32位) |
D_pc | I | D级指令所对应的PC地址(32位) |
ReadData1 | O | GRF(寄存器堆)中Read register1地址对应寄存器的输出 |
pc | O | PC当前值(32位) |
instr | O | PC地址对应IM(指令存储器)的指令输出(32位) |
IF_ID(D级寄存器)
端口 | 方向 | 描述 |
---|---|---|
clk | I | 时钟信号 |
reset | I | 寄存器存储值清零 1: 复位 0:无效 |
enable_D | I | 写使能信号, 1: 可写入数据 0: 不可写入数据(不可更改) |
F_pc | I | F级指令对应的PC地址(32位) |
F_instr | I | F级指令PC地址对应的指令(32位) |
D_pc | O | D级指令对应的PC地址(32位) |
D_instr | O | D级指令PC地址对应的指令(32位) |
Stall (暂停信号控制器)
端口 | 方向 | 描述 |
---|---|---|
rs_Tuse | I | D级指令对应的rs_Tuse(4位) |
rt_Tuse | I | D级指令对应的rt_Tuse(4位) |
E_Tnew | I | E级指令对应的Tnew(4位) |
M_Tnew | I | M级指令对应的Tnew(4位) |
W_Tnew | I | W级指令对应的Tnew(4位) |
Rs | I | D级指令对应的Rs(5位) |
Rt | I | D级指令对应的Rt(5位) |
E_WriteRes | I | E级指令执行写入GRF操作时的地址(5位) |
M_WriteRes | I | M级指令执行写入GRF操作时的地址(5位) |
W_WriteRes | I | W级指令执行写入GRF操作时的地址(5位) |
E_RegWrite | I | E级指令是否执行写入GRF操作, 1: 写入 0: 不写入 |
M_RegWrite | I | M级指令是否执行写入GRF操作, 1: 写入 0: 不写入 |
W_RegWrite | I | W级指令是否执行写入GRF操作, 1: 写入 0: 不写入 |
enable_PC | O | IFU模块中的PC寄存器写使能信号, 1: 可写入数据 0: 不可写入数据(不可更改) |
enable_D | O | D级寄存器写使能信号, 1: 可写入数据 0: 不可写入数据(不可更改) |
enable_PC | O | IFU模块中的PC寄存器写使能信号, 1: 可写入数据 0: 不可写入数据(不可更改) |
reset_E | O | E级寄存器存储值清零 1: 复位 0:无效 |
shift(移位器)
端口 | 方向 | 描述 |
---|---|---|
input | I | 操作数 |
shamt | I | 偏移量(5位) |
output | I | 操作数移位后输出 |
CMP(比较器)
端口 | 方向 | 描述 |
---|---|---|
ReadData1 | I | 操作数1 |
ReadData2 | I | 操作数2 |
Zero | O | 比较ReadData1和ReadData2, 1: 相等 0: 不相等 |
GRF(寄存器堆)
端口 | 方向 | 描述 |
---|---|---|
Clk | I | 时钟信号 |
Reset | I | 复位信号,将寄存器的值全部清零 1: 复位 0:无效 |
WE | I | 写使能信号 1: 可写入数据 0: 不可写入数据 |
ReadRes1 | I | 读出地址输入(5位),读出到Read Data1 |
ReadRes2 | I | 读出地址输入(5位),读出到Read Data2 |
WriteRes | I | 写入地址输入(5位) |
WriteData | I | 写入数据(32位) |
WPC | I | 输入当前pc地址 |
ReadData1 | O | Read register1地址对应寄存器的输出 |
ReadData2 | O | Read register2地址对应寄存器的输出 |
ID_EX (E级寄存器)
端口 | 方向 | 描述 |
---|---|---|
clk | I | 时钟信号 |
reset | I | 复位信号,将寄存器的值全部清零 1: 复位 0:无效 |
D_pc | I | D级指令对应的pc地址 |
reset_E | I | E级寄存器的复位信号,将寄存器的值全部清零 1: 复位 0:无效 |
D_ReadRes1 | I | D级指令对应的Rs,GRF读出地址(5位) |
D_ReadRes2 | I | D级指令对应的Rt,GRF读出地址(5位) |
D_ReadData1 | I | D级指令D_ReadRes1地址对应寄存器的输出(32位) |
D_ReadData2 | I | D级指令D_ReadRes2地址对应寄存器的输出(32位) |
D_WriteRes | I | D级指令写入GRF的地址(5位) |
D_WriteData | I | D级指令写入GRF的数据(32位) |
D_ExtShift | I | D级指令的extend和shift模块输出(32位) |
D_MemtoReg | I | D级指令存入GRF的数据类型(4位) |
D_MemWrite | I | D级指令是否写入DM 1: 可写入 0:不可写入 |
D_MemCate | I | D级指令写入DM的指令类型(4位) |
D_ALUOper | I | D级指令运算类型(4位) |
D_RegWrite | I | D级指令是否可写入GRF 1: 可写入 0:不可写入 |
D_ALUSrc | I | D级指令ALU模块的B端口输入数据类型(4位) |
D_Tnew | I | D级指令对应的Tnew(4位) |
E_pc | I | E级指令对应的pc地址 |
E_ReadRes1 | I | E级指令对应的Rs,GRF读出地址(5位) |
E_ReadRes2 | I | E级指令对应的Rt,GRF读出地址(5位) |
E_ReadData1 | I | E级指令D_ReadRes1地址对应寄存器的输出(32位) |
E_ReadData2 | I | E级指令D_ReadRes2地址对应寄存器的输出(32位) |
E_WriteRes | IE级指令写入GRF的地址(5位) | |
E_WriteData | I | E级指令写入GRF的数据(32位) |
E_ExtShift | I | E级指令的extend和shift模块输出(32位) |
E_MemtoReg | I | E级指令存入GRF的数据类型(4位) |
E_MemWrite | I | E级指令是否写入DM 1: 可写入 0:不可写入 |
E_MemCate | I | E级指令写入DM的指令类型(4位) |
E_ALUOper | I | E级指令运算类型(4位) |
E_RegWrite | I | E级指令是否可写入GRF 1: 可写入 0:不可写入 |
E_ALUSrc | I | E级指令ALU模块的B端口输入数据类型(4位) |
E_Tnew | I | E级指令对应的Tnew(4位) |
ALU(算数逻辑单位)
端口 | 方向 | 描述 |
---|---|---|
A | I | 操作数1(32位) |
B | I | 操作数2(32位) |
ALUOper | I | ALU功能选择(4位) |
Result | O | 结果输出(32位) |
EX_MEM(M级寄存器)
端口 | 方向 | 描述 |
---|---|---|
clk | I | 时钟信号 |
reset | I | 复位信号,将寄存器的值全部清零 1: 复位 0:无效 |
ALU_out | I | D级指令ALU的输出结果(32位) |
E_pc | I | E级指令对应的pc地址 |
E_ReadRes1 | I | E级指令对应的Rs,GRF读出地址(5位) |
E_ReadRes2 | I | E级指令对应的Rt,GRF读出地址(5位) |
E_ReadData2 | I | E级指令D_ReadRes2地址对应寄存器的输出,需转发(32位) |
E_WriteRes | I | E级指令写入GRF的地址(5位) |
E_WriteData | I | E级指令写入GRF的数据(32位) |
E_MemtoReg | I | E级指令存入GRF的数据类型(4位) |
E_MemWrite | I | E级指令是否写入DM 1: 可写入 0:不可写入 |
E_MemAddress | I | E级指令写入DM的地址(32位) |
E_MemCate | I | E级指令写入DM的指令类型(4位) |
E_RegWrite | I | E级指令是否可写入GRF 1: 可写入 0:不可写入 |
E_Tnew | I | E级指令对应的Tnew(4位) |
M_pc | O | M级指令对应的pc地址 |
M_ReadRes1 | O | M级指令对应的Rs,GRF读出地址(5位) |
M_ReadRes2 | O | M级指令对应的Rt,GRF读出地址(5位) |
M_ReadData2 | O | M级指令D_ReadRes2地址对应寄存器的输出(32位) |
M_WriteRes | O | M级指令写入GRF的地址(5位) |
M_WriteData | O | M级指令写入GRF的数据(32位) |
M_MemtoReg | O | M级指令存入GRF的数据类型(4位) |
M_MemWrite | O | M级指令是否写入DM 1: 可写入 0:不可写入 |
M_MemAddress | O | M级指令写入DM的地址(32位) |
M_MemCate | O | M级指令写入DM的指令类型(4位) |
M_RegWrite | O | M级指令是否可写入GRF 1: 可写入 0:不可写入 |
M_Tnew | O | M级指令对应的Tnew(4位) |
DM(数据存储器)
端口 | 方向 | 描述 |
---|---|---|
Clk | I | 时钟信号 |
pc | O | M级指令的PC当前值(32位) |
Reset | I | 数据存储器(RAM)所有地址的存储值清零 1: 复位 0:无效 |
MemWrite | I | 写使能信号, 1: 可写入数据 0: 不可写入数据 |
MemCate | I | 判断向数据储存器写入数据的操作指令类型(4位) |
Address | I | 读写地址(12位) |
WriteData | I | 写入数据(32位) |
ReadData_DM | O | Address地址对应数据储存器(RAM)的储存值输出 |
MEM_WB
端口 | 方向 | 描述 |
---|---|---|
clk | I | 时钟信号 |
reset | I | 复位信号,将寄存器的值全部清零 1: 复位 0:无效 |
M_pc | I | M级指令对应的pc地址 |
M_WriteRes | I | M级指令写入GRF的地址(5位) |
M_WriteData | I | M级指令写入GRF的数据(32位) |
M_MemtoReg | I | M级指令存入GRF的数据类型(4位) |
M_MemWrite | I | M级指令是否写入DM 1: 可写入 0:不可写入 |
M_RegWrite | I | M级指令是否可写入GRF 1: 可写入 0:不可写入 |
M_Tnew | I | M级指令对应的Tnew(4位) |
ReadData_DM | I | M级指令Address地址对应数据储存器(RAM)的储存值输出 |
W_pc | O | W级指令对应的pc地址 |
W_WriteRes | O | W级指令写入GRF的地址(5位) |
W_WriteData | O | W级指令写入GRF的数据(32位) |
W_MemtoReg | O | W级指令存入GRF的数据类型(4位) |
W_MemWrite | O | W级指令是否写入DM 1: 可写入 0:不可写入 |
W_RegWrite | O | W级指令是否可写入GRF 1: 可写入 0:不可写入 |
W_Tnew | O | W级指令对应的Tnew(4位) |
三、数据通路
指令 | A | B | PC | IM Adr | Reg1 | Reg2 | Wreg | Wdata | A | B | DM Adr | DM Wdata | Sign-ext | A | B | shift | ext | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Adder: | ALU: | Nadder: | / | |||||||||||||||
R型指令与访存 | PC | 4 | Adder | PC | Rs | Rt | Rd | ALU | Rdata1 | Rdata2 | / | / | / | / | / | /! | / | |
Lw | PC | 4 | Adder | PC | Rs | / | Rt | DM | Rdata1 | Sign_ext | ALU | / | imm16 | / | / | / | / | |
Sw | PC | 4 | Adder | PC | Rs | Rt | / | / | Rdata1 | Sign_ext | ALU | Rdata2 | imm16 | / | / | / | / | |
Beq | PC | 4 | Adder/Nadder | PC | Rs | Rt | / | / | Rdata1 | Rdata2 | / | / | imm16 | Adder | Sign-imm16(左移2) | / | / | |
Ori | PC | 4 | Adder | PC | Rs | / | Rt | ALU | Rdata1 | zero_ext | / | / | / | / | / | / | imm16 | |
Lui | PC | 4 | Adder | PC | / | / | Rt | shift | / | / | / | / | / | / | / | imm16 | / | / |
Nop | PC | 4 | Adder | PC | / | Rt | Rd | shift | / | / | / | / | / | / | / | Rdata2 | / | |
jal | PC | 4 | Jal_Adr | PC | / | / | 31 | Adder | / | / | / | / | / | / | / | / | / | |
jr | / | / | Rdata1 | PC | Rs | / | / | / | / | / | / | / | / | / | / | / | / |
四、测试
1 | .text |
- Mars导出的机械码(储存在code.txt中的文件):
1 | 34081001 |
利用$readmemh指令读取code.txt中的机械码指令并储存在IFU_mips模块的指令存储器im_reg(4096个32位寄存器)当中,运行mips顶层模块,通过$display指令检测存入寄存器堆(GRF)和数据存储器(DM)时的pc地址,相应数据以及存入的寄存器或数据存储器地址,将结果与Mars对拍运行时的数据做比对,以此检测Verilog代码编写的单周期CPU是否正确。
五、思考题
Q1
键盘和鼠标将用户的操作转化为电信号,电信号通过计算机的接口电路进入计算机中.
由于键盘和鼠标是串行慢速输入设备,需要用南桥芯片作为与CPU和内存的连接桥梁,当上述输入设备产生输入信号,中断控制器产生中断信号,每一个IO口会代表不同的功能,由CPU去识别,并当CPU能处理时再进行处理中断。
Q2
因为中断处理程序是操作系统内核的一部分,它们需要以一定的方式被加载到内存中,以便CPU在发生中断时能够找到并执行它们。如果允许用户自定义入口地址,那么操作系统将无法保证通过中断类型直接找到其对应的地址,或者用户自定义地址的有效性,可能会导致程序崩溃或数据损坏。
因为针对不同的指令集,其对指令异常和中断的要求是不同的,并且在对应中断和异常的方法并不相同。对于固定的CPU,其适合使用其指令集对应的异常处理程序,即CPU处理中断异常跳转到已经指定好的地址。
一定条件上处理中断异常的程序由用户提供能提供我们所希望的功能。前提条件是用户能对其使用的CPU处理中断和异常有深入的了解,能选择满足功能要求的异常中断程序,否则不能提供我们所希望的功能
安全性问题
:导致安全漏洞。
例如,恶意用户可能会提供一段恶意代码作为中断处理程序,从而执行未经授权的操作。
稳定性问题
:
中断处理程序需要快速响应并处理中断,如果用户提供的中断处理程序存在错误或不稳定,可能会导致系统崩溃或数据损坏。
兼容性问题
:
不同的操作系统和硬件平台可能有不同的中断处理机制和规范,如果用户提供的中断处理程序与操作系统或硬件平台不兼容,可能会导致系统行为异常。
Q3
CPU不能为每个设备都提供一套地址/数据的,否则会导致CPU设计变得复杂。
故为设置输入端口,连接每个设备的输入信号,选择满足地址条件的读出信号端口输出
设置写入数据和写入使能,根据地址判断写入的外设
Q4
异(中断产生逻辑):
模式0
通常用于产生定时中断,模式0
下的中断信号将持续有效,直至控制寄存器中的中断屏蔽位被设置为;模式1
通常用于产生周期性脉冲。不同于模式0
,模式1
下计数器每次计数循环中只产生一周期的中断信号.
实现方式:
当模式0
的计数器倒计数为0后,计数器停止计数,此时控制寄存器中的使能 Enable自动变为 0。当使能 Enable 被设置为 1 后,初值寄存器值再次被加载至计数器,计数器重新启动倒计数。当模式1
的计数器倒计数为 0 后,初值寄存器值被自动加载至计数器,计数器继续倒计数。同(内部基本结构):由相同的控制寄存器、初值寄存器、32 位计数器构成,模块的功能与接口相同。
Q5
会导致在跳转进入中断信号时,无法返回宏观PC(PC为空)或者返回错误的宏观PC(BD为空)
保存信息:插入空泡一级的上一级的PC和BD(Branch Delay 是否是延迟槽指令)值
Q6
这样的指令是无效的,若将
$31
中的值赋值给PC
,再将PC+4
赋值给$31
,则会导致丢失返回地址,导致无法正确返回到调用者。因为
$31
寄存器用于存储函数的返回地址,在执行jalr $31 $31
指令时,$31
的值被更改,导致函数将无法正确返回应该使用一个不同的寄存器来存储这个地址(PC + 4)