/RISCV-Simulation

MS106 homework.

Primary LanguageC++

RISC-V-Simulation

类及hpp介绍

  • func_and_tools.hpp: myspa中放了所有需要的枚举类型、常量、功能函数(得到立即数和十六进制转十进制)。
  • memory.hpp: Memory_simu类作为内存,把读入的指令放置在mem[]中,initialize()时把所有指令读入。
  • program.hpp: 在类program中,Reg[]指代寄存器。

五级流水:

  • 当遇到data_hazard和部分control_hazard时暂停流水。
  • 结构体ID_Reg,EXE_Reg,MEM_Reg,WB_Reg分别用于暂存从IF()ID(),从ID()EXE(),从EXE()MEM(),从MEM()WB()的数据。
  • 需要暂停流水时,在IF()时设置dReg.now_code为-1,在ID()时若dReg.now_code为-1,则把eReg.type设为NOType,在接下来的函数中,若其类型为NOType,则把它传给下一个函数的结构体中的type也设为NOType,并return。这样流水就被暂停了一个回合。

mem()三周期模拟

  • cycle用于在mem()时用三周期模拟,当某条指令需要内存操作时,设置cycle为3,接下来的循环中,IF()时若cycle不为0,就将cycle减1并暂停流水。

分支预测

  • 使用两位饱和计数器,结构体branch_pre_cache用于缓存。
  • IF()时判断上一条指令是否是B开头的指令,再根据缓存结构体的jud()预测是否跳转,在这个过程中,用结构体中的pos_c暂存该指令的位置,pc不改变。
  • EXE()中跳转与不跳转的情况下分别对缓存结构体调用push()函数。若预测成功则继续流水,若预测不成功则对dReg重新取值,然后流水可以继续。
  • 特别的,若读到的指令是结束指令,则不论是否预测成功,都当成不成功,直接把pos_c设为pc不可能变为的值,把dReg.now_code设为-1。
  • 调用函数success_rate()可输出成功率,最高能达到85%,最低只有17%,平均在60%左右。当然,对于分支预测成功率而言,小数据并没有意义,对于较大的数据,成功率可以达到75%左右。

forwarding

  • ID()时判断这一轮是否用到上一轮要修改的寄存器,如果用到,就把值从上一轮EXE()时算出来的mReg.data直接拿来。

乱序执行(没有写)

  • 含义:对于指令123,若2与1产生了data_hazard,而3与1、2独立,对1暂停流水时,可先执行3操作,然后再执行2操作。