# P3 课上测试游记

通过阅读本文,您可以大致了解 2021 年秋季北航计算机组成课程 P3 课上测试的题目内容、难度和解题思路
P3 课上测试的主要内容是对课下用 Logisim 搭建单周期 CPU 进行强测,同时添加一些新指令
题目每年都会发生变化,题意描述大致清晰,但是可能与原题有一定差异

想要完成 P3 课上,请务必保证熟悉单周期 CPU 的数据通路,同时课下一定要尝试自行添加一些指令,比如 jaljr 以及 lbsb

# T1 添加 bezal 指令

指令的意思是 branch if equal to zero and link

指令格式

special$rs$rt00funct
0000005 位寄存器地址5 位寄存器地址0000000000110001

操作

if (GPR[$rt] == 0)
	NPC <- GPR[$rs]
	GPR[$ra] <- PC + 4
else
	NPC <- PC + 4

解法

  • ALU 增加一位输出,判断 $rt 是否为 0,把这一位连到 NPC 和 CTRL 上
  • GRF 读出的 RD1 连到 NPC 上(如果课下搭过 jr ,那这一步已经做过了)
  • NPC 根据信号判断是否跳转到 GPR[$rs]
  • CTRL 根据信号判断 GPR 的写使能 WE 是否为 1(即是否把 PC + 4 写到 $ra 里面)(这一条我刚开始没加,就意味着每一次执行到 bezal ,不管是否相等,都会往 $ra 里面写入 PC+4 ,但是自己测试根本看不出,调了 20+min...)

# T2 添加 slo 指令

指令的意思是 shift left and or

这一题出的就比较灵活了

指令格式

special0$rt$rdshamtfunct
000000000005 位寄存器地址5 位寄存器地址左移的位数101010

操作

GPR[$rd] <- GPR[$rd]<<shamt | 1*{shamt}

(翻译成大白话)把 $rt 里的值左移 shamt 位,左移出来的位填 1,把这个数存到 $rd

解法

  • 首先明确只需要在 ALU 和 CTRL 中修改
  • 下面是非常暴力的做法
  • 首先利用 Bit Shifter 把 GPR[$rd] 左移 shamt
  • 然后再利用 Bit Shifter 把 32'b1000_0000_0000_0000_0000_0000_0000_0000 算术右移 shamt-1
  • 再把上述结果利用 Bit Shifter 循环左移 shamt
  • 得到了 32'b0000...00111...1 (后面有 shamt 个 1)
  • 然后两者取按位或运算得到答案

# T3 添加 lwor 指令

指令的意思就是是 load word

指令格式

opcodebase$rtoffset
1011015 位寄存器地址5 位寄存器地址16 位偏移量

操作

Addr <- [GPR[base] + sign_extend(offset) + rt*4] & 0x7c
GPR[rt] <- Memory[Addr]

注意区分 rt$rt ,前者代表 rt 的地址,后者代表 GPR($rt)

解法

  • 首先明确需要修改的是 ALU 和 CTRL(注意,其实本题不需要对 DM 做任何改动)
  • 把操作中描述的那一堆运算扔给 ALU 做,输出 C 就连接 DM 的地址
  • 注意再做 rt*4 的时候先扩展到 32 位再移位,否则可能会溢出?

# T4 选择题

第一题是挑错,找 beqjal 实现中的错误,位扩展、与门和或门用错了

第二题是问 subiuaddiu 是否等价,貌似补码表示时负数比正数能多表示一个数,所以我选的不等价对了,但是不知道是不是这个原因

# 提答

  • 就是解释你的设计,然后问一下调试时的问题

# 一些提示

课上第一题前几个点好像只有课下添加的指令,如果这些错了也许是意味着课下的设计有问题,可能还要调试一会...