计组P3设计文档
P3建议:在阅读课件的基础上梳理每个线路、接口的数据从哪里来、到哪里去,便于理解
设计要求
处理器为 32 位单周期处理器,应支持的指令集为:
add, sub, ori, lw, sw, beq, lui, nop
,其中:nop
为空指令,机器码0x00000000
,不进行任何有效行为(修改寄存器等)。add, sub
按无符号加减法处理(不考虑溢出)。
需要采用模块化和层次化设计。顶层有效的驱动信号要求包括且仅包括异步复位信号 reset(clk 请使用内置时钟模块)。
模块规格
顶层设计
IFU(取指令单元)
- 内部包括 PC(程序计数器)、IM(指令存储器)及相关逻辑。
- PC 用寄存器实现,应具有异步复位功能,复位值为起始地址。
- 起始地址:0x00003000。
- 地址范围:0x00003000 ~ 0x00006FFF。
- IM 用 ROM 实现,容量为 4096 × 32bit。
- IM 实际地址宽度仅为 12 位,需要使用恰当的方法将 PC 中储存的地址同 IM 联系起来。
PC(Moore型状态机)
变量 | 方向 | 位宽 | 解释 | 来源/去向 |
---|---|---|---|---|
clk | in | 1 | 时钟信号 | 内置 |
rst | in | 1 | 异步复位信号 | 顶层输入 |
ctrl | in | 1 | 控制信号 | Control |
beq_addr | in | 32 | 跳转指令地址 | IM的Instr |
addr | out | 32 | 下一条指令地址 | IM |
难点:异步复位置0x00003000
解决方案:输出+0x00003000,内部仍从0开始
IM
变量 | 方向 | 位宽 | 解释 | 来源/去向 |
---|---|---|---|---|
sel? | in | 1 | 读取选择信号 | |
addr | in | 12 | 指令地址 | PC |
Instr | out | 32 | 指令机器码 | Control/PC/ |
GRF(通用寄存器组,也称为寄存器文件、寄存器堆)
- 用具有写使能的寄存器实现,寄存器总数为 32 个,应具有异步复位功能。
- 0 号寄存器的值始终保持为 0。其他寄存器初始值(复位后)均为 0,无需专门设置。
变量 | 方向 | 位宽 | 解释 | 来源/去向 |
---|---|---|---|---|
clk | in | 1 | 时钟信号 | 内置 |
rst | in | 1 | 异步复位信号 | 顶层输入 |
WE/RegWrite | in | 1 | 写使能信号 | Control |
RegAddr | in | 5 | GRF 5 位写入地址 | Instr |
WD/RegData | in | 32 | GRF 32 位写入数据 | ALU/DM/Instr |
A1 | in | 5 | 读出数据的寄存器编号 | Instr |
A2 | in | 5 | 读出数据的寄存器编号 | Instr |
RD | out | 32 | GRF 32 位读出数据 | ALU |
RD2 | out | 32 | GRF 32 位读出数据 | ALU |
ALU(算术逻辑单元)
?比较按无符号还是有符号?
- 提供 32 位加、减、或运算及大小比较功能。
- 加减法按无符号处理(不考虑溢出)。
变量 | 方向 | 位宽 | 解释 | 来源/去向 |
---|---|---|---|---|
op | in | 2 | 功能选择 | Control |
a | in | 32 | 操作数1 | GRF/Instr |
b | in | 32 | 操作数2 | GRF/Instr |
out | out | 32 | 结果 | GRF/DM |
DM(数据存储器)
- 使用 RAM 实现,容量为 3072 × 32bit,应具有异步复位功能,复位值为 0x00000000。
- 起始地址:0x00000000。
- 地址范围:0x00000000 ~ 0x00002FFF。
- RAM 应使用双端口模式,即设置 RAM 的 Data Interface 属性为 Separate load and store ports。
变量 | 方向 | 位宽 | 解释 | 来源/去向 |
---|---|---|---|---|
MemWrite | in | 1 | DM 写入控制信号 | Control |
MemAddr | in | 32 | DM 32 位写入地址 | ALU |
MemData | in | 32 | DM 32 位写入数据 | GRF |
MemData | out | 32 | DM 32 位输出数据 | GRF |
EXT(扩展单元)
- 可以使用 Logisim 内置的 Bit Extender。
Controller(控制器)
- 使用与或门阵列构造控制信号的具体方法见后文叙述。
- 也可以通过其它方式构造控制信号,同学们可以自行探索。
指令解读
指令 | 31-26 | 25-21 | 20-16 | 15-11 | 10-6 | 5-0 | 解释 |
---|---|---|---|---|---|---|---|
add | 000000 | rs | rt | rd | 00000 | 100000 | rd=rs+rt |
sub | 000000 | rs | rt | rd | 00000 | 100010 | rd=rs-rt |
ori | 001101 | rs | rt | im | im | im | rt=rs|im |
lw | 100011 | base | rt | offset | offset | offset | rt=mem(base+of) |
sw | 101011 | base | rt | offset | offset | offset | mem(base+of)=rt |
beq | 000100 | rs | rt | offset | offset | offset | PC+=4+of00? |
lui | 001111 | 00000 | rt | im | im | im | rt=im(0*16) |
控制器
变量 | 方向 | 位宽 | 解释 |
---|---|---|---|
Instr | in | 32 | 指令机器码 |
ctrl | out | 1 | PC,控制是否beq |
WE | out | 1 | GRF,写使能信号 |
GRF_op1 | out | 1 | GRF,控制写入地址来源(0,rd) |
GRF_op2 | out | 2 | GRF,控制写入数据来源(0,ALU,1,DM) |
op | out | 2 | ALU,运算选择 |
ALU_op | out | 1 | ALU,控制运算数来源(0,rt,1,im,2,of) |
MemWrite | out | 1 | DM,写入控制信号 |
思考题
上面我们介绍了通过 FSM 理解单周期 CPU 的基本方法。请大家指出单周期 CPU 所用到的模块中,哪些发挥状态存储功能,哪些发挥状态转移功能。
状态存储:GRF、DM、IFU
状态转移:ALU、Controller、EXT
现在我们的模块中 IM 使用 ROM, DM 使用 RAM, GRF 使用 Register,这种做法合理吗? 请给出分析,若有改进意见也请一并给出。
合理,IM存储指令,一般无需、也不应在执行过程中修改,因此使用ROM;DM需要读写,因此使用RAM;GRF所需存储规模较小,而且某些指令需要同时执行存储、读出行为,因此每一寄存器用 Register较为合理。
在上述提示的模块之外,你是否在实际实现时设计了其他的模块?如果是的话,请给出介绍和设计的思路。
设计了指令解读模块,将32位机器码按字段转为相应的值如OPcode、rt、offset等。思路就是利用splitter,只是将其封装为模块。
事实上,实现
nop
空指令,我们并不需要将它加入控制信号真值表,为什么?输入nop指令时,Conrtoller内部的与门阵列输出信号全为0,GRF、DM的写信号为0,因此相当于没进行任何操作。
阅读 Pre 的 “MIPS 指令集及汇编语言” 一节中给出的测试样例,评价其强度(可从各个指令的覆盖情况,单一指令各种行为的覆盖情况等方面分析),并指出具体的不足之处。
指令覆盖情况:缺少sub指令
单一指令覆盖:add缺少
intmax
,ori缺少中间值,lui缺少0,lw、sw偏移量没考虑负数,beq跳转范围应包含前后。
测试方案
机器码转指令的
运行C语言代码(code_instruction.c),1为从文件输入,输出到文件;2为单个指令翻译
自动生成数据点的C语言代码
待开发,目前只有手敲代码(
1 |
|
命令行自动化测试
文件夹下:logisim的jar包、测试电路文件
文件夹打开命令行输入:
java -jar logisim-generic-2.7.1.jar 单周期CPU.circ -tty table > result.txt
运行C语言代码(CPU_test.c),依次输出32个寄存器存储数值,可与MARS比较