版本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
|
|
|