1,ADDU指令
ADDU rd,rs,rt
将寄存器rs的值与寄存器rt的值相加,结果写入rt寄存器中。
GPR[rd]<-GPR[rs]+GPR[rt]
指令码:000000
2,ADDIU指令
与ADDU不同的是第二个源操作数不时来自寄存器,而是从立即数中直接获得
可以和ADDU的数据通路基本复用,然后加上一个二选一多路选择器
第二个操作数(立即数)需要将16位符号扩展到32位后后形成数据 。
3,SUBU指令
与ADDU的指令大致相同,可以直接对输入数字src2按位取反,进位输入在处理加法时为0,在处理减法时为1
4,LW指令
三个要点
1)将基址寄存器rs的值和指令码中的立即数offset相加,得到虚地址vaddr
2)将虚地址vaddr通过虚实地址映射得到物理地址
3)根据paddr,从内存中读出数据
写入寄存器堆的结果数据出现了两个来源,一个是加法器的结果,另一个则是数据RAM的输出,显然又要引入一个二选一的部件,即输出向RAM或者输出向寄存器
5,SW指令
与LW在取址,地址计算,虚实地址转换部分完全相同,LW读RAM写通用寄存器,SW读通用寄存器写RAM
6,BEQ和BNE指令
功能要点:
1)判断分支条件
2)计算跳转条件
3)如果跳转,则修改取指PC为跳转目标,否则PC加4
思路:实现独立的分支判断比较逻辑(不使用ALU加法器做减法进行比较,方便流水线CPU的冲突的处理 )
计算跳转目标
计算跳转目标有一个小陷阱需要注意,看下面BEQ指令定义中特殊标记的两处,即该分支对应延迟槽指令的PC加offset
汇编格式:REQ rs,rt,offset
功能描述:如果寄存器rs的值等于寄存器rt的值则转移,否则顺序执行。转移目标由立即数offset左移两位并进行有符号扩展的值再加上该分支指令对应的延迟槽指令的PC计算得到。
操作定义:I:condition<-GPR[rs]=GPR[rt]
target_offset <-Sign_extend(offset||0^2)
I+1:if condition then
PC<-PC+target_offset
endif
此处使用了延迟槽的定义但是我对于延迟槽的理解较浅,不太明白为什么要这样做。
分支延迟槽 (Branch delay slot),简单地说就是位于分支指令后面的一条指令,不管分支发生与否其总是被执行,而且位于分支延迟槽中的指令先于分支指令提交 (commit)
7,JAL指令
1)不用进行分枝条件判断,一定会跳转。
2)跳转的目标地址还是通过计算延迟槽指令的PC与指令码中的立即数得到,但是采用的方法是拼接而不是直接相加。
3)不仅要修改PC,还要写通用寄存器
对于前两点,需要将原有的二选一变为三选一部件,三选一部件的输入in0,in1,与原有的“二选一”部件得我输入in0和in1一致,新增的in2输入为高位与保存下来JAL指令中的instr_index左移两位进行拼接的结果。
link操作:
jal意为jump and 领空的缩写,jump为跳转,link操作是用带“link”操作的跳转指令来完成call操作,跳转中的link操作会将该跳转的延迟槽指令的PC加4写入一个通用寄存器(通常是31号寄存器),也就是说,这个调用点对应的返回地址应该被写入一个通用寄存器中。要完成return的跳转功能,只需要将保存在通用寄存器中的值取出,作为跳转目标地址完成跳转就好。具体来说是使用间接跳转指令,如JR指令来完成。
用JAL指令完成link操作时,返回地址默认会写入31号寄存器,查看指令的编码格式定义,就会发现这个目操作数第寄存器好并不是编码在rs,rt这样的域,它是隐含的。这就需要我们对现有的数据通路中通用寄存器堆写端口的地址输入waddr的生成逻辑进行调整,将现有的二选一扩展为三选一部件,在原有的基础上增加一个常数值8作为新增的输入in2.
由于JAL指令将返回地址写入31号寄存器的操作是在JAL执行的时候完成的,此时CPU的数据通路上并没有JAL延迟槽指令PC加4的数值。因此我们只能通过运算逻辑将这个值算出来。此时使用加法器,in0介入通用寄存器堆的数据输出端口1,in1接当前指令的PC。
8,JR指令
间接跳转指令,
特点:
1)跳转不需要进行条件判断,一定会跳转。
2)跳转的目标地址来自通用寄存器的第rs项。
根据以上两个特点,需要将原有的nextPC的三选一部件进一步调整为四选一部件,新增的第四个数据来自通用寄存器堆读端口1的输出rdata1.
9,SLT和SLTU的指令
这两条指令页数算术运算指令,与ADDU,SUBU指令相比,差异仅是从源操作数输入到结果的运算过程不一样,其他方面都是一致的,可以直接服用以前的新功能。
此处可以增加一个能处理两个有符号数和无符号数大小的比较器。一个控制信号可以用于标志是有符号数还是无符号数比较,输出比较结果为0或1
10,SLL,SRL和SRA指令
三条指令均为移位指令,分别是逻辑左移,逻辑右移,算术右移。
三条指令的源操作数均有连个,一个来自通用寄存器的第rt项,另一个是指令码中sa的数值。三条指令的结果均写入通用寄存器堆的第rd项。
可以添加一个“移位器”的数据通路。
11,LUI ,AND,OR,XOR,NOR
这些指令都是运算指令,可以和ADD,SUB等结合到一个模块中(ALU)