你好!本文章为该博客的第3篇文章!

本文章是对课上部分的题目回忆,不保证回忆内容一定正确,请各位注意甄别!

以及,如果本文章涉及学术诚信问题,请第一时间和我联系,我将及时做出修改,谢谢支持!

P3课上题目回忆

三题为互相独立的添加指令题。(懒得写RTL了)

第一题添加指令为 cwp,I型指令。具体操作为,将 imm 零扩展为32位数后逻辑左移8位的结果与PC的值进行比较,若大于PC,则将 imm 零扩展的结果存入 GPR[rs] 中,否则存入 GPR[rt] 中。

第二题添加指令为 bgc,I型指令。具体操作为,将 GPR[rs] 分割为16个二进制数后,将每个二进制数 ii 转为其格雷码 greyigrey_i,计算所有转化结果的1的个数之和,若该总和大于 rt,则进行类似 beq 的指令跳转,否则PC正常自增。

第三题添加指令为 lwso,I型指令。具体操作为……这题我不建议看文字描述,直接看伪代码吧:

1
2
3
4
5
6
7
8
h_temp = GPR[rt] & 0xf;
reg_right = (GPR[rt] >> h_temp) & 0x1f;
reg_left = (GPR[rt] << h_temp) & 0x1f;
write_data = mem[GPR[rs]+sign_ext(imm)];
if (write_data % 2 == 1)
GPR[reg_left] = write_data;
else
GPR[reg_right] = write_data;

对CPU电路连接的几点建议

  • 尽可能让主模块仅起到连接各模块的作用,并且尽可能用Tunnel沟通各模块。这样在对电路进行修改时,我们可以把精力只放在对各个模块内部的修改,而无需过度置疑CPU连接的正确性。
  • 可以预先对模块外观进行修改后再接入CPU,否则务必注意外观变化对CPU处接线的影响。
  • 为模块新增端口时,可以先把使用该模块的端口断开,再进行添加,添加时保证新端口在旧端口的下方。
  • 课下的时候控制信号请务必集成到控制器里,能不新开模块就别新开模块生成控制信号。

题目分析

这三题都是不涉及新增数据通路的新增指令题,因此仅需要考虑指令对各模块的影响即可。正是基于这样的想法,以下分析里我会尽量只列出修改的模块和修改方法。

需要额外注意的是,对一些故意绕的离谱的指令,请务必直接读RTL。

为了防止大家看不懂所以把我课下设计的模块放上来

  • 取指令模块(IFU):根据PC的值,从内存中读出指令。
  • 译码器(InstSplitter):将指令按MIPS指令集架构分为各个部分。
  • 通用寄存器组(GRF):读取最多两个寄存器的值,向最多一个寄存器写入值。
  • 控制器(Controller):确定CPU各部分写入使能和写入数据源。
  • 分支控制器(BranchController):计算并选择分支跳转的目标地址。
  • ALU解码器(ALUDecoder):确定ALU需要执行的运算操作ALU_opcode。
  • ALU立即数扩展(ALUExt):确定立即数扩展方式,对立即数进行扩展。
  • ALU运算数选择器(ALUMux):确定操作数源,选择ALU的操作数。
  • 算数逻辑单元(ALU):对操作数进行运算。
  • PC写入值选择器(PCMux):选择下一周期PC的值。
  • 数据内存(DM):进行内存读写。
  • GRF写入地址选择器(GRFAddrMux):选择下一周期写入的寄存器。
  • GRF写入值选择器(GRFMux):选择下一周期写入寄存器的值。

cwp

需要修改的模块有控制器,ALU解码器,ALU,GRF写入地址选择器。

具体来说:

  • (控制器)该指令将触发GRF写入信号,并且需要额外输入立即数和PC值比较,产出比较信号;
  • (ALU解码器,ALU)该指令将新增直接将立即数零扩展结果作为运算结果的运算;
  • (GRF写入地址选择器)该指令将对GRF的写入地址额外进行影响,并且可能额外用到rs作为写入寄存器地址,额外用到比较信号作为选择依据。

bgc

需要修改的模块有控制器,分支控制器。

具体来说:

  • (控制器)该指令将触发写入PC数据源选择信号。
  • (分支控制器)该指令将额外需要rt作为分支跳转条件的数据源,添加bgc的分支跳转判断结果生成。

另外,由于需要对两位二进制数进行格雷码转化,因此需要新增两个模块,一个对两位二进制数进行格雷码转化,另一个对16组两位二进制数的格雷码1的个数进行合并(这里可以采用bitadder元件)。第二个元件放入分支控制器内,辅助分支跳转条件的计算。

lwso

需要修改的模块有控制器,GRF写入地址选择器。

具体来说:

  • (控制器)该指令将触发GRF写入信号,DM读信号,GRF写入数据源选择信号。
  • (GRF写入地址选择器)该指令将需要额外用到 GRF[rt] 和DM读出结果作为写入寄存器地址选择依据。

需要额外注意的是,对一些故意绕的离谱的指令,请务必直接读RTL,照着RTL慢慢写,需要“暂存”的东西就用Tunnel标记一下。

反思课下设计模块的问题

写到这里已经懒得写了。就说一条最严重的吧。

我课下设计的模块里有一个ALU运算数选择器和ALU解码器,这两个元件会独立于控制器产生控制信号,所以在新增指令的时候,有可能要一次改三个元件(没错,我第一题的原始做法其实就涉及了这个问题,你们看到的这个做法是我写博客写一半意识到有更好的临时解决方法才改的)。

所以这几个独立的产生控制信号的部分要去掉。