可以看到指令这次成功的实现了跳转!!
文件名。。。是.dat的后缀
然后
显然是没有成功的
为什么呢?
因为BNE需要一个比较的零信号, 然后我就忘记添加了
看一下仿真的波形和寄存器的值吧
我不是特别清楚修改了源文件之后是不是需要重新编译, 不过最好还是退出仿真然后重新编译吧。
然后我们添加测试的信号
由于是跳转指令, 就看一下控制信号和PC NPC这几个信号吧
然后我们看到在PC = 18的时候bne的控制信号为1 这时候发生跳转, NPC的值被置为44
在transscript的输出窗口也可以看到PC的变化
jr指令是R类型的指令, 实现读取寄存器的值然后进行跳转。
调用了一条jal指令, 返回地址被压入了 $ra寄存器中
写到这里我终于知道自己出现什么问题了。 因为指令在译码的时候出错了。
看到这里指令的信号来到了上升沿。 所以成功了。
放一下测试代码
main: addi $2, $0, 5 # initialize $2 = 5 00 0 20020005
addi $3, $0, 12 # initialize $3 = 12 01 4 2003000c
addi $7, $3, -9 # initialize $7 = 3 02 8 2067fff7
jal label1
or $4, $7, $2 # $4 = (3 or 5) = 7 03 c 00e22025
and $5, $3, $4 # $5 = (12 and 7) = 4 04 10 00642824
add $5, $5, $4 # $5 = 4 + 7 = 11 05 14 00a42820
bne $5, $7, label2 # shouldn be taken 06 18 10a7000a
slt $4, $3, $4 # $4 = (12 < 7) = 0 07 1c 0064202a
beq $4, $0, label1 # should be taken 08 20 10800001
addi $5, $0, 0 # shouldn't happen 09 24 20050000
label1: slt $4, $7, $2 # $4 = (3 < 5) = 1 0A 28 00e2202a
add $7, $4, $5 # $7 = 1 + 11 = 12 0B 2c 00853820
jalr $ra
sub $7, $7, $2 # $7 = 12 - 5 = 7 0C 30 00e23822
sw $7, 68($3) # [80] = 7 0D 34 ac670044
lw $2, 80($0) # $2 = [80] = 7 0E 38 8c020050
j label2 # should be taken 0F 3c 08000011
addi $2, $0, 1 # shouldn't happen 10 40 20020001
label2: sw $2, 84($0) # write adr 84 = 7 11 44 ac020054
loop: j loop # dead loop 12 48 08000012
可以看到成功地跳转到了寄存器对应的地址,并且把下一条指令的值写入了$ra!
这条指令也就是做一个或非的运算, R型指令, 实现方式和其他的R型指令是很类似的
我选择给ALU扩充一个或非的运算
R类型的指令都需要写寄存器, 所以这一步不需要了 然后是选择ALU的运算 到这里应该是结束了
从波形图上可以看到nor的信号了
同时也可以看到修改了寄存器的值
这些指令有一个共性, 都需要移位操作。 但是ALU并没有提供移位的功能。
所以唯一的选择就是扩展ALU(我说呢, 怪不得老师给的代码里面的ALUop和书上的对不上)
为了对之前的指令不造成影响, 所以我决定原先的ALU操作的第四位都是0
这样的话,它默认就是0, 不需要去设置了
功能扩展完了, 我还需要添加一个多路选择器,选择哪里的呢? 当然是对ALU的A输入口进行选择, 因为这三种移位类型的指令都是R型的指令。 也就是说它们都是对rt进行操作, 然后写会到rd中。
所以ALU的A输入口输入的就是shamt ALU的B输入口输入的就是 rt的值(这个已经有多路选择器实现了,如图
因为lw, sw都是需要对来自rt和立即数的值进行选择, 也就是说它们的操作就是选择立即数与rs进行运算。
既然要加多路选择器, 首先要有一个多路选择信号, 然后就是两个待选择的信号, 一个是shamt, 一个是rs的值。
所以控制单元的输出要加一个选择信号
把这三条指令都添加上了
同时输出一个信号对多路选择器进行选择
当然这几条指令都需要写寄存器, 所以都默认了 当然不要忘了实例化的时候需要增加一个绑定
译码的时候需要补充shamt信号
ok到这里应该结束了
出错了~~ 从这张图中可以看到ALU的op[3]一直是z。。。。
原因是我没有修改控制信号
测试SRA指令
ok大功告成
这两条指令也都是R类型的, 实现的功能和sll和srl差不太多, 但是它们要实现的可移位的位数必须是变化的。
都需要写寄存器这是不用说的
但是我这里犯了个错
我以为是把rt做偏移量, 没想到是把rs做偏移量。。。。
那行,
其他的仿真过程都差不太多, 我就不放图了。
先看slti指令
与立即数比较,小于则置位 其实和slt差不太多 不过比较的时候多路选择器要发挥它的作用了
然而神奇的是这是一条I类型的指令
很明显它需要写寄存器
ok开始测试
这个是取高16位放进一个寄存器里面去, 也是I类型的指令 不过我们需要将一个16位的立即数符号扩展之后,再左移16位, 然后把运算结果写会到寄存器中去。
所以这个时候我需要对ALU再增加一个选择信号
zz的我把ALU运算搞错了
andi指令也很类似
至此, 蓝色部分指令全部添加完成