【BUAA-CO】p4单周期CPU-verilog实现
发表于:2022-11-24 | 分类: BUAA计算机组成原理
字数统计: 1.3k | 阅读时长: 5分钟 | 阅读量:

BUAA-CO课程p4,用verilog实现单周期的CPU

p4_log

模块化层次化

  • 整体结构与p3中logisim的分层一致,顶层端口定义为mips.v
  • 不同:
    • 需要增加同步复位信号reset
    • clk留端口,而不是内置
  • 需要支持的指令集为:add, sub, ori, lw, sw, beq, lui, jal, jr, nop
  • 后期添加的指令为:slt,sll,lh,sh,lbu

设计方案

  • 模块化、端口定义等等大致和p3一致
  • 连线的时候的命名:推荐使用模块+输出端口命名法,小写字母表示,每一个模块的线放一块,这样输入的时候一目了然
    连线命名
  • 注意存储器地址访问的/4细节,思考题中的[11:2]应该就是出于这个考虑

datapath

  • 所有的MUX放在同一个MUX.v的文件中,命名为:MUX_SelNum_bit(默认为32位), 如MUX_4,MUX_4_26,MUX_2_5;

RF

信号名 IO 描述 备注
clk I 时钟信号
reset I 异步复位
WE I 写使能信号
A1[4:0] I 读出地址1
A2[4:0] I 读出地址2
A3[4:0] I 写入地址
WD[31:0] I 写入的数据
RD1[31:0] O 输出A1地址寄存器中的值
RD2[31:0] O 输出A2地址寄存器中的值

NPC

信号名 IO 描述 备注
PC[31:0] I 当前指令地址
Simm26[25:0] I 地址偏移
ra[31:0] I 返回地址
CmpOut I B类指令的比较结果
NPCOp[2:0] I NPC功能选择:</br> 000: 顺序+4 </br> 001: B类跳转 </br>010: jal/j </br> 011:jr/jalr
NPC[31:0] O 下一条指令地址

EXT

信号名 IO 描述 备注
imm16[15:0] I 16位立即数
EXTOp I EXT功能选择:</br> 0: 0拓展 </br> 1: 符号位拓展 lui指令的高位拓展在ALU里执行
S0imm32 O 拓展后的32位立即数

ALU

信号名 IO 描述 备注
ALUOp[3:0] I ALU功能选择
A[31:0] I 运算数1
B[31:0] I 运算数2
shamt[4:0] I 位移值
ALUout[31:0] O 计算结果
DM
信号名 IO 描述 备注
clk I 时钟信号
reset I 异步复位
WE I 写使能信号
A[31:0] I 待操作数据的地址
DMOp[2:0] I DM功能选择:000: word </br> 001: halfword </br> 010: byte </br> 1xx: 无符号拓展load 最高位置一表示无符号位拓展
DMout[31:0] 输出的32位数据

数据通路表

controller

  • 对于控制器,我采用先用操作码识别出不同的指令,再去记录下每个控制信号所对应的指令,因为这样更加符合电路的直观(或运算),也更符合我对未来的想象()
    控制信号表

测试方案

  • 还是用p3时候的测试数据,但是需要多多注意的是这个东西肉眼debug其实还好一点,但更加适合自动化评测,开始手搓!

增量开发

slt

  • 处理ctrl,ALU,先填表再连线

sll

  • shamt传入ALU,其他就没什么问题了

lh,sh,lhu

  • 加上DMOp,在前面有定义

思考题

  • 阅读下面给出的 DM 的输入示例中(示例 DM 容量为 4KB,即 32bit × 1024字),根据你的理解回答,这个 addr 信号又是从哪里来的?地址信号 addr 位数为什么是 [11:2] 而不是 [9:0]
    • 从ALUout输出过来,是按字节寻址的指令,但我们的IM是按字寻址的,addr应该是4的整数倍,所以左移两位,按字存取。
  • 思考上述两种控制器设计的译码方式,给出代码示例,并尝试对比各方式的优劣。
    • 第二种是最后靠信号输出的,更符合电路的或逻辑,便于后续开发,且更加符合电路
  • 在相应的部件中,复位信号的设计都是同步复位,这与 P3 中的设计要求不同。请对比同步复位与异步复位这两种方式的 reset 信号与 clk 信号优先级的关系。
    • 异步复位reset的优先级高于clk,不管clk是否处于上升沿,都会复位(所以需要加入触发条件中)。
    • 而同步复位的reset优先级低于clk,只有clk到来才会生效。
  • C 语言是一种弱类型程序设计语言。C 语言中不对计算结果溢出进行处理,这意味着 C 语言要求程序员必须很清楚计算结果是否会导致溢出。因此,如果仅仅支持 C 语言,MIPS 指令的所有计算指令均可以忽略溢出。 请说明为什么在忽略溢出的前提下,addi 与 addiu 是等价的,add 与 addu 是等价的。提示:阅读《MIPS32® Architecture For Programmers Volume II: The MIPS32® Instruction Set》中相关指令的 Operation 部分。
    • addi和add,在operate中加入了溢出检测
    • 以add为例
    • 加法检测
    • 若R[rs]和R[rt]的30都是1且31相同的话,就分别对应正数和负数的溢出情况,则这么计算后temp32!temp31,不相等,所以溢出。
    • 检测溢出后就会抛出异常,但没有检测溢出的话,还是正常计算,所以和addiu,addu一样。
上一篇:
【BUAA-CO】p5流水线CPU-lite
下一篇:
【BUAA-CO】p3-单周期CPU(logisim实现)