CO_P3
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 |
I类型指令
I类型指令 | Op(31~26) | Rs(25~21) | Rt(20~16) | immediate or address |
---|---|---|---|---|
Ori | 001101 | Rs | Rt | imm16 |
Lui | 001111 | 00000 | Rt | imm16 |
Lw | 100011 | Rs | Rt | imm16 |
Sw | 101011 | Rs | Rt | imm16 |
Beq | 000100 | Rs | Rt | imm16 |
J类型指令
J类型指令 | Op(31~26) | 26 address |
---|---|---|
j | 000010 | target |
二、主要模块
Conroller(控制器)
控制信号类型及含义
Branch
>
- Beq 1: 若Zero=1,PC输入选择加法器Nadd
- Other : 0,PC输入选择加法器Add输出(PC+4)
RegDst
>
- 0: 选择Rd
- 1: 选择Rt
RegWirte
>1: 表示寄存器堆可写入
MemtoReg
>
- R型指令 0: 选择 ALU 输出
- Lw 1: 选择数据存储器DM输出
MemtoReg_1
>
- 0 : MemtoReg
- Lui 1 : 选择shift输出
ALUSrc
>
- R型指令 0: 选择寄存器堆的 Read data2 输出
- Lw 1: 选择Signext的输出
- Sw 1: 选择Signext的输出
- Beq 0: 选择Read data2输出
ALUSrc_1
>
- 0 : ALUSrc
- Ori 1: 选择zero_ext 输出
ALUOp1 + ALUOp2
>
- 输入到ALU controller 控制单元
MemRead
>
- 0:表示DM不可写入
- 1:表示DM可写入
MemWrite
- 0:表示DM不可写入
- 1:表示DM可写入
shiftSrc
>
- 0: input(shift)选择Rdata2输出,shamt(shift)选择shamt输入
- 1:input(shift)选择imm16 输出,shamt(shift) 选择0x10输入
指令运算类型选择
指令 | Func字段 | ALUOp | ALU运算类型 | ALU Oper | ||
---|---|---|---|---|---|---|
Lw | XXXXXX | 00 | + | 000 | ||
Sw | XXXXXX | 00 | + | 000 | ||
Beq | XXXXXX | 01 | >/</= | 010 | ||
Ori | XXXXXX | 11 | \ | \ | 011 | |
Add | 100000 | 10 | + | 000 | ||
Sub | 100010 | 10 | - | 001 |
指令实现控制信号的转换
- x表示指令实现与该输入无关
指令 | Opcode | Branch | RegDst | RegWrite | MemtoReg | MemtoReg_1 | ALUSrc | ALUSrc_1 | ALUOp1 | ALUOp2 | MemRead | MemWrite | shiftSrc |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Add/Sub | 000000 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | x |
Lw | 100011 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | x |
Sw | 101011 | 0 | x | 0 | x | x | 1 | 0 | 0 | 0 | 0 | 1 | x |
Beq | 000100 | 1 | x | 0 | x | x | x | x | 0 | 1 | 0 | 0 | x |
Ori | 001101 | 0 | 1 | 1 | 0 | 0 | x | 1 | 1 | 1 | 0 | 0 | x |
Lui | 001111 | 0 | 1 | 1 | x | 1 | x | x | x | x | 0 | 0 | 1 |
Nop | 000000 | 0 | 0 | 1 | x | 1 | x | x | x | x | 0 | 0 | 0 |
GRF(寄存器堆)
端口 | 方向 | 描述 |
---|---|---|
Clk | I | 时钟信号 |
Reset | I | 复位信号,将寄存器的值全部清零 1: 复位 0:无效 |
WE | I | 写使能信号 1: 可写入数据 0: 不可写入数据 |
Read register1 | I | 读出地址输入(5位),读出到Read Data1 |
Read register2 | I | 读出地址输入(5位),读出到Read Data2 |
Write register | I | 写入地址输入(5位) |
Write data | I | 写入数据(32位) |
Read Data1 | O | Read register1地址对应寄存器的输出 |
Read Data2 | O | Read register2地址对应寄存器的输出 |
ALU(算数逻辑单位)
端口 | 方向 | 描述 |
---|---|---|
A | I | 操作数1(32位) |
B | I | 操作数2(32位) |
ALU Oper | I | ALU功能选择(3位) |
Zero | O | 判断操作数1与操作数2是否相等(1位) |
Result | O | 结果输出(32位) |
ALU control(ALU控制单元)
端口 | 方向 | 描述 |
---|---|---|
ALUOp | I | 指令类型区分(2位) |
Func | I | 指令[5:0]位 |
ALU Oper | O | ALU功能选择(3位) |
Add(加法器)
端口 | 方向 | 描述 |
---|---|---|
A | I | 操作数1(32位) |
B | I | 操作数2(32位) |
Result | O | A,B相加结果输出(32位) |
Shift left 2(左移两位)
端口 | 方向 | 描述 |
---|---|---|
in | I | 操作数1(32位) |
out | O | in左移两位输出(32位) |
IFU (取指令单元)
端口 | 方向 | 描述 |
---|---|---|
Clk | I | 时钟信号 |
Reset | I | 指令存储器(ROM)所有地址的存储值清零 1: 复位 0:无效 |
Branch | I | PC值分支跳转判断(1位) |
Zero | I | beq指令判断PC是否跳转条件(1位) |
immZeExt | I | 16位立即数无符号扩展输入(32位) |
pc | O | PC当前值(32位) |
instruction | O | PC地址对应IM(指令存储器)的指令输出(32位) |
DM(数据存储器)
端口 | 方向 | 描述 |
---|---|---|
Clk | I | 时钟信号 |
Reset | I | 数据存储器(RAM)所有地址的存储值清零 1: 复位 0:无效 |
MemWrite | I | 写使能信号, 1: 可写入数据 0: 不可写入数据 |
MemRead | I | 读使能信号, 1: 可读出数据 0: 不可读出数据 |
Address | I | 读写地址(12位) |
Writedata | I | 写入数据(32位) |
ReadData | O | Address地址对应数据储存器(RAM)的储存值输出 |
shift(移位器)
端口 | 方向 | 描述 |
---|---|---|
input | I | 操作数 |
shamt | I | 偏移量 |
output | I | 操作数移位后输出 |
三、数据通路
- 加粗表示该列存在分支
指令 | A | B | PC | IM Adr | Reg1 | Reg2 | Wreg | Wdata | A | B | DM Adr | DM Wdata | Sign-ext | A | B | shift | zero-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 | / |
四、测试
1 | ori $a1, $a0, 456 #$a0与立即数取或存入$a1 |
- Mars导出的机械码:
1 | v2.0 raw |
将上述机械码存入IM(指令储存器),控制时钟信号运行单周期CPU,将Logisim中DM中的内容和MARS中内存中的内容,GRF中的寄存器储存的值与MARS中寄存器储存的值以及Logism的PC值和MARS的PC值进行比对,以此来检测Logisim中的CPU是否运行正确。
五、思考题
Q1
- 状态存储:PC寄存器,GRF(通用寄存器组),数据存储器(DM),指令存储器(IM)
- 状态转移:ALU(算术逻辑运算单元),Adder(加法器),MUX(多路选择器),Signext(符号扩展器),shift left 2(左移两位)
Q2
- 合理。\
ROM可以完成指令的存入以及程序运行后指令的读出,RAM可以完成程序运行过程中的数据存入和读出。32个register组成一个寄存器堆,可以完成通用寄存器所需的数据临时存储以及读出。
- 改进意见
- ROM和RAM模块的地址访问宽度是24位,若CPU的地址访存范围是超过24位,若使用ROM和RAM,则地址访存空间受到限制。(可以对ROM和RAM进行扩展,扩大地址访存范围)
- 使用register作为GRF时,需要将32个寄存器进行合并,扩展成一个通用寄存器组
Q3
- 设计过Adder模块,ALU模块,GRF模块,EXT模块:
- Adder:使用Logisimn内置的Adder
- 内部设计:
首先,设计一位半加器(对两个1位二进制数进行相加求和,并向高位进位),再设计一位全加器(对两个1位二进制数进行相加并考虑低位来的进位、求得和并向高位进位),再使用32个1位全加器进行扩展,为降低线路的复杂度,使用组内并行,组间串行的方式32位加法器(8位并行加法器,对上述4个加法器进行串行扩展)
- shift(移位器):使用Logisimn内置的Shifter
- 设置input(输入)和shamt(偏移量)端口,按照shamt对输入进行移位操作,再通过端口output输出。
- 移2位:最低两位拼接2位“0”
Q4
- 因为nop(空操作指令)无需完成任何操作,只需进行PC值的转移(进入下一条指令),而这本身故无需控制信号的控制即可进行,故我们并不需要将nop加人控制信号真值表。
Q5
强度适中,但存在未考虑的情况。
寄存器
寄存器存入数据时,未考虑数据的边界情况,应分类为0及附近的数,32位数边界附近的数,32位数范围内的一些随机数\
对于无符号立即数,未考虑无符号立即数的边界情况,应分类为0及附近的数,16位数边界附近的数,16位数范围内的一些随机数\
未考虑存入寄存器是$0的情况存取指令
未考虑地址偏移offset是负数的情况\
未考虑$base存储值为负数的情况\
未考虑lw指令的目标寄存器为$0的情况
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ascendira!