BUAA-CO-p3-课下
整体设计
本次P3要求实现的指令:add sub ori lw sw lui beq

整体设计参考黑书
各模块设计
由于添加额外指令的原因,某些模块可能比只完成课下要求的cpu多出一些端口
IFU
我是从IFU开始搭的,因为只有确定了指令,才好确定其他部件的功能
| 端口名称 | IO | 功能 |
|---|---|---|
| NPCOp[1:0] | I | 确定PC的状态转移形式 |
| InStr[31:0] | O | 要执行的机器码 |
| PC | O | 当前PC |
IFU本身的逻辑其实并不复杂,但是如果要实现更多对于PC进行操作的指令,如 j,jal,jr等,就需要很多额外的输入与运算。为保持精简,此处仅列出完成p3课下必要的端口。
如果需要满足更多 j型指令的需求,我们用多路选择器,依据 NPCOp来选择PC转移至NPC的依据。

另外需要注意的是,PC在 reset时需要置为 0x00003000而非 0x00000000。
GRF
直接复用p0搭的即可,这里不再赘述
提醒:P0对于GRF的评测强度较弱,请自行检查是否有隐藏的bug
ALU
| 端口名称 | IO | 功能 |
|---|---|---|
| SrcA[31:0] | I | 计算的第一个数 |
| SrcB[31:0] | I | 计算的第二个数 |
| Ans[31:0] | O | 答案 |
| ALUOp | I | 选择计算模式 |
DM
| 端口名称 | IO | 功能 |
|---|---|---|
| Addr[31:0] | I | 地址 |
| WD[31:0] | I | 数据内容 |
| RD[31:0] | I | 读出数据 |
| WE | I | 写使能 |
需要注意的是,DM中使用的是RAM,而Logisim中RAM的地址最多只能为14位,因此要取输入地址的低14位
CRTL
同IFU,此处仅列出通过本次P3必要的端口
| 端口名称 | IO | 功能 |
|---|---|---|
| op[5:0] | I | opcode |
| func[5:0] | I | func code |
| ALUOp[1:0] | O | ALU模式选择 |
| ALUSrc | O | 选择ALU的第二个输入(RD2还是Imm) |
| RegWr | O | GRF的写使能 |
| RegWrOp[1:0] | O | 选择GRF写入的数据 |
| MemWr | O | DM写使能 |
| MemToReg | O | 选择RegData(ALU结果还是DM的RD) |
| EXTOp | O | 是否进行sign_extend |
调试过程
课下测试很弱,一定要自己调
比较容易出问题的就是 beq,看清RTL语言后再动手搭线。一个问题是 offset需要左移2位后再进行符号位扩展,另一个是 offset不是绝对地址而是偏移量,因此 addr除 offset外还需 + PC + 4
调试工具
关于样例的生成,这里推荐23级学长的随机样例生成器。强度是够的,不过需要自己添加 jal指令。
关于自动化测评机,这里推荐轮椅流自动测评机。
指令添加
R-R运算一般来说,其编码格式为:
| 31:26 | 25:21 | 20:16 | 15:11 | 10:6 | 5:0 |
|---|---|---|---|---|---|
| 000000 | rs | rt | rd | 00000 | func |
主要添加ALU的操作,同时可能增加 ALUOp的位数,开启GRF写使能,写入地址选 rd,写入数据选 RegData
R-I运算
| 31:26 | 25:21 | 20:16 | 15:0 |
|---|---|---|---|
| op | rs | rt | imm16 |
将 $rs与 signed_ext(imm16)进行运算,存入 rt
与 R-R最主要的不同在于 ALUSrc置1,写入地址选 rt
- 分支
| 31:26 | 25:21 | 20:16 | 15:0 |
|---|---|---|---|
| op | rs | rt | offset |
用ALU进行运算后,如果满足分支跳转条件,PC转移到
所有分支指令对于PC的计算方法是一样的,因此可以这样做: 将指令选中信号与ALU输出的判断信号做 && ,再与其他分支信号做 ||,如果得到1,则将 NPCOp置 branch的指定信号,否则置0。
跳转
j和jal没有本质区别,jal只是多了一步存PC+4的操作。显然,这两种指令是对PC的转移方式进行的扩展,所以主要注意力应放在IFU和NPCOp上。我们要为IFU增加
instr_index的端口,增加NPCOp的选择。除此以外,不要忘记jal要对$31寄存器进行写入操作,因此要打开GRF的写使能、增加写入地址处的多路选择器以及对应的RegDst的选择(当然也可以选择在最后端额外加一个专门服务与jal的多路选择器,与一个jal?信号,但这不符合模块化的设计思想,虽然笨人就是这么做的),以及给IFU增加一个PC+4的输出端口,作为写入的数据源。那么既然数据源增加了,RegWrite模块中的选择又多了一个,RegWrOp的选择也要多一个…jr和jalr可以放在一起说这两条指令的核心是让PC转移到
GRF[rs],那么首先要将GRF[rs]传入IFU中,然后增加NPC的选择。jalr再进行一步对$rd的写入操作:打开GRF写使能、写入寄存器地址选择rd,写入数据选择PC+4,即可。
- Title: BUAA-CO-p3-课下
- Author: OWPETER
- Created at : 2024-10-24 13:32:15
- Updated at : 2025-08-09 17:04:31
- Link: https://owpeter.github.io/2024/10/24/CO/CO-p3-beforeclass/
- License: This work is licensed under CC BY-NC-SA 4.0.