北航co计算机组成P4设计文档

P4CPU设计文档及思考题
设计草稿
1.指令详解
- ADD:add RD, RS, RT
编码:000000 sssss ttttt ddddd 00000 100000
描述:GPR[rd] = GPR[rs] + GPR[rt] - SUB:sub RD, RS, RT
编码:000000 sssss ttttt ddddd 00000 100010
描述:GPR[rd] = GPR[rs] - GPR[rt] - ORI:ori RT, RS, IMM
编码:001101 sssss ttttt iiiii iiiii iiiiii
描述:GPR[rt] = GPR[rs] | zero_extend(IMM) - LW:lw RT, OFFSET(RS)
编码:100011 sssss ttttt iiiii iiiii iiiiii
描述:GPR[rt] = MEM[GPR[rs] + sign_ext(OFFSET)] - SW:sw RT, OFFSET(RS)
编码:101011 sssss ttttt iiiii iiiii iiiiii
描述:MEM[GPR[rs] + sign_ext(OFFSET)] = GPR[rt] - BEQ:beq RS, RT, LABEL
编码:000100 sssss ttttt iiiii iiiii iiiiii
描述:if GPR[rs] == GPR[rt], PC = PC + 4 + sign_ext(LABEL); else PC = PC + 4; - lui:lui RT, IMM
编码:001111 00000 ttttt iiiii iiiii iiiiii
描述:GPR[rt] = sign_ext(IMM) << 16; - jal: jal target
编码:000011 iiiii iiiii iiiii iiiii iiiiii
描述:GPR[31] = PC + 4; PC = PC[31,28]||instr_index||00 - jr: jr rs
编码:000000 sssss 00000 00000 00000 001000
描述:PC = GPR[rs] - nop:nop
编码:000000 00000 00000 00000 00000 000000
描述:GPR[0] = GPR[0]
2.各部件接口设计
NPC
| 接口名称 | 输入或输出 | 位宽 | 描述 |
|---|---|---|---|
| PC | I | 31:0 | 前一拍指令地址 |
| offset | I | 31:0 | 用于计算B类指令跳转地址 |
| Ins_26 | I | 25:0 | 用于计算J、JAL跳转地址 |
| Ra | I | 31:0 | 用于读取JR、JALR中寄存器存储的地址 |
| if_Branch | I | 1 | 用于判断是否为B类指令 |
| if_JR | I | 1 | 用于判断是否为J、JR指令 |
| Next_PC | O | 31:0 | 下一拍指令地址 |
| PC+4 | O | 31:0 | 上一拍指令地址+4,用于JAL、JALR地址存储 |
IFU
| 接口名称 | 输入或输出 | 位宽 | 描述 |
|---|---|---|---|
| clk | I | 1 | 时钟信号 |
| Reset | I | 1 | 同步复位信号 |
| Next_PC | I | 31:0 | 计算出的下一拍指令地址 |
| PC | O | 31:0 | 当前指令地址 |
| Instr | O | 31:0 | 当前指令内容 |
GRF
| 接口名称 | 输入或输出 | 位宽 | 描述 |
|---|---|---|---|
| RA1 | I | 4:0 | 读寄存器1地址 |
| RA2 | I | 4:0 | 读寄存器2地址 |
| WA | I | 4:0 | 写寄存器地址 |
| WD | I | 31:0 | 写寄存器数据 |
| clk | I | 1 | 时钟信号 |
| reset | I | 1 | 同步复位信号 |
| RegWrite | I | 1 | 写寄存器控制信号 |
| RD1 | O | 31:0 | 读寄存器1数据 |
| RD2 | O | 31:0 | 读寄存器2数据 |
ALU
| 接口名称 | 输入或输出 | 位宽 | 描述 |
|---|---|---|---|
| ALU_Op | I | 3:0 | ALU操作码 |
| Src_A | I | 31:0 | ALU输入A数据 |
| Src_B | I | 31:0 | ALU输入B数据 |
| shift | I | 5:0 | 位移量(对B数据进行位移) |
| AequalB | O | 1 | ALU输出结果是否等于输入B数据 |
| AsmallB | O | 1 | ALU输出结果是否小于输入B数据 |
| AbigB | O | 1 | ALU输出结果是否大于输入B数据 |
| ALU_Result | O | 31:0 | ALU输出结果 |
DM
| 接口名称 | 输入或输出 | 位宽 | 描述 |
|---|---|---|---|
| clk | I | 1 | 时钟信号 |
| Reset | I | 1 | 同步复位信号 |
| MemWrite | I | 1 | 写内存控制信号 |
| A | I | 31:0 | 写地址 |
| WD | I | 31:0 | 写数据 |
| RD | O | 31:0 | 读数据 |
EXT
| 接口名称 | 输入或输出 | 位宽 | 描述 |
|---|---|---|---|
| Imm | I | 15:0 | 扩展前的立即数 |
| if_sign | I | 1 | 是否为有符号扩展 |
| offset | O | 31:0 | 扩展后的立即数 |
3.数据通路设计
以下表示每个部分应该如何连接,连接在mips顶层中,本人采取的形式是:
1 | wire [31:0] NPC_PC; |
此形式虽复杂但是方便debug)
NPC
| 操作 | PC | offset | Ins_26 | RA | if_Branch | if_jr | if_jal |
|---|---|---|---|---|---|---|---|
| all | IFU | EXT | splitter | GRF | control | control | control |
IFU
| 操作 | clk | Reset | Next_PC |
|---|---|---|---|
| all | clk | reset | NPC |
GRF
| 操作 | clk | Reset | RA1 | RA2 | WA | WD | RegWrite |
|---|---|---|---|---|---|---|---|
| add | clk | reset | splitter[s] | splitter[t] | splitter[d] | ALU | control |
| sub | clk | reset | splitter[s] | splitter[t] | splitter[d] | ALU | control |
| ori | clk | reset | splitter[s] | - | splitter[t] | ALU | control |
| lw | clk | reset | splitter[s] | - | splitter[t] | DM | control |
| sw | clk | reset | splitter[s] | splitter[t] | - | - | control |
| beq | clk | reset | splitter[s] | splitter[t] | - | - | control |
| lui | clk | reset | - | - | splitter[t] | ALU | control |
| jal | clk | reset | - | - | 31 | NPC | control |
| jr | clk | reset | splitter[s] | - | - | - | control |
ALU
| 操作 | ALU_Op | Src_A | Src_B | shift |
|---|---|---|---|---|
| add | control | GRF-RD1 | GRF-RD2 | - |
| sub | control | GRF-RD1 | GRF-RD2 | - |
| ori | control | GRF-RD1 | EXT | - |
| lw | control | GRF-RD1 | EXT | - |
| sw | control | GRF-RD1 | EXT | - |
| beq | control | GRF-RD1 | GRF-RD2 | - |
| lui | control | - | EXT | 16 |
| jal | - | - | - | - |
| jr | - | - | - | - |
DM
| 操作 | clk | Reset | MemWrite | A | WD |
|---|---|---|---|---|---|
| lw | clk | reset | control | ALU-Result | - |
| sw | clk | reset | control | ALU-Result | GRF-RD2 |
| else | - | - | - | - | - |
EXT
| 操作 | Imm | if_sign |
|---|---|---|
| all | splitter[i] | control |
4.控制信号
总控制
| 数值 | MemToReg | MemWrite | ALUSrc | RegWrite | signedEXT | RegDst | if_Branch | if_JR | if_JAL | AddrToReg | Ralink | if_lui |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 控制的位置 | GRF-WD | DM-MemWrite | ALU-SrcB | GRF-RegWrite | EXT-if_sign | GRF-WA | NPC-if_Branch | NPC-if_JR | NPC-if_JAL | GRF-WD | GRF-WA | ALU_shift |
| 0 | ALU | unable | GRF-RD2 | unable | zero_extend | splitter[t] | NOT-BEQ | NOT-JR | NOT-JAL | - | - | - |
| 1 | DM | enable | EXT | enable | sign_extend | splitter[d] | BEQ | JR | JAL | 将PC+4存入寄存器 | 将PC+4存入寄存器的编号(31) | 偏移量16 |
ALU控制
0000 : +
0001 : -
0010 : |
0011 : 数据B向左位移shift位
指令对应控制信号
| 指令 | ALU操作 | ALUcontrol | MemToReg | MemWrite | ALUSrc | RegWrite | signedEXT | RegDst | if_Branch | if_JR | if_JAL | AddrToReg | Ralink | if_lui |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| add | + | 0000 | 0 | 0 | 0 | 1 | - | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
| sub | - | 0001 | 0 | 0 | 0 | 1 | - | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
| ori | or | 0010 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| lw | + | 0000 | 1 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| sw | + | 0000 | - | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| beq | == | - | 0 | 0 | 0 | 0 | 1 | - | 1 | 0 | 0 | 0 | 0 | 0 |
| lui | << | 0011 | 0 | 0 | 1 | 1 | - | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| jal | - | - | 0 | 0 | - | 1 | - | 0 | 0 | 0 | 1 | 1 | 1 | 0 |
| jr | - | - | 0 | 0 | - | 0 | - | - | 0 | 1 | 0 | 0 | 0 | 0 |
课上
采用P3的思路可以继续解决
往年题可以看推荐题,同时指路室友博客
思考题点击展开,不保证正确性,建议自己思考
思考题
1.阅读下面给出的 DM 的输入示例中(示例 DM 容量为 4KB,即 32bit × 1024字),根据你的理解回答,这个 addr 信号又是从哪里来的?地址信号 addr 位数为什么是 [11:2] 而不是 [9:0] ?
addr来源:来自ALU计算出的有效地址,ALU计算出的32位地址取其中的[11:2]位。
ALU计算出的有效地址是按字节寻址(地址最低2位[1:0]用于字节选择,[13:2]用于字选择),而在Verilog中构建的DM是按字寻址的。所以,需要将ALU计算出的地址左移两位,即除以四,才是DM中的地址。另外,DM容量是32bit × 1024字,可知,字地址有10位。
2.思考上述两种控制器设计的译码方式,给出代码示例,并尝试对比各方式的优劣。
1.指令对应的控制信号如何取值
1 | case(instr) |
2.控制信号每种取值所对应的指令
1 | assign MemTOReg = (All_input == `lw); |
3.优劣对比
| 特性 | 方式一(查表式) | 方式二(分布式) |
|---|---|---|
| 可读性 | 高,结构清晰 | 低,逻辑分散 |
| 可维护性 | 高,修改集中 | 低,修改分散 |
| 扩展性 | 中等 | 高,易于添加新信号 |
| 综合结果 | 可能生成较大多路器 | 逻辑更优化 |
| 调试难度 | 容易调试 | 较难调试 |
3.在相应的部件中,复位信号的设计都是同步复位,这与 P3 中的设计要求不同。请对比同步复位与异步复位这两种方式的 reset 信号与 clk 信号优先级的关系。
同步复位,clk优先级更高
异步复位,reset优先级更高
4.C 语言是一种弱类型程序设计语言。C 语言中不对计算结果溢出进行处理,这意味着 C 语言要求程序员必须很清楚计算结果是否会导致溢出。因此,如果仅仅支持 C 语言,MIPS 指令的所有计算指令均可以忽略溢出。 请说明为什么在忽略溢出的前提下,addi 与 addiu 是等价的,add 与 addu 是等价的。提示:阅读《MIPS32® Architecture For Programmers Volume II: The MIPS32® Instruction Set》中相关指令的 Operation 部分。
“ADDU performs the same arithmetic operation but does not trap on overflow”
add与addu指令的大致功能是一样的。其区别是add在溢出时,触发Integer Overflow异常;而addu忽略溢出,不产生异常。因此在忽略溢出的C语言环境下,两条指令完全等价。同理,addi与addiu在忽略溢出时也是等价的。
本作品由 一一 于 2026-02-13 11:00:00 发布
作品地址:北航co计算机组成P4设计文档
除特别声明外,本站作品均采用 CC BY-NC-SA 4.0 许可协议,转载请注明来自 anAilurus' Blog
