需要添加的指令:
sll /srl/sllv/ srlv/bne/ nor /jr/ jalr/andi/ lui/ slti/
bne 不相等则分支 I型
bne rs, rt, label1 形式为6 5 5 16(offeset)
func[5:0]:000101
指令译码
由于bne指令要跳转,所以要修改npc
用到ALU计算
用Mars添加bne,检测
观察波形图信号量pc npc
pc=18,npc=44,说明bne指令添加成功
sll & srl & sllv & srlv
在此说明一下,shamt是在A端口,imm是在B端口,(我们原本的ALUsrc注释中,ALU A应该是B)
所以需要添加一个多路选择器,来选择rs和shamt
sll 逻辑左移 R型 funct 000000
sll rd, rt, shamt rd =rt << shamt 655556形式
srl 逻辑右移 R型 funct 000010
srl rd, rt, shamt rd =rt >> shamt 655556形式
sllv 逻辑左移变量 R型 funct 000100
srllv rd, rt, rs rd =rt << rs 655556
srlv 逻辑右移变量 R型 funct 000110
srlv rd, rt, rs rd =rt >> rs 65556
添加译码
由于ALU中没有移位,所以要扩展ALU
增添多路选择器
加一个信号对多路选择器进行选择(判断选择rs还是shamt)
接着绑定信号
增添信号
补充shamt信号
补充ALU A 信号
定义shamt的格式
前27位为0,取6到10位指令(至于为什么这样子取,还未明白)
补充多路选择器
修改ALU的输入端口
仿真运行
sllv和srlv 在原来的基础上只需要修改译码和操作数
运行成功后,如下
slti 小于立即数则置位 I型 001010
slti rt, rs, imm
65516
指令译码
寄存器写
ALUOp和slt一样
仿真运行
nor 异或 R型 funct100111
nor rd, rs, rt 0 rs rt rd 0 0x27(6 5 5 5 5 6)
rd = ~(rs|rt)
扩充ALU
添加译码
修改ALUOp的控制
添加nor指令
仿真运行
观察ALUA/B/C端口的情况
A=c, B=4,C=fffffff3,结果正确,添加指令成功
lui 立即数高16位放进一个寄存器 I型 funct001111
lui rt, imm RT={imm,16'b0}
6 5 5 16
需要16位立即数符号扩展,再左移16位
译码
ALU扩展
写寄存器
写回rt寄存器
ALU运算,来自一个立即数
符号扩展
ALUOp修改
仿真运行
jr & jalr
jr 寄存器跳转 R型 001000
jr rs(无条件跳转到由寄存器rs指定的指令) 0 rs 0 8(6 5 15 6)
pc=GPR[rs]
指令译码
修改npc
添加指令
仿真运行
jr指令来到上升沿,调用成功
jalr 跳转并链接到寄存器 R型 001001
jalr rs rd 0 rs 0 rd 0 9(6 5 5 5 5 6)
pc=GPR[rs]; GPR[rd]=pc+4
指令译码
需要写寄存器
选择需要写的数据-来自PC
对NPC选择
添加指令
运行仿真
观察波形图有jalr的跳跃信号
andi 立即数与 I型 op:001100
andi rt rs imm oxc rs rt imm(6 5 5 16)
添加译码
需符号扩展
需写寄存器
需对ALU进行选择
对ALU端口选择
运行仿真
观察ALUOp的值为3,添加指令成功
运行学号
01510008
8421码译码之后:
0000 0001 0101 0001 0000 0000 0000 1000
最后想说明一下,做完,我简直要爆炸,仿真运行,底下的框出不来数据,只能看波形图,中间认认真真地添完了指令,却在仿真运行的时候出现了error loading design,以及运行学号,可以在别人电脑上跑,我的却不行,所以待续。
另外,参考了萍水间人的文章,大家都可以去观摩!