版本2.0
实现了对ori,or,andi,and等逻辑运算指令和sll,srl移位指令的支持。
一,测试逻辑运算指令:
ori $1,$0,0x0001 #$1=1
ori $2,$0,0x0002 #$2=2
ori $3,$0,0x0003 #$3=3
#逻辑运算测试
and $4,$1,$3 #测试and(与)指令,预计出现$4=1
or $4,$1,$2 #测试or(或)指令,预计出现$4=3
xor $4,$1,$3 #测试xor(异或)指令,预计出现$4=2
andi $4,$1,0x0003 #测试andi指令,预计出现$4=1
对应机器码:
34010001
34020002
34030003
00232024
00222025
00232026
30240003
仿真波形图:
和预计结果完全相同。
一,测试移位运算指令:
ori $1,$0,0x0001 #$1=1
ori $2,$0,0x0002 #$2=2
#移位指令测试
sll $3,$2,1 #测试sll(左移位)指令,预计出现$3=4(0x0100)
srl $3,$2,1 #测试srl(右移位)指令,预计出现$3=1(0x0001)
对应机器码:
34010001
34020002
00021840
00021842
仿真波形图:
实现了寄存器前半个周期写,后半个周期读的功能
实现了ex_ex,ex_mem旁路
反思:
1,不该定义那么多宏的。。。。。。。。。。。。。
比如刚开始还真的仿照书本定义了rst_enable,rst_disable,write_enable,read_disable,
等等等等很多使能信号(感觉这在写c++时并没有什么问题,but丫的这sb软件并没有自动补全与语法检查,宏很容易打错,而且很麻烦,还会忘记)。。。。。。。
然后,我重新把绝大部分使能信号用enable_signal~ disable_signal宏代替(其实直接enable~disable更好,但是disable是关键字)。
嗯。。。。。其实觉得大部分使能类的信号都都只有两个结果(true or false),所以应该本身就有良好的自注释作用。。。。。不应该用宏的,但木已成舟,又不想重写。就修修补补吧
2,书上好像流水线的设计把模块分得比较散。。。。
例如下图
但我写的时候好像把一些东西全扔一块了。。。。比如多路选择器。。。。。相当于直接通过模块内的分支语句代替了。。。。。
还有我将结构冒险的检测,控制器也全扔id模块里了。。。。。是不是该分开呢???以后再说。
3,找不到未添加ex_ex旁路与mem_ex旁路时的文件了。。。。。只有添加旁路以后的,所有没办法将无旁路时的波形图截图了。So还是上版本控制系统吧。。。。。
4,选择仿真时,老老实实的simulate>>start simulate>>选择要仿真的模块>>去掉enable optimizion>>选择10ns的时间间隔>>ok吧!
软件太坑。。。。。反正只用几天,也不想填坑了。。。。。。
5, 感觉重复的代码好多。。。。。ctrl+c 和ctrl+v用了好多次。。。。。
但是这样在c++,java,python等编程语言中是不对的,很容易导致bug。
但好像verilog是硬件描述语言,和c++,Java等有本质的区别。。。。。不知道符不符合这个规律。
就比如几个段寄存器的实现好像都差不多。。。。感觉用一个段寄存器的(姑且叫做类,用c++的叫法)就可以了。然后再实例化。好迷啊!!!
6,网上找到的mips指令对应的机器码,设计指令时还是按照官方文档来吧。。。。瞎玩容易出事(踩过坑)
Mips指令对应机器码:
MIPS 指令集(共31条) |
MIPS 指令集(共31条) |
助记符 |
指令格式 |
示例 |
示例含义 |
操作及其解释 |
Bit # |
31..26 |
25..21 |
20..16 |
15..11 |
10..6 |
5..0 |
|
|
|
R-type |
op |
rs |
rt |
rd |
shamt |
func |
|
|
|
add |
000000 |
rs |
rt |
rd |
00000 |
100000 |
add $1,$2,$3 |
$1=$2+$3 |
rd <- rs + rt ;其中rs=$2,rt=$3, rd=$1 |
addu |
000000 |
rs |
rt |
rd |
00000 |
100001 |
addu $1,$2,$3 |
$1=$2+$3 |
rd <- rs + rt ;其中rs=$2,rt=$3, rd=$1,无符号数 |
sub |
000000 |
rs |
rt |
rd |
00000 |
100010 |
sub $1,$2,$3 |
$1=$2-$3 |
rd <- rs - rt ;其中rs=$2,rt=$3, rd=$1 |
subu |
000000 |
rs |
rt |
rd |
00000 |
100011 |
subu $1,$2,$3 |
$1=$2-$3 |
rd <- rs - rt ;其中rs=$2,rt=$3, rd=$1,无符号数 |
and |
000000 |
rs |
rt |
rd |
00000 |
100100 |
and $1,$2,$3 |
$1=$2 & $3 |
rd <- rs & rt ;其中rs=$2,rt=$3, rd=$1 |
or |
000000 |
rs |
rt |
rd |
00000 |
100101 |
or $1,$2,$3 |
$1=$2 | $3 |
rd <- rs | rt ;其中rs=$2,rt=$3, rd=$1 |
xor |
000000 |
rs |
rt |
rd |
00000 |
100110 |
xor $1,$2,$3 |
$1=$2 ^ $3 |
rd <- rs xor rt ;其中rs=$2,rt=$3, rd=$1(异或) |
nor |
000000 |
rs |
rt |
rd |
00000 |
100111 |
nor $1,$2,$3 |
$1=~($2 | $3) |
rd <- not(rs | rt) ;其中rs=$2,rt=$3, rd=$1(或非) |
slt |
000000 |
rs |
rt |
rd |
00000 |
101010 |
slt $1,$2,$3 |
if($2<$3) $1=1 else $1=0 |
if (rs < rt) rd=1 else rd=0 ;其中rs=$2,rt=$3, rd=$1 |
sltu |
000000 |
rs |
rt |
rd |
00000 |
101011 |
sltu $1,$2,$3 |
if($2<$3) $1=1 else $1=0 |
if (rs < rt) rd=1 else rd=0 ;其中rs=$2,rt=$3, rd=$1 (无符号数) |
sll |
000000 |
00000 |
rt |
rd |
shamt |
000000 |
sll $1,$2,10 |
$1=$2<<10 |
rd <- rt << shamt ;shamt存放移位的位数, 也就是指令中的立即数,其中rt=$2, rd=$1 |
srl |
000000 |
00000 |
rt |
rd |
shamt |
000010 |
srl $1,$2,10 |
$1=$2>>10 |
rd <- rt >> shamt ;(logical) ,其中rt=$2, rd=$1 |
sra |
000000 |
00000 |
rt |
rd |
shamt |
000011 |
sra $1,$2,10 |
$1=$2>>10 |
rd <- rt >> shamt ;(arithmetic) 注意符号位保留 其中rt=$2, rd=$1 |
sllv |
000000 |
rs |
rt |
rd |
00000 |
000100 |
sllv $1,$2,$3 |
$1=$2<<$3 |
rd <- rt << rs ;其中rs=$3,rt=$2, rd=$1 |
srlv |
000000 |
rs |
rt |
rd |
00000 |
000110 |
srlv $1,$2,$3 |
$1=$2>>$3 |
rd <- rt >> rs ;(logical)其中rs=$3,rt=$2, rd=$1 |
srav |
000000 |
rs |
rt |
rd |
00000 |
000111 |
srav $1,$2,$3 |
$1=$2>>$3 |
rd <- rt >> rs ;(arithmetic) 注意符号位保留 其中rs=$3,rt=$2, rd=$1 |
jr |
000000 |
rs |
00000 |
00000 |
00000 |
001000 |
jr $31 |
goto $31 |
PC <- rs |
I-type |
op |
rs |
rt |
immediate |
|
|
|
addi |
001000 |
rs |
rt |
immediate |
addi $1,$2,100 |
$1=$2+100 |
rt <- rs + (sign-extend)immediate ;其中rt=$1,rs=$2 |
addiu |
001001 |
rs |
rt |
immediate |
addiu $1,$2,100 |
$1=$2+100 |
rt <- rs + (zero-extend)immediate ;其中rt=$1,rs=$2 |
andi |
001100 |
rs |
rt |
immediate |
andi $1,$2,10 |
$1=$2 & 10 |
rt <- rs & (zero-extend)immediate ;其中rt=$1,rs=$2 |
ori |
001101 |
rs |
rt |
immediate |
andi $1,$2,10 |
$1=$2 | 10 |
rt <- rs | (zero-extend)immediate ;其中rt=$1,rs=$2 |
xori |
001110 |
rs |
rt |
immediate |
andi $1,$2,10 |
$1=$2 ^ 10 |
rt <- rs xor (zero-extend)immediate ;其中rt=$1,rs=$2 |
lui |
001111 |
00000 |
rt |
immediate |
lui $1,100 |
$1=100*65536 |
rt <- immediate*65536 ;将16位立即数放到目标寄存器高16 位,目标寄存器的低16位填0 |
lw |
100011 |
rs |
rt |
immediate |
lw $1,10($2) |
$1=memory[$2 +10] |
rt <- memory[rs + (sign-extend)immediate] ;rt=$1,rs=$2 |
sw |
101011 |
rs |
rt |
immediate |
sw $1,10($2) |
memory[$2+10] =$1 |
memory[rs + (sign-extend)immediate] <- rt ;rt=$1,rs=$2 |
beq |
000100 |
rs |
rt |
immediate |
beq $1,$2,10 |
if($1==$2) goto PC+4+40 |
if (rs == rt) PC <- PC+4 + (sign-extend)immediate<<2 |
bne |
000101 |
rs |
rt |
immediate |
bne $1,$2,10 |
if($1!=$2) goto PC+4+40 |
if (rs != rt) PC <- PC+4 + (sign-extend)immediate<<2 |
slti |
001010 |
rs |
rt |
immediate |
slti $1,$2,10 |
if($2<10) $1=1 else $1=0 |
if (rs <(sign-extend)immediate) rt=1 else rt=0 ; 其中rs=$2,rt=$1 |
sltiu |
001011 |
rs |
rt |
immediate |
sltiu $1,$2,10 |
if($2<10) $1=1 else $1=0 |
if (rs <(zero-extend)immediate) rt=1 else rt=0 ; 其中rs=$2,rt=$1 |
J-type |
op |
address |
|
|
|
j |
000010 |
address |
j 10000 |
goto 10000 |
PC <- (PC+4)[31..28],address,0,0 ;address=10000/4 |
jal |
000011 |
address |
jal 10000 |
$31<-PC+4; goto 10000 |
$31<-PC+4;PC <- (PC+4)[31..28],address,0,0 ;address=10000/4 |
|
|