P3
P3_Study
1 单周期CPU设计方案
1.1 设计概述
本文所呈现的是利用logisim实现的MIPS架构CPU,可以支持8条指令,含有IFU、GRF、ALU、DM、Controller、BranchControl、EXT、NPC模块。整体设计实现采用自下而上的设计思路,先逐一设计搭建每个子模块,再将所有子模块整合连接,从而实现完整的数据通路。
CPU顶层模块如下:
1.2 实现指令说明
1.2.1 R型指令
算术指令:add(暂视为不做溢出检查),sub(暂视为不做溢出检查)
若要扩展支持其他R型指令,主要改变Controller模块与ALU模块
1.2.2 I型指令
B类指令:beq
算术指令:lui,ori
访存指令:lw,sw
若要扩展支持其他I型指令,主要改变Controller模块,EXT模块,ALU模块
1.2.3 J型指令
本CPU不支持J型指令,若要支持j,jr等指令可做以下拓展:
①Controller模块增加JR与JUMP信号输出
②NPC模块增加JR与JUMP信号输入、将Imm16改为Imm26、增加GPR[ra]数据输入
1.2.4 其他
nop
1.3 数据通路模块
1.3.1 IFU(取指令单元)
该模块包含PC(程序计数器)和IM(指令存储器),PC通过32位寄存器实现,存储当前需执行指令的地址,IM通过ROM实现(32 * 32bit),存储所有需要执行的指令。根据PC的值从IM中取出对应指令传入后续数据通路。
注意 :
ROM中是以字为单位存储的,并且ROM容量为32条指令,只需五位数表示地址,所以取PC的62位即可。同理,若ROM容量为1024*32bit则取PC的112位。
- 模块外观
- 模块内部电路
- 端口定义
信号名 方向 位宽 描述 reset I 1 异步复位信号 NPC I 32 下一条要被执行的指令的地址 Imm O 16 当前指令的15~0位 func O 6 当前指令的5~0位 Opcode O 6 当前指令的31~26位 Instr O 32 当前执行的指令 rs O 5 当前指令的25~21位 rt O 5 当前指令的20~16位 rd O 5 当前指令的15~11位 PC O 32 当前指令的地址 - 功能定义
序号 功能名称 功能描述 1 复位 reset信号为1时,PC寄存器的值置为0x00000000 2 取指令 根据当前PC寄存器的值从ROM中读取指令 3 取数据 根据不同位代表不同信息读取指令包含的数据
1.3.2 GRF(通用寄存器组)
该模块包含32个32位寄存器,对应MIPS架构中$0~$31通用寄存器,可以通过输入的5位地址访存寄存器,其中,$0寄存器设置写入信息为const0。
- 模块外观
- 模块内部电路
- 端口定义
信号名 方向 位宽 描述 reset I 1 异步复位信号 WE I 1 写使能信号,决定当前寄存器堆是否可以写入 rs I 5 需要读取的第1个寄存器的编号 rt I 5 需要读取的第2个寄存器的编号 rd I 5 需要写入的寄存器的编号 Data I 32 需要写入寄存器的数据 RD1 O 32 读取到的第1个寄存器的数据 RD2 O 32 读取到的第2个寄存器的数据 - 功能定义
序号 功能名称 功能描述 1 复位 reset信号为1时,所有寄存器的值变为0 2 读取数据 将rs,rt地址对应寄存器的数据加载到RD1,RD2 3 写入数据 WE信号为1且时钟上升沿到来时,将Data中数据写入rd地址对应的寄存器
1.3.3 ALU(算术运算单元)
该模块可以实现加、减、与、或运算,通过ALUOp信号选择何种运算,通过logisim内置算术运算与逻辑运算原件实现运算。
- 模块外观
- 模块内部电路
- 端口定义
信号名 方向 位宽 描述 ALUControl I 3 ALU功能选择信号 SourceA I 32 参与ALU计算的第一个数据 SourceB I 32 参与ALU计算的第二个数据 ALUResult O 32 ALU计算结果 - 功能定义
|序号|功能名称|ALUOp|功能描述|
|1|按位与|000|ALUResult = SourceA & SourceB|
|2|按位或|001|ALUResult = SourceA | SourceB|
|3|加|010|ALUResult = SourceA + SourceB|
|4|减|110|ALUResult = SourceA - SourceB| - 可能的拓展:
- 移位指令sll,srl,sra:
增加ALU模块的shift数据输入,利用logisim内置移位器实现移位;增加ALU模块中ALUOp的对应信号 - add、sub溢出判断:
增加ALU模块FlowJudge信号输入,指示是否需要判断溢出,通过比较temp32与temp31是否相等判断是否溢出,增加ALU模块Overflow信号输出,输出是否溢出
1.3.4 DM(数据存储器)
该模块利用RAM元件实现对数据的访存
注意:
①RAM要设置separate load and store ports
②RAM写使能端不可浮空,否则会随机写入
- 模块外观
- 模块内部电路
- 端口定义
信号名 方向 位宽 描述 reset I 1 异步复位信号 WE I 1 写使能信号,决定当前RAM是否可以写入 ALUResult I 32 需要访存的地址,指向RAM中的某个存储单元 WriteData I 32 需要写入的数据 ReadData O 32 从RAM中读取到的数据 - 功能定义
序号 功能名称 功能描述 1 复位 reset信号有效时,RAM中的数据将被清零 2 读取数据 读取ALUResult地址对应存储单元的数据,将其加载到ReadData 3 写入数据 当WE信号有效且时钟上升沿到来,将WriteData写入ALUResult对应的存储单元 - 可能的拓展
对于lb,lbu,lh,lhu,sb,sh等对字节或者半字进行访存操作的指令,可以设置一个另一个子模块LSControl。首先根据ALUResult将RAM中的对应数据ReadData读取/由WriteData输入数据,然后把32位数据输入LSControl处理,得到真正需要读取的数据LoadData或写入数据StoreData,然后通过mux实现真正数据的读取和写入。
1.3.5 Controller(控制器)
通过解码Opcode(3125)和func(50)以及Instr整体,输出当前指令对应的控制信号。主要组成是AND逻辑——当前是和指令;OR逻辑——当前指令对应的信号输出。
- 模块外观
- 模块内部电路
- 端口定义
信号 方向 位宽 描述 触发信号 Opcode I 6 指令的31~26位 func I 6 指令的5~0位,确定是何种R型指令,I型和J型指令不必要判断 add,sub Instr I 32 整条指令,这里主要是判断是否为nop指令 RegDst O 1 0:寄存器堆写入寄存器为rt(20 16) 1:寄存器堆写入寄存器为rd(1511)add,sub RegWrite O 1 0:寄存器堆不可写入 1:寄存器堆写入使能 add,sub,ori,lw,lui MemtoReg O 1 0:ALUResult写入寄存器堆 1:ReadData写入寄存器堆 lw ALUSource O 1 0:ALU的SourceB是RD2 1:ALU的SourceB是ImmExtend ori,lw,sw,lui MemWrite O 1 0:DM不可写入 1:DM可以写入 sw Branch O 1 0:是Beq指令 1:不是Beq指令 beq EXTCtrl O 2 00:符号拓展 01:零拓展 10:将imm16左移16位 11:sign_extend(imm16 + 00) ori,lw,sw,beq,lui ALUCtrl O 3 控制ALU进行何种运算的信号 add,sub,ori,lw,sw,beq,lui - 功能定义
序号 功能名称 功能描述 1 输出控制信号 根据Opcode和func输出控制整个数据通路的信号 - 可能的拓展
跟据不同的指令要求,输出所需要的控制信号
1.3.6 BranchControl(B类指令控制模块)
该模块主要用于处理B类指令是否跳转,B类指令可以跳转有两个条件:①是B类指令②满足跳转要求
- 模块外观
- 模块内部电路
- 端口定义
信号 方向 位宽 描述 ALUResult I 1 判断是否为0、不为0、大于0等等,从而去匹配B类指令的跳转条件 Branch I 1 当前指令是否是B类指令 PCSource O 1 控制信号,控制NPC是(PC+4)或者B类信号跳转到的PC值 - 功能定义
序号 功能名称 功能描述 1 PC跳转信号输出 决定NPC是否是B类指令跳转到的PC值 - 可能的拓展
①需要增加BranchOp信号输入,判断当前是何种B类指令
②对于bltz,blez,bgtz,bgez等指令,增加32位操作数输入,直接与0比较判断即可。
最终PCSource信号输出由mux和与门合力完成。
1.3.7 EXT(扩展单元)
本模块根据不同指令对立即数的扩展需要对立即数进行扩展
- 模块外观
- 模块内部电路
- 端口定义
信号 方向 位宽 描述 Imm I 16 需扩展的立即数 EXTControl I 2 控制进行何种扩展 ImmExtend O 16 扩展结果 - 功能定义
序号 功能名称 功能描述 1 立即数扩展 把立即数进行相应拓展
1.3.8 NPC(计算下一条指令的地址)
该模块用于计算下一条需要执行的指令的地址
- 模块外观
- 模块内部电路
- 端口定义
信号 方向 位宽 描述 PC I 32 当前指令地址 Imm I 16 当前指令的15~0位 PCSource I 1 0:PC+4 1:B类指令跳转地址 NPC O 32 下一条指令地址 - 功能定义
序号 功能名称 功能描述 1 计算NPC 根据当前指令计算NPC - 可能的拓展
主要是对于J类指令的拓展
对于J需要增加指令25~0位输入,对于jal还需增加PC+4输出,对于jr指令需增加$ra的数据输入。然后利用splitter和mux实现最终的NPC输出。
2 测试方案
2.1 典型测试样例
1 | # 算术指令 |
可见除$gp $sp 等特殊寄存器外,其他寄存器值相同
此外通过和同学对拍测试其他数据(包括边界数据65533、65535等),只有在使能端不关心这个数据(即这个数据并不进入这条指令对应的数据通路)时,数据会出现不同,其他情况下输出相同。
2.2 自动测试工具
该python程序可以实现将MIPS程序text.asm 转化成rom.txt并自动加载进存有cpu电路文件P3_v2.circ的ROM元件中,并生成新的电路文件P3_v2_remake.circ
使用虚拟机里python3然后CTRL+D退出,然后cd到python文件所在文件夹,输入python3 -u <filename>.py
即可执行python文件。
1 | import os |
3 思考题解答
- 现在我们的模块中 IM 使用 ROM, DM 使用 RAM, GRF 使用 Register,这种做法合理吗? 请给出分析,若有改进意见也请一并给出。
答:
①首先这个设计思路是合理的,ROM是是只读存储器,不能修改数据,可以用于存储指令,因此满足IM对于只读功能的需要;RAM是随机存储器,可以实现读取和写入数据,因此可以满足DM的读写功能需求;GRF是寄存器堆,用寄存器实现也是合理的。
②但我们应当注意到指令存储器为ROM时,存在过度简化。在大多数实际处理器中,指令存储器必须是可写的,从而使操作系统可以载入一个新的程序到存储器中。(好像黑书某个注释部分写的有,记不清楚辣)
祝P3上机一切顺利!
P3_Review
- 具体题目记得不是很清楚了,前两个题比较简单,要注意的是在模块增加输入输出端口的时候,模块外观也会改变,接线可能出错,注意一下模块接口。
- 需要注意的是,课上的MARS需要导入新的指令,setting -> load instruction,将下载的class.h文件导入。手写测试机器码真的太蠢了。
再接再励!一口气干到P8!
- Post title:P3
- Post author:Coooookie
- Create time:2023-01-02 20:29:52
- Post link:https://coooookie0913.github.io/2023/01/02/P3/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.