用scala写一个基本五级流水线CPU(三)增加R型指令
ctime:2020-06-28 13:01:45 +0900|1593316905
标签(空格分隔): 技术 硬件
本次更新的代码可参考:
https://github.com/Ncerzzk/SimpleCPU/tree/deeb0217751f32bda5adf748b60cf528296466a6
前面的文章中已经添加了一条最基本的ORI指令(I型指令),然而指令系统目前还很不完善,如果要增加指令的话,还需要改动大量代码。
因此,本文开始着手进行指令系统的优化修改,着重思考几个问题:
- 增加指令所需修改的地方尽量少
- 有一些指令如and 和 andi ,一个是R型指令,一个I型指令,在译码阶段是不同的,但是到了执行阶段,这两个应用的是同一个操作,如何优化?
EX优化
针对第二个问题,在之前指令枚举的基础上,增加一些新的指令枚举:指令类型枚举、指令功能码FUNC枚举(针对R型指令)、指令操作码OP枚举(针对I型指令),指令运算类型枚举,除了原本的LOGIC以外,还增加了ALU(算数运算)。
object
针对指令运算类型,如LOGIC和ALU,都增加了一个caculate方法,用于将运算类型和对应的操作绑定起来,这样在EX阶段就不需要再针对每个指令、或者每个运算类型,来写相应的操作了,因为操作已经在枚举中绑定了。
trait
这样一来,EX模块就可以进一步优化,因为操作都已经写在枚举中了,EX模块仅需调用即可:
class
与之前想必,EX模块精简了不少,以后增加新指令时,EX模块也不需要改动,仅需在上面的枚举中增加相应功能及操作即可。
ID优化
针对译码模块,也要进行相应优化。增加了R型指令后,新的译码逻辑为:
- 判断指令类型是R型还是I型
- 针对指令类型,做出不同的操作
- 设置是否读取寄存器(如I型,只读取一个寄存器。R型,要读取两个寄存器)
- 设置读取的寄存器的地址
- 设置写入寄存器地址(I型写入的寄存器地址是rt,R型写入寄存器的地址是rd)
- 根据指令的功能码(R型)或者操作码(I型),译出给后级(EX)的操作码(OP)和子操作码(OPSel)
主要修改:
when
测试
测试代码:
addiu
波形图: